mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
BPF: Add sample code for new ib_umad tracepoint
Provide a count of class types for a summary of MAD packets. The example shows one way to filter the trace data based on management class. Signed-off-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
2ccfbb70c2
commit
0ac01febd4
@ -7655,6 +7655,8 @@ F: include/uapi/rdma/
|
||||
F: include/rdma/
|
||||
F: include/trace/events/ib_mad.h
|
||||
F: include/trace/events/ib_umad.h
|
||||
F: samples/bpf/ibumad_kern.c
|
||||
F: samples/bpf/ibumad_user.c
|
||||
|
||||
INGENIC JZ4780 DMA Driver
|
||||
M: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
|
||||
|
@ -52,6 +52,7 @@ hostprogs-y += xdpsock
|
||||
hostprogs-y += xdp_fwd
|
||||
hostprogs-y += task_fd_query
|
||||
hostprogs-y += xdp_sample_pkts
|
||||
hostprogs-y += ibumad
|
||||
hostprogs-y += hbm
|
||||
|
||||
# Libbpf dependencies
|
||||
@ -108,6 +109,7 @@ xdpsock-objs := xdpsock_user.o
|
||||
xdp_fwd-objs := xdp_fwd_user.o
|
||||
task_fd_query-objs := bpf_load.o task_fd_query_user.o $(TRACE_HELPERS)
|
||||
xdp_sample_pkts-objs := xdp_sample_pkts_user.o $(TRACE_HELPERS)
|
||||
ibumad-objs := bpf_load.o ibumad_user.o $(TRACE_HELPERS)
|
||||
hbm-objs := bpf_load.o hbm.o $(CGROUP_HELPERS)
|
||||
|
||||
# Tell kbuild to always build the programs
|
||||
@ -166,6 +168,7 @@ always += xdp_adjust_tail_kern.o
|
||||
always += xdp_fwd_kern.o
|
||||
always += task_fd_query_kern.o
|
||||
always += xdp_sample_pkts_kern.o
|
||||
always += ibumad_kern.o
|
||||
always += hbm_out_kern.o
|
||||
|
||||
KBUILD_HOSTCFLAGS += -I$(objtree)/usr/include
|
||||
|
144
samples/bpf/ibumad_kern.c
Normal file
144
samples/bpf/ibumad_kern.c
Normal file
@ -0,0 +1,144 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
|
||||
/**
|
||||
* ibumad BPF sample kernel side
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* Copyright(c) 2018 Ira Weiny, Intel Corporation
|
||||
*/
|
||||
|
||||
#define KBUILD_MODNAME "ibumad_count_pkts_by_class"
|
||||
#include <uapi/linux/bpf.h>
|
||||
|
||||
#include "bpf_helpers.h"
|
||||
|
||||
|
||||
struct bpf_map_def SEC("maps") read_count = {
|
||||
.type = BPF_MAP_TYPE_ARRAY,
|
||||
.key_size = sizeof(u32), /* class; u32 required */
|
||||
.value_size = sizeof(u64), /* count of mads read */
|
||||
.max_entries = 256, /* Room for all Classes */
|
||||
};
|
||||
|
||||
struct bpf_map_def SEC("maps") write_count = {
|
||||
.type = BPF_MAP_TYPE_ARRAY,
|
||||
.key_size = sizeof(u32), /* class; u32 required */
|
||||
.value_size = sizeof(u64), /* count of mads written */
|
||||
.max_entries = 256, /* Room for all Classes */
|
||||
};
|
||||
|
||||
#undef DEBUG
|
||||
#ifdef DEBUG
|
||||
#define bpf_debug(fmt, ...) \
|
||||
({ \
|
||||
char ____fmt[] = fmt; \
|
||||
bpf_trace_printk(____fmt, sizeof(____fmt), \
|
||||
##__VA_ARGS__); \
|
||||
})
|
||||
#else
|
||||
#define bpf_debug(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Taken from the current format defined in
|
||||
* include/trace/events/ib_umad.h
|
||||
* and
|
||||
* /sys/kernel/debug/tracing/events/ib_umad/ib_umad_read/format
|
||||
* /sys/kernel/debug/tracing/events/ib_umad/ib_umad_write/format
|
||||
*/
|
||||
struct ib_umad_rw_args {
|
||||
u64 pad;
|
||||
u8 port_num;
|
||||
u8 sl;
|
||||
u8 path_bits;
|
||||
u8 grh_present;
|
||||
u32 id;
|
||||
u32 status;
|
||||
u32 timeout_ms;
|
||||
u32 retires;
|
||||
u32 length;
|
||||
u32 qpn;
|
||||
u32 qkey;
|
||||
u8 gid_index;
|
||||
u8 hop_limit;
|
||||
u16 lid;
|
||||
u16 attr_id;
|
||||
u16 pkey_index;
|
||||
u8 base_version;
|
||||
u8 mgmt_class;
|
||||
u8 class_version;
|
||||
u8 method;
|
||||
u32 flow_label;
|
||||
u16 mad_status;
|
||||
u16 class_specific;
|
||||
u32 attr_mod;
|
||||
u64 tid;
|
||||
u8 gid[16];
|
||||
u32 dev_index;
|
||||
u8 traffic_class;
|
||||
};
|
||||
|
||||
SEC("tracepoint/ib_umad/ib_umad_read_recv")
|
||||
int on_ib_umad_read_recv(struct ib_umad_rw_args *ctx)
|
||||
{
|
||||
u64 zero = 0, *val;
|
||||
u8 class = ctx->mgmt_class;
|
||||
|
||||
bpf_debug("ib_umad read recv : class 0x%x\n", class);
|
||||
|
||||
val = bpf_map_lookup_elem(&read_count, &class);
|
||||
if (!val) {
|
||||
bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST);
|
||||
val = bpf_map_lookup_elem(&read_count, &class);
|
||||
if (!val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*val) += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
SEC("tracepoint/ib_umad/ib_umad_read_send")
|
||||
int on_ib_umad_read_send(struct ib_umad_rw_args *ctx)
|
||||
{
|
||||
u64 zero = 0, *val;
|
||||
u8 class = ctx->mgmt_class;
|
||||
|
||||
bpf_debug("ib_umad read send : class 0x%x\n", class);
|
||||
|
||||
val = bpf_map_lookup_elem(&read_count, &class);
|
||||
if (!val) {
|
||||
bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST);
|
||||
val = bpf_map_lookup_elem(&read_count, &class);
|
||||
if (!val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*val) += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
SEC("tracepoint/ib_umad/ib_umad_write")
|
||||
int on_ib_umad_write(struct ib_umad_rw_args *ctx)
|
||||
{
|
||||
u64 zero = 0, *val;
|
||||
u8 class = ctx->mgmt_class;
|
||||
|
||||
bpf_debug("ib_umad write : class 0x%x\n", class);
|
||||
|
||||
val = bpf_map_lookup_elem(&write_count, &class);
|
||||
if (!val) {
|
||||
bpf_map_update_elem(&write_count, &class, &zero, BPF_NOEXIST);
|
||||
val = bpf_map_lookup_elem(&write_count, &class);
|
||||
if (!val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*val) += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
122
samples/bpf/ibumad_user.c
Normal file
122
samples/bpf/ibumad_user.c
Normal file
@ -0,0 +1,122 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
|
||||
/**
|
||||
* ibumad BPF sample user side
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* Copyright(c) 2018 Ira Weiny, Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/bpf.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <getopt.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "bpf_load.h"
|
||||
#include "bpf_util.h"
|
||||
#include "bpf/libbpf.h"
|
||||
|
||||
static void dump_counts(int fd)
|
||||
{
|
||||
__u32 key;
|
||||
__u64 value;
|
||||
|
||||
for (key = 0; key < 256; key++) {
|
||||
if (bpf_map_lookup_elem(fd, &key, &value)) {
|
||||
printf("failed to read key %u\n", key);
|
||||
continue;
|
||||
}
|
||||
if (value)
|
||||
printf("0x%02x : %llu\n", key, value);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_all_counts(void)
|
||||
{
|
||||
printf("Read 'Class : count'\n");
|
||||
dump_counts(map_fd[0]);
|
||||
printf("Write 'Class : count'\n");
|
||||
dump_counts(map_fd[1]);
|
||||
}
|
||||
|
||||
static void dump_exit(int sig)
|
||||
{
|
||||
dump_all_counts();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static const struct option long_options[] = {
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"delay", required_argument, NULL, 'd'},
|
||||
};
|
||||
|
||||
static void usage(char *cmd)
|
||||
{
|
||||
printf("eBPF test program to count packets from various IP addresses\n"
|
||||
"Usage: %s <options>\n"
|
||||
" --help, -h this menu\n"
|
||||
" --delay, -d <delay> wait <delay> sec between prints [1 - 1000000]\n"
|
||||
, cmd
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned long delay = 5;
|
||||
int longindex = 0;
|
||||
int opt;
|
||||
char bpf_file[256];
|
||||
|
||||
/* Create the eBPF kernel code path name.
|
||||
* This follows the pattern of all of the other bpf samples
|
||||
*/
|
||||
snprintf(bpf_file, sizeof(bpf_file), "%s_kern.o", argv[0]);
|
||||
|
||||
/* Do one final dump when exiting */
|
||||
signal(SIGINT, dump_exit);
|
||||
signal(SIGTERM, dump_exit);
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "hd:rSw",
|
||||
long_options, &longindex)) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
delay = strtoul(optarg, NULL, 0);
|
||||
if (delay == ULONG_MAX || delay < 0 ||
|
||||
delay > 1000000) {
|
||||
fprintf(stderr, "ERROR: invalid delay : %s\n",
|
||||
optarg);
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_bpf_file(bpf_file)) {
|
||||
fprintf(stderr, "ERROR: failed to load eBPF from file : %s\n",
|
||||
bpf_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
sleep(delay);
|
||||
dump_all_counts();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user