1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 3 /* 4 * ibumad BPF sample kernel side 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of version 2 of the GNU General Public 8 * License as published by the Free Software Foundation. 9 * 10 * Copyright(c) 2018 Ira Weiny, Intel Corporation 11 */ 12 13 #define KBUILD_MODNAME "ibumad_count_pkts_by_class" 14 #include <uapi/linux/bpf.h> 15 16 #include <bpf/bpf_helpers.h> 17 18 19 struct { 20 __uint(type, BPF_MAP_TYPE_ARRAY); 21 __type(key, u32); /* class; u32 required */ 22 __type(value, u64); /* count of mads read */ 23 __uint(max_entries, 256); /* Room for all Classes */ 24 } read_count SEC(".maps"); 25 26 struct { 27 __uint(type, BPF_MAP_TYPE_ARRAY); 28 __type(key, u32); /* class; u32 required */ 29 __type(value, u64); /* count of mads written */ 30 __uint(max_entries, 256); /* Room for all Classes */ 31 } write_count SEC(".maps"); 32 33 #undef DEBUG 34 #ifndef DEBUG 35 #undef bpf_printk 36 #define bpf_printk(fmt, ...) 37 #endif 38 39 /* Taken from the current format defined in 40 * include/trace/events/ib_umad.h 41 * and 42 * /sys/kernel/debug/tracing/events/ib_umad/ib_umad_read/format 43 * /sys/kernel/debug/tracing/events/ib_umad/ib_umad_write/format 44 */ 45 struct ib_umad_rw_args { 46 u64 pad; 47 u8 port_num; 48 u8 sl; 49 u8 path_bits; 50 u8 grh_present; 51 u32 id; 52 u32 status; 53 u32 timeout_ms; 54 u32 retires; 55 u32 length; 56 u32 qpn; 57 u32 qkey; 58 u8 gid_index; 59 u8 hop_limit; 60 u16 lid; 61 u16 attr_id; 62 u16 pkey_index; 63 u8 base_version; 64 u8 mgmt_class; 65 u8 class_version; 66 u8 method; 67 u32 flow_label; 68 u16 mad_status; 69 u16 class_specific; 70 u32 attr_mod; 71 u64 tid; 72 u8 gid[16]; 73 u32 dev_index; 74 u8 traffic_class; 75 }; 76 77 SEC("tracepoint/ib_umad/ib_umad_read_recv") 78 int on_ib_umad_read_recv(struct ib_umad_rw_args *ctx) 79 { 80 u64 zero = 0, *val; 81 u8 class = ctx->mgmt_class; 82 83 bpf_printk("ib_umad read recv : class 0x%x\n", class); 84 85 val = bpf_map_lookup_elem(&read_count, &class); 86 if (!val) { 87 bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST); 88 val = bpf_map_lookup_elem(&read_count, &class); 89 if (!val) 90 return 0; 91 } 92 93 (*val) += 1; 94 95 return 0; 96 } 97 SEC("tracepoint/ib_umad/ib_umad_read_send") 98 int on_ib_umad_read_send(struct ib_umad_rw_args *ctx) 99 { 100 u64 zero = 0, *val; 101 u8 class = ctx->mgmt_class; 102 103 bpf_printk("ib_umad read send : class 0x%x\n", class); 104 105 val = bpf_map_lookup_elem(&read_count, &class); 106 if (!val) { 107 bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST); 108 val = bpf_map_lookup_elem(&read_count, &class); 109 if (!val) 110 return 0; 111 } 112 113 (*val) += 1; 114 115 return 0; 116 } 117 SEC("tracepoint/ib_umad/ib_umad_write") 118 int on_ib_umad_write(struct ib_umad_rw_args *ctx) 119 { 120 u64 zero = 0, *val; 121 u8 class = ctx->mgmt_class; 122 123 bpf_printk("ib_umad write : class 0x%x\n", class); 124 125 val = bpf_map_lookup_elem(&write_count, &class); 126 if (!val) { 127 bpf_map_update_elem(&write_count, &class, &zero, BPF_NOEXIST); 128 val = bpf_map_lookup_elem(&write_count, &class); 129 if (!val) 130 return 0; 131 } 132 133 (*val) += 1; 134 135 return 0; 136 } 137 138 char _license[] SEC("license") = "GPL"; 139