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_helpers.h" 17 18 19 struct bpf_map_def SEC("maps") read_count = { 20 .type = BPF_MAP_TYPE_ARRAY, 21 .key_size = sizeof(u32), /* class; u32 required */ 22 .value_size = sizeof(u64), /* count of mads read */ 23 .max_entries = 256, /* Room for all Classes */ 24 }; 25 26 struct bpf_map_def SEC("maps") write_count = { 27 .type = BPF_MAP_TYPE_ARRAY, 28 .key_size = sizeof(u32), /* class; u32 required */ 29 .value_size = sizeof(u64), /* count of mads written */ 30 .max_entries = 256, /* Room for all Classes */ 31 }; 32 33 #undef DEBUG 34 #ifdef DEBUG 35 #define bpf_debug(fmt, ...) \ 36 ({ \ 37 char ____fmt[] = fmt; \ 38 bpf_trace_printk(____fmt, sizeof(____fmt), \ 39 ##__VA_ARGS__); \ 40 }) 41 #else 42 #define bpf_debug(fmt, ...) 43 #endif 44 45 /* Taken from the current format defined in 46 * include/trace/events/ib_umad.h 47 * and 48 * /sys/kernel/debug/tracing/events/ib_umad/ib_umad_read/format 49 * /sys/kernel/debug/tracing/events/ib_umad/ib_umad_write/format 50 */ 51 struct ib_umad_rw_args { 52 u64 pad; 53 u8 port_num; 54 u8 sl; 55 u8 path_bits; 56 u8 grh_present; 57 u32 id; 58 u32 status; 59 u32 timeout_ms; 60 u32 retires; 61 u32 length; 62 u32 qpn; 63 u32 qkey; 64 u8 gid_index; 65 u8 hop_limit; 66 u16 lid; 67 u16 attr_id; 68 u16 pkey_index; 69 u8 base_version; 70 u8 mgmt_class; 71 u8 class_version; 72 u8 method; 73 u32 flow_label; 74 u16 mad_status; 75 u16 class_specific; 76 u32 attr_mod; 77 u64 tid; 78 u8 gid[16]; 79 u32 dev_index; 80 u8 traffic_class; 81 }; 82 83 SEC("tracepoint/ib_umad/ib_umad_read_recv") 84 int on_ib_umad_read_recv(struct ib_umad_rw_args *ctx) 85 { 86 u64 zero = 0, *val; 87 u8 class = ctx->mgmt_class; 88 89 bpf_debug("ib_umad read recv : class 0x%x\n", class); 90 91 val = bpf_map_lookup_elem(&read_count, &class); 92 if (!val) { 93 bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST); 94 val = bpf_map_lookup_elem(&read_count, &class); 95 if (!val) 96 return 0; 97 } 98 99 (*val) += 1; 100 101 return 0; 102 } 103 SEC("tracepoint/ib_umad/ib_umad_read_send") 104 int on_ib_umad_read_send(struct ib_umad_rw_args *ctx) 105 { 106 u64 zero = 0, *val; 107 u8 class = ctx->mgmt_class; 108 109 bpf_debug("ib_umad read send : class 0x%x\n", class); 110 111 val = bpf_map_lookup_elem(&read_count, &class); 112 if (!val) { 113 bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST); 114 val = bpf_map_lookup_elem(&read_count, &class); 115 if (!val) 116 return 0; 117 } 118 119 (*val) += 1; 120 121 return 0; 122 } 123 SEC("tracepoint/ib_umad/ib_umad_write") 124 int on_ib_umad_write(struct ib_umad_rw_args *ctx) 125 { 126 u64 zero = 0, *val; 127 u8 class = ctx->mgmt_class; 128 129 bpf_debug("ib_umad write : class 0x%x\n", class); 130 131 val = bpf_map_lookup_elem(&write_count, &class); 132 if (!val) { 133 bpf_map_update_elem(&write_count, &class, &zero, BPF_NOEXIST); 134 val = bpf_map_lookup_elem(&write_count, &class); 135 if (!val) 136 return 0; 137 } 138 139 (*val) += 1; 140 141 return 0; 142 } 143 144 char _license[] SEC("license") = "GPL"; 145