forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
- Loading branch information
1 parent
2ccfbb7
commit 0ac01fe
Showing
4 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 <[email protected]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |