On Sun, Sep 20, 2020 at 7:47 AM Xin Hao <xhao@xxxxxxxxxxxxxxxxx> wrote: > > This patch is aimed to count the execution time of > each soft irq and it supports log2 histogram display. > > Soft irq counts: > us : count distribution > > 0 -> 1 : 151 |****************************************| > 2 -> 3 : 86 |********************** | > 4 -> 7 : 59 |*************** | > 8 -> 15 : 20 |***** | > 16 -> 31 : 3 | | > > Signed-off-by: Xin Hao <xhao@xxxxxxxxxxxxxxxxx> > --- I assume you saw softirqs tools ([0]) from libbpf-tools in BCC, right? Could you mention in the commit message how this tool is different and why there is a need for another one? BTW, if you are interested in contributing more and making samples/bpf better overall, consider looking at adding BPF skeleton integration into samples/bpf, similarly to how all libbpf-tools use skeletons. [0] https://github.com/iovisor/bcc/pull/3076 > samples/bpf/Makefile | 3 ++ > samples/bpf/soft_irq_kern.c | 87 ++++++++++++++++++++++++++++++++++++ > samples/bpf/soft_irq_user.c | 88 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 178 insertions(+) > create mode 100644 samples/bpf/soft_irq_kern.c > create mode 100644 samples/bpf/soft_irq_user.c > > diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile > index f87ee02073ba..0774f0fb8bdf 100644 > --- a/samples/bpf/Makefile > +++ b/samples/bpf/Makefile > @@ -53,6 +53,7 @@ tprogs-y += task_fd_query > tprogs-y += xdp_sample_pkts > tprogs-y += ibumad > tprogs-y += hbm > +tprogs-y += soft_irq > > # Libbpf dependencies > LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a > @@ -109,6 +110,7 @@ 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) > +soft_irq-objs := bpf_load.o soft_irq_user.o $(TRACE_HELPERS) > > # Tell kbuild to always build the programs > always-y := $(tprogs-y) > @@ -170,6 +172,7 @@ always-y += ibumad_kern.o > always-y += hbm_out_kern.o > always-y += hbm_edt_kern.o > always-y += xdpsock_kern.o > +always-y += soft_irq_kern.o > > ifeq ($(ARCH), arm) > # Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux > diff --git a/samples/bpf/soft_irq_kern.c b/samples/bpf/soft_irq_kern.c > new file mode 100644 > index 000000000000..e63f829cf7c7 > --- /dev/null > +++ b/samples/bpf/soft_irq_kern.c > @@ -0,0 +1,87 @@ > +/* SPDX-License-Identifier: GPL-2.0 > + * > + * 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. > + */ > + > +#include <uapi/linux/bpf.h> > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> > +#include <uapi/linux/ptrace.h> > +#include <uapi/linux/perf_event.h> > +#include <linux/version.h> > +#include <linux/sched.h> > +#include "common_kern.h" > + > +typedef struct key { > + u32 pid; > + u32 cpu; > +} irqkey_t; > + > +typedef struct val { > + u64 ts; > + u32 vec; > +} val_t; > + > +typedef struct delta_irq { > + u64 delta; > + u32 value; > +} delta_irq_t; kernel style generally discourages unnecessary typedefs, I think following that is a good idea. I'm not sure those typedefs provide much value and they save only few letters when typing. > + > +struct bpf_map_def SEC("maps") start = { > + .type = BPF_MAP_TYPE_HASH, > + .key_size = sizeof(irqkey_t), > + .value_size = sizeof(val_t), > + .max_entries = 1000, > +}; > + > +struct soft_irq { > + u64 pad; > + u32 vec; > +}; it's a good idea to keep empty line between type declarations and variables/functions > +SEC("tracepoint/irq/softirq_entry") > +int entryirq(struct soft_irq *ctx) > +{ > + irqkey_t entry_key = {}; > + val_t val = {}; > + > + entry_key.pid = bpf_get_current_pid_tgid(); > + entry_key.cpu = bpf_get_smp_processor_id(); > + > + val.ts = bpf_ktime_get_ns(); > + val.vec = ctx->vec; > + > + bpf_map_update_elem(&start, &entry_key, &val, BPF_ANY); > + return 0; > +} > + > +struct bpf_map_def SEC("maps") over = { > + .type = BPF_MAP_TYPE_HASH, > + .key_size = sizeof(irqkey_t), > + .value_size = sizeof(delta_irq_t), > + .max_entries = 10000, > +}; same > +SEC("tracepoint/irq/softirq_exit") > +int exitirq(struct soft_irq *ctx) > +{ > + irqkey_t entry_key = {}; > + delta_irq_t delta_val = {}; > + val_t *valp; > + > + entry_key.pid = bpf_get_current_pid_tgid(); > + entry_key.cpu = bpf_get_smp_processor_id(); > + > + valp = bpf_map_lookup_elem(&start, &entry_key); > + if (valp) { > + delta_val.delta = (bpf_ktime_get_ns() - valp->ts) / 1000; /* us */ > + delta_val.value = log2l(delta_val.delta); > + > + bpf_map_update_elem(&over, &entry_key, &delta_val, BPF_ANY); > + bpf_map_delete_elem(&start, valp); > + } > + > + return 0; > +} here as well > +char _license[] SEC("license") = "GPL"; > +u32 _version SEC("version") = LINUX_VERSION_CODE; [...]