xref: /openbmc/linux/samples/bpf/ibumad_kern.c (revision 7cf245a37ef013b2c1c5ca7ae25061de2ba7ad01)
10ac01febSIra Weiny // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
20ac01febSIra Weiny 
30ac01febSIra Weiny /**
40ac01febSIra Weiny  * ibumad BPF sample kernel side
50ac01febSIra Weiny  *
60ac01febSIra Weiny  * This program is free software; you can redistribute it and/or
70ac01febSIra Weiny  * modify it under the terms of version 2 of the GNU General Public
80ac01febSIra Weiny  * License as published by the Free Software Foundation.
90ac01febSIra Weiny  *
100ac01febSIra Weiny  * Copyright(c) 2018 Ira Weiny, Intel Corporation
110ac01febSIra Weiny  */
120ac01febSIra Weiny 
130ac01febSIra Weiny #define KBUILD_MODNAME "ibumad_count_pkts_by_class"
140ac01febSIra Weiny #include <uapi/linux/bpf.h>
150ac01febSIra Weiny 
16*7cf245a3SToke Høiland-Jørgensen #include <bpf/bpf_helpers.h>
170ac01febSIra Weiny 
180ac01febSIra Weiny 
190ac01febSIra Weiny struct bpf_map_def SEC("maps") read_count = {
200ac01febSIra Weiny 	.type        = BPF_MAP_TYPE_ARRAY,
210ac01febSIra Weiny 	.key_size    = sizeof(u32), /* class; u32 required */
220ac01febSIra Weiny 	.value_size  = sizeof(u64), /* count of mads read */
230ac01febSIra Weiny 	.max_entries = 256, /* Room for all Classes */
240ac01febSIra Weiny };
250ac01febSIra Weiny 
260ac01febSIra Weiny struct bpf_map_def SEC("maps") write_count = {
270ac01febSIra Weiny 	.type        = BPF_MAP_TYPE_ARRAY,
280ac01febSIra Weiny 	.key_size    = sizeof(u32), /* class; u32 required */
290ac01febSIra Weiny 	.value_size  = sizeof(u64), /* count of mads written */
300ac01febSIra Weiny 	.max_entries = 256, /* Room for all Classes */
310ac01febSIra Weiny };
320ac01febSIra Weiny 
330ac01febSIra Weiny #undef DEBUG
347ae9f281SMichal Rostecki #ifndef DEBUG
357ae9f281SMichal Rostecki #undef bpf_printk
367ae9f281SMichal Rostecki #define bpf_printk(fmt, ...)
370ac01febSIra Weiny #endif
380ac01febSIra Weiny 
390ac01febSIra Weiny /* Taken from the current format defined in
400ac01febSIra Weiny  * include/trace/events/ib_umad.h
410ac01febSIra Weiny  * and
420ac01febSIra Weiny  * /sys/kernel/debug/tracing/events/ib_umad/ib_umad_read/format
430ac01febSIra Weiny  * /sys/kernel/debug/tracing/events/ib_umad/ib_umad_write/format
440ac01febSIra Weiny  */
450ac01febSIra Weiny struct ib_umad_rw_args {
460ac01febSIra Weiny 	u64 pad;
470ac01febSIra Weiny 	u8 port_num;
480ac01febSIra Weiny 	u8 sl;
490ac01febSIra Weiny 	u8 path_bits;
500ac01febSIra Weiny 	u8 grh_present;
510ac01febSIra Weiny 	u32 id;
520ac01febSIra Weiny 	u32 status;
530ac01febSIra Weiny 	u32 timeout_ms;
540ac01febSIra Weiny 	u32 retires;
550ac01febSIra Weiny 	u32 length;
560ac01febSIra Weiny 	u32 qpn;
570ac01febSIra Weiny 	u32 qkey;
580ac01febSIra Weiny 	u8 gid_index;
590ac01febSIra Weiny 	u8 hop_limit;
600ac01febSIra Weiny 	u16 lid;
610ac01febSIra Weiny 	u16 attr_id;
620ac01febSIra Weiny 	u16 pkey_index;
630ac01febSIra Weiny 	u8 base_version;
640ac01febSIra Weiny 	u8 mgmt_class;
650ac01febSIra Weiny 	u8 class_version;
660ac01febSIra Weiny 	u8 method;
670ac01febSIra Weiny 	u32 flow_label;
680ac01febSIra Weiny 	u16 mad_status;
690ac01febSIra Weiny 	u16 class_specific;
700ac01febSIra Weiny 	u32 attr_mod;
710ac01febSIra Weiny 	u64 tid;
720ac01febSIra Weiny 	u8 gid[16];
730ac01febSIra Weiny 	u32 dev_index;
740ac01febSIra Weiny 	u8 traffic_class;
750ac01febSIra Weiny };
760ac01febSIra Weiny 
770ac01febSIra Weiny SEC("tracepoint/ib_umad/ib_umad_read_recv")
780ac01febSIra Weiny int on_ib_umad_read_recv(struct ib_umad_rw_args *ctx)
790ac01febSIra Weiny {
800ac01febSIra Weiny 	u64 zero = 0, *val;
810ac01febSIra Weiny 	u8 class = ctx->mgmt_class;
820ac01febSIra Weiny 
837ae9f281SMichal Rostecki 	bpf_printk("ib_umad read recv : class 0x%x\n", class);
840ac01febSIra Weiny 
850ac01febSIra Weiny 	val = bpf_map_lookup_elem(&read_count, &class);
860ac01febSIra Weiny 	if (!val) {
870ac01febSIra Weiny 		bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST);
880ac01febSIra Weiny 		val = bpf_map_lookup_elem(&read_count, &class);
890ac01febSIra Weiny 		if (!val)
900ac01febSIra Weiny 			return 0;
910ac01febSIra Weiny 	}
920ac01febSIra Weiny 
930ac01febSIra Weiny 	(*val) += 1;
940ac01febSIra Weiny 
950ac01febSIra Weiny 	return 0;
960ac01febSIra Weiny }
970ac01febSIra Weiny SEC("tracepoint/ib_umad/ib_umad_read_send")
980ac01febSIra Weiny int on_ib_umad_read_send(struct ib_umad_rw_args *ctx)
990ac01febSIra Weiny {
1000ac01febSIra Weiny 	u64 zero = 0, *val;
1010ac01febSIra Weiny 	u8 class = ctx->mgmt_class;
1020ac01febSIra Weiny 
1037ae9f281SMichal Rostecki 	bpf_printk("ib_umad read send : class 0x%x\n", class);
1040ac01febSIra Weiny 
1050ac01febSIra Weiny 	val = bpf_map_lookup_elem(&read_count, &class);
1060ac01febSIra Weiny 	if (!val) {
1070ac01febSIra Weiny 		bpf_map_update_elem(&read_count, &class, &zero, BPF_NOEXIST);
1080ac01febSIra Weiny 		val = bpf_map_lookup_elem(&read_count, &class);
1090ac01febSIra Weiny 		if (!val)
1100ac01febSIra Weiny 			return 0;
1110ac01febSIra Weiny 	}
1120ac01febSIra Weiny 
1130ac01febSIra Weiny 	(*val) += 1;
1140ac01febSIra Weiny 
1150ac01febSIra Weiny 	return 0;
1160ac01febSIra Weiny }
1170ac01febSIra Weiny SEC("tracepoint/ib_umad/ib_umad_write")
1180ac01febSIra Weiny int on_ib_umad_write(struct ib_umad_rw_args *ctx)
1190ac01febSIra Weiny {
1200ac01febSIra Weiny 	u64 zero = 0, *val;
1210ac01febSIra Weiny 	u8 class = ctx->mgmt_class;
1220ac01febSIra Weiny 
1237ae9f281SMichal Rostecki 	bpf_printk("ib_umad write : class 0x%x\n", class);
1240ac01febSIra Weiny 
1250ac01febSIra Weiny 	val = bpf_map_lookup_elem(&write_count, &class);
1260ac01febSIra Weiny 	if (!val) {
1270ac01febSIra Weiny 		bpf_map_update_elem(&write_count, &class, &zero, BPF_NOEXIST);
1280ac01febSIra Weiny 		val = bpf_map_lookup_elem(&write_count, &class);
1290ac01febSIra Weiny 		if (!val)
1300ac01febSIra Weiny 			return 0;
1310ac01febSIra Weiny 	}
1320ac01febSIra Weiny 
1330ac01febSIra Weiny 	(*val) += 1;
1340ac01febSIra Weiny 
1350ac01febSIra Weiny 	return 0;
1360ac01febSIra Weiny }
1370ac01febSIra Weiny 
1380ac01febSIra Weiny char _license[] SEC("license") = "GPL";
139