diff --git a/libbpf-tools/hardirqs.bpf.c b/libbpf-tools/hardirqs.bpf.c index cd9b4d6d54aa..cbcbd5c05158 100644 --- a/libbpf-tools/hardirqs.bpf.c +++ b/libbpf-tools/hardirqs.bpf.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2020 Wenbo Zhang #include +#include #include #include #include "hardirqs.h" @@ -12,6 +13,7 @@ const volatile bool filter_cg = false; const volatile bool targ_dist = false; const volatile bool targ_ns = false; +const volatile bool do_count = false; struct { __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); @@ -36,59 +38,53 @@ struct { static struct info zero; -SEC("tracepoint/irq/irq_handler_entry") -int handle__irq_handler(struct trace_event_raw_irq_handler_entry *ctx) +static int handle_entry(int irq, struct irqaction *action) { - struct irq_key key = {}; - struct info *info; - if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0)) return 0; - bpf_probe_read_kernel_str(&key.name, sizeof(key.name), ctx->__data); - info = bpf_map_lookup_or_try_init(&infos, &key, &zero); - if (!info) + if (do_count) { + struct irq_key key = {}; + struct info *info; + + bpf_probe_read_kernel_str(&key.name, sizeof(key.name), BPF_CORE_READ(action, name)); + info = bpf_map_lookup_or_try_init(&infos, &key, &zero); + if (!info) + return 0; + info->count += 1; return 0; - info->count += 1; - return 0; -} + } else { + u64 ts = bpf_ktime_get_ns(); + u32 key = 0; -SEC("tp_btf/irq_handler_entry") -int BPF_PROG(irq_handler_entry) -{ - u64 ts = bpf_ktime_get_ns(); - u32 key = 0; + if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0)) + return 0; - if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0)) + bpf_map_update_elem(&start, &key, &ts, BPF_ANY); return 0; - - bpf_map_update_elem(&start, &key, &ts, 0); - return 0; + } } -SEC("tp_btf/irq_handler_exit") -int BPF_PROG(irq_handler_exit_exit, int irq, struct irqaction *action) +static int handle_exit(int irq, struct irqaction *action) { struct irq_key ikey = {}; struct info *info; u32 key = 0; - s64 delta; + u64 delta; u64 *tsp; if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0)) return 0; tsp = bpf_map_lookup_elem(&start, &key); - if (!tsp || !*tsp) + if (!tsp) return 0; delta = bpf_ktime_get_ns() - *tsp; - if (delta < 0) - return 0; if (!targ_ns) delta /= 1000U; - bpf_probe_read_kernel_str(&ikey.name, sizeof(ikey.name), action->name); + bpf_probe_read_kernel_str(&ikey.name, sizeof(ikey.name), BPF_CORE_READ(action, name)); info = bpf_map_lookup_or_try_init(&infos, &ikey, &zero); if (!info) return 0; @@ -107,4 +103,28 @@ int BPF_PROG(irq_handler_exit_exit, int irq, struct irqaction *action) return 0; } +SEC("tp_btf/irq_handler_entry") +int BPF_PROG(irq_handler_entry_btf, int irq, struct irqaction *action) +{ + return handle_entry(irq, action); +} + +SEC("tp_btf/irq_handler_exit") +int BPF_PROG(irq_handler_exit_btf, int irq, struct irqaction *action) +{ + return handle_exit(irq, action); +} + +SEC("raw_tp/irq_handler_entry") +int BPF_PROG(irq_handler_entry, int irq, struct irqaction *action) +{ + return handle_entry(irq, action); +} + +SEC("raw_tp/irq_handler_exit") +int BPF_PROG(irq_handler_exit, int irq, struct irqaction *action) +{ + return handle_exit(irq, action); +} + char LICENSE[] SEC("license") = "GPL"; diff --git a/libbpf-tools/hardirqs.c b/libbpf-tools/hardirqs.c index 21a094f82b9b..7961215ea17f 100644 --- a/libbpf-tools/hardirqs.c +++ b/libbpf-tools/hardirqs.c @@ -205,7 +205,20 @@ int main(int argc, char **argv) return 1; } + if (probe_tp_btf("irq_handler_entry")) { + bpf_program__set_autoload(obj->progs.irq_handler_entry, false); + bpf_program__set_autoload(obj->progs.irq_handler_exit, false); + if (env.count) + bpf_program__set_autoload(obj->progs.irq_handler_exit_btf, false); + } else { + bpf_program__set_autoload(obj->progs.irq_handler_entry_btf, false); + bpf_program__set_autoload(obj->progs.irq_handler_exit_btf, false); + if (env.count) + bpf_program__set_autoload(obj->progs.irq_handler_exit, false); + } + obj->rodata->filter_cg = env.cg; + obj->rodata->do_count = env.count; /* initialize global data (filtering options) */ if (!env.count) { @@ -234,29 +247,10 @@ int main(int argc, char **argv) } } - if (env.count) { - obj->links.handle__irq_handler = bpf_program__attach(obj->progs.handle__irq_handler); - if (!obj->links.handle__irq_handler) { - err = -errno; - fprintf(stderr, - "failed to attach irq/irq_handler_entry: %s\n", - strerror(-err)); - } - } else { - obj->links.irq_handler_entry = bpf_program__attach(obj->progs.irq_handler_entry); - if (!obj->links.irq_handler_entry) { - err = -errno; - fprintf(stderr, - "failed to attach irq_handler_entry: %s\n", - strerror(-err)); - } - obj->links.irq_handler_exit_exit = bpf_program__attach(obj->progs.irq_handler_exit_exit); - if (!obj->links.irq_handler_exit_exit) { - err = -errno; - fprintf(stderr, - "failed to attach irq_handler_exit: %s\n", - strerror(-err)); - } + err = hardirqs_bpf__attach(obj); + if (err) { + fprintf(stderr, "failed to attach BPF object: %d\n", err); + goto cleanup; } signal(SIGINT, sig_handler);