From ddf81226e8559c8beab88afb0cbb6702e11d0120 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 15 2022 06:38:22 +0000 Subject: import bcc-0.24.0-4.el9 --- diff --git a/.bcc.metadata b/.bcc.metadata index 82927a1..e3a63ae 100644 --- a/.bcc.metadata +++ b/.bcc.metadata @@ -1 +1 @@ -87f0836bc2a1d7a795a44622d14930e6d4f6d627 SOURCES/bcc-0.20.0.tar.gz +896d0249470dedfabfcc9a4c8b4089a55b793277 SOURCES/bcc-0.24.0.tar.gz diff --git a/.gitignore b/.gitignore index c5b3e19..277ef94 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/bcc-0.20.0.tar.gz +SOURCES/bcc-0.24.0.tar.gz diff --git a/SOURCES/bcc-0.20.0-Define-KERNEL_VERSION.patch b/SOURCES/bcc-0.20.0-Define-KERNEL_VERSION.patch deleted file mode 100644 index 959eae5..0000000 --- a/SOURCES/bcc-0.20.0-Define-KERNEL_VERSION.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6516fb0d00208f05b29f320176204957b02b23e3 Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Mon, 26 Jul 2021 12:05:57 +0200 -Subject: [PATCH] Define KERNEL_VERSION - -The libbpf version on RHEL9 doesn't define it. ---- - libbpf-tools/biolatency.bpf.c | 2 ++ - libbpf-tools/biosnoop.bpf.c | 2 ++ - libbpf-tools/bitesize.bpf.c | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/libbpf-tools/biolatency.bpf.c b/libbpf-tools/biolatency.bpf.c -index 8d8fe584..8e6e81e2 100644 ---- a/libbpf-tools/biolatency.bpf.c -+++ b/libbpf-tools/biolatency.bpf.c -@@ -9,6 +9,8 @@ - - #define MAX_ENTRIES 10240 - -+#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) -+ - extern int LINUX_KERNEL_VERSION __kconfig; - - const volatile bool targ_per_disk = false; -diff --git a/libbpf-tools/biosnoop.bpf.c b/libbpf-tools/biosnoop.bpf.c -index 76697967..7b7cb1a4 100644 ---- a/libbpf-tools/biosnoop.bpf.c -+++ b/libbpf-tools/biosnoop.bpf.c -@@ -11,6 +11,8 @@ - const volatile bool targ_queued = false; - const volatile dev_t targ_dev = -1; - -+#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) -+ - extern __u32 LINUX_KERNEL_VERSION __kconfig; - - struct piddata { -diff --git a/libbpf-tools/bitesize.bpf.c b/libbpf-tools/bitesize.bpf.c -index 7b4d3f9d..5e7d9d97 100644 ---- a/libbpf-tools/bitesize.bpf.c -+++ b/libbpf-tools/bitesize.bpf.c -@@ -10,6 +10,8 @@ - const volatile char targ_comm[TASK_COMM_LEN] = {}; - const volatile dev_t targ_dev = -1; - -+#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) -+ - extern __u32 LINUX_KERNEL_VERSION __kconfig; - - struct { --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-Fix-a-llvm-compilation-error.patch b/SOURCES/bcc-0.20.0-Fix-a-llvm-compilation-error.patch deleted file mode 100644 index 5c15817..0000000 --- a/SOURCES/bcc-0.20.0-Fix-a-llvm-compilation-error.patch +++ /dev/null @@ -1,46 +0,0 @@ -From e2a4a556755d3c5ae7538ba9bcb731f93b9f81c9 Mon Sep 17 00:00:00 2001 -From: Yonghong Song -Date: Tue, 25 May 2021 19:58:00 -0700 -Subject: [PATCH] Fix a llvm compilation error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Current llvm trunk (https://github.com/llvm/llvm-project) -will cause the following compilation errors: - /home/yhs/work/bcc/src/cc/bcc_debug.cc: In member function ‘void ebpf::SourceDebugger::dump()’: - /home/yhs/work/bcc/src/cc/bcc_debug.cc:135:75: error: no matching function for call to - ‘llvm::MCContext::MCContext(llvm::Triple&, std::unique_ptr::pointer, - std::unique_ptr::pointer, llvm::MCObjectFileInfo*, - std::unique_ptr::pointer, std::nullptr_t)’ - MCContext Ctx(TheTriple, MAI.get(), MRI.get(), &MOFI, STI.get(), nullptr); - ^ - ...... - -This is because upstream patch https://reviews.llvm.org/D101921 -refactored MCObjectFileInfo initialization and changed MCContext -constructor signature. - -This patch fixed the issue by following the new code patterns -in https://reviews.llvm.org/D101921. ---- - src/cc/bcc_debug.cc | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/cc/bcc_debug.cc b/src/cc/bcc_debug.cc -index 775c9141..97d6d95b 100644 ---- a/src/cc/bcc_debug.cc -+++ b/src/cc/bcc_debug.cc -@@ -132,7 +132,8 @@ void SourceDebugger::dump() { - T->createMCSubtargetInfo(TripleStr, "", "")); - MCObjectFileInfo MOFI; - #if LLVM_MAJOR_VERSION >= 13 -- MCContext Ctx(TheTriple, MAI.get(), MRI.get(), &MOFI, STI.get(), nullptr); -+ MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), nullptr); -+ Ctx.setObjectFileInfo(&MOFI); - MOFI.initMCObjectFileInfo(Ctx, false, false); - #else - MCContext Ctx(MAI.get(), MRI.get(), &MOFI, nullptr); --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-Fix-mdflush-on-RHEL9.patch b/SOURCES/bcc-0.20.0-Fix-mdflush-on-RHEL9.patch deleted file mode 100644 index b6b9e07..0000000 --- a/SOURCES/bcc-0.20.0-Fix-mdflush-on-RHEL9.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 8032bb4053ff8803371b038fc696b9fa682027f2 Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Thu, 7 Oct 2021 17:31:53 +0200 -Subject: [PATCH] Fix mdflush on RHEL9 - -Since kernel commit 309dca309fc ("block: store a block_device pointer -in struct bio") struct bio points again to a block_device and not to a -gendisk directly. However mdflush is looking at the presence or not of -the bio_dev macro to check whether to get the gendisk directly from -the bio or not, which doesn't work anymore since the bio_dev macro -still exists. Since we don't have to deal other ekrnel kernel version -but our own, just use the definition that we use in our kernels. ---- - tools/mdflush.py | 11 ----------- - 1 file changed, 11 deletions(-) - -diff --git a/tools/mdflush.py b/tools/mdflush.py -index 2abe15cf..df0f13c1 100755 ---- a/tools/mdflush.py -+++ b/tools/mdflush.py -@@ -35,18 +35,7 @@ int kprobe__md_flush_request(struct pt_regs *ctx, void *mddev, struct bio *bio) - u32 pid = bpf_get_current_pid_tgid(); - data.pid = pid; - bpf_get_current_comm(&data.comm, sizeof(data.comm)); --/* -- * The following deals with a kernel version change (in mainline 4.14, although -- * it may be backported to earlier kernels) with how the disk name is accessed. -- * We handle both pre- and post-change versions here. Please avoid kernel -- * version tests like this as much as possible: they inflate the code, test, -- * and maintenance burden. -- */ --#ifdef bio_dev -- struct gendisk *bi_disk = bio->bi_disk; --#else - struct gendisk *bi_disk = bio->bi_bdev->bd_disk; --#endif - bpf_probe_read_kernel(&data.disk, sizeof(data.disk), bi_disk->disk_name); - events.perf_submit(ctx, &data, sizeof(data)); - return 0; --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-Handle-renaming-of-task_struct_-state-field-on-RHEL-.patch b/SOURCES/bcc-0.20.0-Handle-renaming-of-task_struct_-state-field-on-RHEL-.patch deleted file mode 100644 index 6a35839..0000000 --- a/SOURCES/bcc-0.20.0-Handle-renaming-of-task_struct_-state-field-on-RHEL-.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 019615235458a9486d883a675a3ea16014ee597f Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Thu, 14 Oct 2021 12:01:01 +0200 -Subject: [PATCH] Handle renaming of task_struct_>state field on RHEL 9 - -There has been some cleanup of task_struct's state field and to catch -any place that has been missed in the conversion, it has been renamed -__state. ---- - tools/offcputime.py | 4 ++-- - tools/offwaketime.py | 4 ++-- - tools/runqlat.py | 4 ++-- - tools/runqslower.py | 4 ++-- - 4 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/tools/offcputime.py b/tools/offcputime.py -index 128c6496..b93e78d2 100755 ---- a/tools/offcputime.py -+++ b/tools/offcputime.py -@@ -205,10 +205,10 @@ thread_context = "" - thread_context = "all threads" - thread_filter = '1' - if args.state == 0: -- state_filter = 'prev->state == 0' -+ state_filter = 'prev->__state == 0' - elif args.state: - # these states are sometimes bitmask checked -- state_filter = 'prev->state & %d' % args.state -+ state_filter = 'prev->__state & %d' % args.state - else: - state_filter = '1' - bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter) -diff --git a/tools/offwaketime.py b/tools/offwaketime.py -index 753eee97..722c0381 100755 ---- a/tools/offwaketime.py -+++ b/tools/offwaketime.py -@@ -254,10 +254,10 @@ int oncpu(struct pt_regs *ctx, struct task_struct *p) { - else: - thread_filter = '1' - if args.state == 0: -- state_filter = 'p->state == 0' -+ state_filter = 'p->__state == 0' - elif args.state: - # these states are sometimes bitmask checked -- state_filter = 'p->state & %d' % args.state -+ state_filter = 'p->__state & %d' % args.state - else: - state_filter = '1' - bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter) -diff --git a/tools/runqlat.py b/tools/runqlat.py -index b13ff2d1..8e443c3c 100755 ---- a/tools/runqlat.py -+++ b/tools/runqlat.py -@@ -116,7 +116,7 @@ int trace_run(struct pt_regs *ctx, struct task_struct *prev) - u32 pid, tgid; - - // ivcsw: treat like an enqueue event and store timestamp -- if (prev->state == TASK_RUNNING) { -+ if (prev->__state == TASK_RUNNING) { - tgid = prev->tgid; - pid = prev->pid; - if (!(FILTER || pid == 0)) { -@@ -170,7 +170,7 @@ RAW_TRACEPOINT_PROBE(sched_switch) - u32 pid, tgid; - - // ivcsw: treat like an enqueue event and store timestamp -- if (prev->state == TASK_RUNNING) { -+ if (prev->__state == TASK_RUNNING) { - tgid = prev->tgid; - pid = prev->pid; - if (!(FILTER || pid == 0)) { -diff --git a/tools/runqslower.py b/tools/runqslower.py -index 6df98d9f..ba71e5d3 100755 ---- a/tools/runqslower.py -+++ b/tools/runqslower.py -@@ -112,7 +112,7 @@ int trace_run(struct pt_regs *ctx, struct task_struct *prev) - u32 pid, tgid; - - // ivcsw: treat like an enqueue event and store timestamp -- if (prev->state == TASK_RUNNING) { -+ if (prev->__state == TASK_RUNNING) { - tgid = prev->tgid; - pid = prev->pid; - u64 ts = bpf_ktime_get_ns(); -@@ -178,7 +178,7 @@ RAW_TRACEPOINT_PROBE(sched_switch) - long state; - - // ivcsw: treat like an enqueue event and store timestamp -- bpf_probe_read_kernel(&state, sizeof(long), (const void *)&prev->state); -+ bpf_probe_read_kernel(&state, sizeof(long), (const void *)&prev->__state); - if (state == TASK_RUNNING) { - bpf_probe_read_kernel(&tgid, sizeof(prev->tgid), &prev->tgid); - bpf_probe_read_kernel(&pid, sizeof(prev->pid), &prev->pid); --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-Remove-APInt-APSInt-toString-std-string-variants.patch b/SOURCES/bcc-0.20.0-Remove-APInt-APSInt-toString-std-string-variants.patch deleted file mode 100644 index 182209e..0000000 --- a/SOURCES/bcc-0.20.0-Remove-APInt-APSInt-toString-std-string-variants.patch +++ /dev/null @@ -1,41 +0,0 @@ -From fd0585d5d8a1a47912ae7a70721d3cab0c7d06f8 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Mon, 14 Jun 2021 12:49:43 -0700 -Subject: [PATCH] Remove APInt/APSInt toString() std::string variants - -clang 13+ has removed this in favour of a pair of llvm::toString -() helpers inside StringExtras.h to improve compile speed by avoiding -hits on header - -Signed-off-by: Khem Raj ---- - src/cc/json_map_decl_visitor.cc | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/cc/json_map_decl_visitor.cc b/src/cc/json_map_decl_visitor.cc -index eff4d067..53896199 100644 ---- a/src/cc/json_map_decl_visitor.cc -+++ b/src/cc/json_map_decl_visitor.cc -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include "common.h" - #include "table_desc.h" - -@@ -79,7 +80,11 @@ void BMapDeclVisitor::genJSONForField(FieldDecl *F) { - result_ += "["; - TraverseDecl(F); - if (const ConstantArrayType *T = dyn_cast(F->getType())) -+#if LLVM_MAJOR_VERSION >= 13 -+ result_ += ", [" + toString(T->getSize(), 10, false) + "]"; -+#else - result_ += ", [" + T->getSize().toString(10, false) + "]"; -+#endif - if (F->isBitField()) - result_ += ", " + to_string(F->getBitWidthValue(C)); - result_ += "], "; --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-Revert-libbpf-tools-remove-unecessary-custom-NULL-de.patch b/SOURCES/bcc-0.20.0-Revert-libbpf-tools-remove-unecessary-custom-NULL-de.patch deleted file mode 100644 index 47cccef..0000000 --- a/SOURCES/bcc-0.20.0-Revert-libbpf-tools-remove-unecessary-custom-NULL-de.patch +++ /dev/null @@ -1,41 +0,0 @@ -From aaa39601b756074e9ba8b9a607102a1ae0cb4c94 Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Mon, 26 Jul 2021 14:45:37 +0200 -Subject: [PATCH] Revert "libbpf-tools: remove unecessary custom NULL - definitions" - -Libbpf on RHEL does not define NULL -This reverts commit a9f461d74a84be2f96fd35c02cf98c7251bd4166. ---- - libbpf-tools/biostacks.bpf.c | 1 + - libbpf-tools/xfsslower.bpf.c | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/libbpf-tools/biostacks.bpf.c b/libbpf-tools/biostacks.bpf.c -index f02a1ac5..6ed0bda6 100644 ---- a/libbpf-tools/biostacks.bpf.c -+++ b/libbpf-tools/biostacks.bpf.c -@@ -9,6 +9,7 @@ - #include "maps.bpf.h" - - #define MAX_ENTRIES 10240 -+#define NULL 0 - - const volatile bool targ_ms = false; - const volatile dev_t targ_dev = -1; -diff --git a/libbpf-tools/xfsslower.bpf.c b/libbpf-tools/xfsslower.bpf.c -index 05962f46..2b1c6e4b 100644 ---- a/libbpf-tools/xfsslower.bpf.c -+++ b/libbpf-tools/xfsslower.bpf.c -@@ -6,6 +6,8 @@ - #include - #include "xfsslower.h" - -+#define NULL 0 -+ - const volatile pid_t targ_tgid = 0; - const volatile __u64 min_lat = 0; - --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-Update-cpudist.py.patch b/SOURCES/bcc-0.20.0-Update-cpudist.py.patch deleted file mode 100644 index 492c72f..0000000 --- a/SOURCES/bcc-0.20.0-Update-cpudist.py.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ad56e8a5a722df2ac2a5b3ea0822fd78f9a6fe51 Mon Sep 17 00:00:00 2001 -From: Nick-nizhen <74173686+Nick-nizhen@users.noreply.github.com> -Date: Thu, 27 May 2021 13:21:59 +0800 -Subject: [PATCH] Update cpudist.py - -When calculating the ONCPU time, prev has left the CPU already. It is not necessary to judge whether the process state is TASK_RUNNING or not. ---- - tools/cpudist.py | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - -diff --git a/tools/cpudist.py b/tools/cpudist.py -index eb04f590..b5a6a978 100755 ---- a/tools/cpudist.py -+++ b/tools/cpudist.py -@@ -100,19 +100,13 @@ int sched_switch(struct pt_regs *ctx, struct task_struct *prev) - u64 pid_tgid = bpf_get_current_pid_tgid(); - u32 tgid = pid_tgid >> 32, pid = pid_tgid; - -+ u32 prev_pid = prev->pid; -+ u32 prev_tgid = prev->tgid; - #ifdef ONCPU -- if (prev->state == TASK_RUNNING) { -+ update_hist(prev_tgid, prev_pid, ts); - #else -- if (1) { -+ store_start(prev_tgid, prev_pid, ts); - #endif -- u32 prev_pid = prev->pid; -- u32 prev_tgid = prev->tgid; --#ifdef ONCPU -- update_hist(prev_tgid, prev_pid, ts); --#else -- store_start(prev_tgid, prev_pid, ts); --#endif -- } - - BAIL: - #ifdef ONCPU --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-biolatpcts-Build-fixes-on-recent-kernels.patch b/SOURCES/bcc-0.20.0-biolatpcts-Build-fixes-on-recent-kernels.patch deleted file mode 100644 index 7eb8da6..0000000 --- a/SOURCES/bcc-0.20.0-biolatpcts-Build-fixes-on-recent-kernels.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 11614bcacdecd4d1f7015bb0f0311bb709207991 Mon Sep 17 00:00:00 2001 -From: Tejun Heo -Date: Thu, 27 Jan 2022 06:25:31 -1000 -Subject: [PATCH] biolatpcts: Build fixes on recent kernels - -* `struct request` definition recently moved from blkdev.h to blk-mq.h - breaking both tools/biolatpcts and examples/tracing/biolatpcts. Fix them - by also including blk-mq.h. - -* blk_account_io_done() got split into two parts - inline condition checks - and the actual accounting with the latter now done in - __blk_account_io_done(). The kprobe attachment needs to be conditionalized - to work across the change. tools/biolatpcts was already updated but - examples/tracing/biolatpcts wasn't. Fix it. - -Signed-off-by: Tejun Heo ---- - examples/tracing/biolatpcts.py | 6 +++++- - tools/biolatpcts.py | 1 + - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/examples/tracing/biolatpcts.py b/examples/tracing/biolatpcts.py -index c9bb834e..68a59516 100755 ---- a/examples/tracing/biolatpcts.py -+++ b/examples/tracing/biolatpcts.py -@@ -11,6 +11,7 @@ from time import sleep - - bpf_source = """ - #include -+#include - #include - #include - -@@ -45,7 +46,10 @@ void kprobe_blk_account_io_done(struct pt_regs *ctx, struct request *rq, u64 now - """ - - bpf = BPF(text=bpf_source) --bpf.attach_kprobe(event='blk_account_io_done', fn_name='kprobe_blk_account_io_done') -+if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ bpf.attach_kprobe(event="__blk_account_io_done", fn_name="kprobe_blk_account_io_done") -+else: -+ bpf.attach_kprobe(event="blk_account_io_done", fn_name="kprobe_blk_account_io_done") - - cur_lat_100ms = bpf['lat_100ms'] - cur_lat_1ms = bpf['lat_1ms'] -diff --git a/tools/biolatpcts.py b/tools/biolatpcts.py -index a2f59592..0f334419 100755 ---- a/tools/biolatpcts.py -+++ b/tools/biolatpcts.py -@@ -56,6 +56,7 @@ parser.add_argument('--verbose', '-v', action='count', default = 0) - bpf_source = """ - #include - #include -+#include - #include - - BPF_PERCPU_ARRAY(rwdf_100ms, u64, 400); --- -2.35.1 - diff --git a/SOURCES/bcc-0.20.0-libbpf-tool-don-t-ignore-LDFLAGS.patch b/SOURCES/bcc-0.20.0-libbpf-tool-don-t-ignore-LDFLAGS.patch deleted file mode 100644 index 6f73a5c..0000000 --- a/SOURCES/bcc-0.20.0-libbpf-tool-don-t-ignore-LDFLAGS.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 657f1b2049f2c7751a9d2a13abb42c409da1bb6f Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Wed, 2 Jun 2021 14:23:20 +0200 -Subject: [PATCH] libbpf-tool: don't ignore LDFLAGS - ---- - libbpf-tools/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libbpf-tools/Makefile b/libbpf-tools/Makefile -index 92dcf5a5..54288380 100644 ---- a/libbpf-tools/Makefile -+++ b/libbpf-tools/Makefile -@@ -77,7 +77,7 @@ endif - - $(APPS): %: $(OUTPUT)/%.o $(LIBBPF_OBJ) $(COMMON_OBJ) | $(OUTPUT) - $(call msg,BINARY,$@) -- $(Q)$(CC) $(CFLAGS) $^ -lelf -lz -o $@ -+ $(Q)$(CC) $(CFLAGS) $^ $(LDFLAGS) -lelf -lz -o $@ - - $(patsubst %,$(OUTPUT)/%.o,$(APPS)): %.o: %.skel.h - --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-libbpf-tools-readahead-don-t-mark-struct-hist-as-sta.patch b/SOURCES/bcc-0.20.0-libbpf-tools-readahead-don-t-mark-struct-hist-as-sta.patch deleted file mode 100644 index 204865b..0000000 --- a/SOURCES/bcc-0.20.0-libbpf-tools-readahead-don-t-mark-struct-hist-as-sta.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 4e2851687904cff7ab4f8faa862b9046e5aaab09 Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Fri, 30 Jul 2021 18:15:05 +0200 -Subject: [PATCH] libbpf-tools: readahead: don't mark struct hist as static - -Libbpf readahead tool does not compile with bpftool v5.14. Since -commit 31332ccb756 ("bpftool: Stop emitting static variables in BPF -skeleton"), bpftool gen skeleton does not include static variable into -the skeleton file anymore. - -Fixes the following compilation error: -readahead.c: In function 'main': -readahead.c:153:26: error: 'struct readahead_bpf__bss' has no member named 'hist' - 153 | histp = &obj->bss->hist; - | ^~ ---- - libbpf-tools/readahead.bpf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libbpf-tools/readahead.bpf.c b/libbpf-tools/readahead.bpf.c -index ba22e534..cfead704 100644 ---- a/libbpf-tools/readahead.bpf.c -+++ b/libbpf-tools/readahead.bpf.c -@@ -24,7 +24,7 @@ struct { - __uint(map_flags, BPF_F_NO_PREALLOC); - } birth SEC(".maps"); - --static struct hist hist; -+struct hist hist = {}; - - SEC("fentry/do_page_cache_ra") - int BPF_PROG(do_page_cache_ra) --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-sync-with-latest-libbpf-repo-3529.patch b/SOURCES/bcc-0.20.0-sync-with-latest-libbpf-repo-3529.patch deleted file mode 100644 index 10765ef..0000000 --- a/SOURCES/bcc-0.20.0-sync-with-latest-libbpf-repo-3529.patch +++ /dev/null @@ -1,408 +0,0 @@ -From 0c12dfe26a362db181e6172cb56a39cd002a6892 Mon Sep 17 00:00:00 2001 -From: yonghong-song -Date: Sun, 18 Jul 2021 15:05:34 -0700 -Subject: [PATCH] sync with latest libbpf repo (#3529) - -sync with latest libbpf repo which is upto commit - 21f90f61b084 sync: latest libbpf changes from kernel - -Signed-off-by: Yonghong Song ---- - docs/kernel-versions.md | 8 ++ - introspection/bps.c | 1 + - src/cc/compat/linux/virtual_bpf.h | 167 ++++++++++++++++++++++++++++-- - src/cc/export/helpers.h | 17 +++ - src/cc/libbpf.c | 8 ++ - 5 files changed, 190 insertions(+), 11 deletions(-) - -diff --git a/docs/kernel-versions.md b/docs/kernel-versions.md -index 9192aa43..33318624 100644 ---- a/docs/kernel-versions.md -+++ b/docs/kernel-versions.md -@@ -208,6 +208,7 @@ Helper | Kernel version | License | Commit | - -------|----------------|---------|--------| - `BPF_FUNC_bind()` | 4.17 | | [`d74bad4e74ee`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d74bad4e74ee373787a9ae24197c17b7cdc428d5) | - `BPF_FUNC_bprm_opts_set()` | 5.11 | | [`3f6719c7b62f`](https://github.com/torvalds/linux/commit/3f6719c7b62f0327c9091e26d0da10e65668229e) -+`BPF_FUNC_btf_find_by_name_kind()` | 5.14 | | [`3d78417b60fb`](https://github.com/torvalds/linux/commit/3d78417b60fba249cc555468cb72d96f5cde2964) - `BPF_FUNC_check_mtu()` | 5.12 | | [`34b2021cc616`](https://github.com/torvalds/linux/commit/34b2021cc61642d61c3cf943d9e71925b827941b) - `BPF_FUNC_clone_redirect()` | 4.2 | | [`3896d655f4d4`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=3896d655f4d491c67d669a15f275a39f713410f8) - `BPF_FUNC_copy_from_user()` | 5.10 | | [`07be4c4a3e7a`](https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit?id=07be4c4a3e7a0db148e44b16c5190e753d1c8569) -@@ -226,6 +227,7 @@ Helper | Kernel version | License | Commit | - `BPF_FUNC_get_current_task()` | 4.8 | GPL | [`606274c5abd8`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=606274c5abd8e245add01bc7145a8cbb92b69ba8) - `BPF_FUNC_get_current_task_btf()` | 5.11 | GPL | [`3ca1032ab7ab`](https://github.com/torvalds/linux/commit/3ca1032ab7ab010eccb107aa515598788f7d93bb) - `BPF_FUNC_get_current_uid_gid()` | 4.2 | | [`ffeedafbf023`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ffeedafbf0236f03aeb2e8db273b3e5ae5f5bc89) -+`BPF_FUNC_get_func_ip()` | 5.15 | | [`5d8b583d04ae`](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=5d8b583d04aedb3bd5f6d227a334c210c7d735f9) - `BPF_FUNC_get_hash_recalc()` | 4.8 | | [`13c5c240f789`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=13c5c240f789bbd2bcacb14a23771491485ae61f) - `BPF_FUNC_get_listener_sock()` | 5.1 | | [`dbafd7ddd623`](https://kernel.googlesource.com/pub/scm/linux/kernel/git/davem/net-next/+/dbafd7ddd62369b2f3926ab847cbf8fc40e800b7) - `BPF_FUNC_get_local_storage()` | 4.19 | | [`cd3394317653`](https://github.com/torvalds/linux/commit/cd3394317653837e2eb5c5d0904a8996102af9fc) -@@ -352,6 +354,8 @@ Helper | Kernel version | License | Commit | - `BPF_FUNC_store_hdr_opt()` | 5.10 | | [`0813a841566f`](https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit?id=0813a841566f0962a5551be7749b43c45f0022a0) - `BPF_FUNC_strtol()` | 5.2 | | [`d7a4cb9b6705`](https://kernel.googlesource.com/pub/scm/linux/kernel/git/davem/net-next/+/d7a4cb9b6705a89937d12c8158a35a3145dc967a) - `BPF_FUNC_strtoul()` | 5.2 | | [`d7a4cb9b6705`](https://kernel.googlesource.com/pub/scm/linux/kernel/git/davem/net-next/+/d7a4cb9b6705a89937d12c8158a35a3145dc967a) -+`BPF_FUNC_sys_bpf()` | 5.14 | | [`79a7f8bdb159`](https://github.com/torvalds/linux/commit/79a7f8bdb159d9914b58740f3d31d602a6e4aca8) -+`BPF_FUNC_sys_close()` | 5.14 | | [`3abea089246f`](https://github.com/torvalds/linux/commit/3abea089246f76c1517b054ddb5946f3f1dbd2c0) - `BPF_FUNC_sysctl_get_current_value()` | 5.2 | | [`1d11b3016cec`](https://kernel.googlesource.com/pub/scm/linux/kernel/git/davem/net-next/+/1d11b3016cec4ed9770b98e82a61708c8f4926e7) - `BPF_FUNC_sysctl_get_name()` | 5.2 | | [`808649fb787d`](https://kernel.googlesource.com/pub/scm/linux/kernel/git/davem/net-next/+/808649fb787d918a48a360a668ee4ee9023f0c11) - `BPF_FUNC_sysctl_get_new_value()` | 5.2 | | [`4e63acdff864`](https://kernel.googlesource.com/pub/scm/linux/kernel/git/davem/net-next/+/4e63acdff864654cee0ac5aaeda3913798ee78f6) -@@ -364,6 +368,10 @@ Helper | Kernel version | License | Commit | - `BPF_FUNC_tcp_send_ack()` | 5.5 | | [`206057fe020a`](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=206057fe020ac5c037d5e2dd6562a9bd216ec765) - `BPF_FUNC_tcp_sock()` | 5.1 | | [`655a51e536c0`](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=655a51e536c09d15ffa3603b1b6fce2b45b85a1f) - `BPF_FUNC_this_cpu_ptr()` | 5.10 | | [`63d9b80dcf2c`](https://github.com/torvalds/linux/commit/63d9b80dcf2c67bc5ade61cbbaa09d7af21f43f1) | -+`BPF_FUNC_timer_init()` | 5.15 | | [`b00628b1c7d5`](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=b00628b1c7d595ae5b544e059c27b1f5828314b4) -+`BPF_FUNC_timer_set_callback()` | 5.15 | | [`b00628b1c7d5`](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=b00628b1c7d595ae5b544e059c27b1f5828314b4) -+`BPF_FUNC_timer_start()` | 5.15 | | [`b00628b1c7d5`](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=b00628b1c7d595ae5b544e059c27b1f5828314b4) -+`BPF_FUNC_timer_cancel()` | 5.15 | | [`b00628b1c7d5`](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=b00628b1c7d595ae5b544e059c27b1f5828314b4) - `BPF_FUNC_trace_printk()` | 4.1 | GPL | [`9c959c863f82`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c959c863f8217a2ff3d7c296e8223654d240569) - `BPF_FUNC_xdp_adjust_head()` | 4.10 | | [`17bedab27231`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=17bedab2723145d17b14084430743549e6943d03) - `BPF_FUNC_xdp_adjust_meta()` | 4.15 | | [`de8f3a83b0a0`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=de8f3a83b0a0fddb2cf56e7a718127e9619ea3da) -diff --git a/introspection/bps.c b/introspection/bps.c -index e92da3f6..25a88cbd 100644 ---- a/introspection/bps.c -+++ b/introspection/bps.c -@@ -47,6 +47,7 @@ static const char * const prog_type_strings[] = { - [BPF_PROG_TYPE_EXT] = "ext", - [BPF_PROG_TYPE_LSM] = "lsm", - [BPF_PROG_TYPE_SK_LOOKUP] = "sk_lookup", -+ [BPF_PROG_TYPE_SYSCALL] = "syscall", - }; - - static const char * const map_type_strings[] = { -diff --git a/src/cc/compat/linux/virtual_bpf.h b/src/cc/compat/linux/virtual_bpf.h -index 3490bc14..bf4bc3a6 100644 ---- a/src/cc/compat/linux/virtual_bpf.h -+++ b/src/cc/compat/linux/virtual_bpf.h -@@ -325,9 +325,6 @@ union bpf_iter_link_info { - * **BPF_PROG_TYPE_SK_LOOKUP** - * *data_in* and *data_out* must be NULL. - * -- * **BPF_PROG_TYPE_XDP** -- * *ctx_in* and *ctx_out* must be NULL. -- * - * **BPF_PROG_TYPE_RAW_TRACEPOINT**, - * **BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE** - * -@@ -528,6 +525,15 @@ union bpf_iter_link_info { - * Look up an element with the given *key* in the map referred to - * by the file descriptor *fd*, and if found, delete the element. - * -+ * For **BPF_MAP_TYPE_QUEUE** and **BPF_MAP_TYPE_STACK** map -+ * types, the *flags* argument needs to be set to 0, but for other -+ * map types, it may be specified as: -+ * -+ * **BPF_F_LOCK** -+ * Look up and delete the value of a spin-locked map -+ * without returning the lock. This must be specified if -+ * the elements contain a spinlock. -+ * - * The **BPF_MAP_TYPE_QUEUE** and **BPF_MAP_TYPE_STACK** map types - * implement this command as a "pop" operation, deleting the top - * element rather than one corresponding to *key*. -@@ -537,6 +543,10 @@ union bpf_iter_link_info { - * This command is only valid for the following map types: - * * **BPF_MAP_TYPE_QUEUE** - * * **BPF_MAP_TYPE_STACK** -+ * * **BPF_MAP_TYPE_HASH** -+ * * **BPF_MAP_TYPE_PERCPU_HASH** -+ * * **BPF_MAP_TYPE_LRU_HASH** -+ * * **BPF_MAP_TYPE_LRU_PERCPU_HASH** - * - * Return - * Returns zero on success. On error, -1 is returned and *errno* -@@ -838,6 +848,7 @@ enum bpf_cmd { - BPF_PROG_ATTACH, - BPF_PROG_DETACH, - BPF_PROG_TEST_RUN, -+ BPF_PROG_RUN = BPF_PROG_TEST_RUN, - BPF_PROG_GET_NEXT_ID, - BPF_MAP_GET_NEXT_ID, - BPF_PROG_GET_FD_BY_ID, -@@ -938,6 +949,7 @@ enum bpf_prog_type { - BPF_PROG_TYPE_EXT, - BPF_PROG_TYPE_LSM, - BPF_PROG_TYPE_SK_LOOKUP, -+ BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ - }; - - enum bpf_attach_type { -@@ -980,6 +992,8 @@ enum bpf_attach_type { - BPF_SK_LOOKUP, - BPF_XDP, - BPF_SK_SKB_VERDICT, -+ BPF_SK_REUSEPORT_SELECT, -+ BPF_SK_REUSEPORT_SELECT_OR_MIGRATE, - __MAX_BPF_ATTACH_TYPE - }; - -@@ -1098,8 +1112,8 @@ enum bpf_link_type { - /* When BPF ldimm64's insn[0].src_reg != 0 then this can have - * the following extensions: - * -- * insn[0].src_reg: BPF_PSEUDO_MAP_FD -- * insn[0].imm: map fd -+ * insn[0].src_reg: BPF_PSEUDO_MAP_[FD|IDX] -+ * insn[0].imm: map fd or fd_idx - * insn[1].imm: 0 - * insn[0].off: 0 - * insn[1].off: 0 -@@ -1107,15 +1121,19 @@ enum bpf_link_type { - * verifier type: CONST_PTR_TO_MAP - */ - #define BPF_PSEUDO_MAP_FD 1 --/* insn[0].src_reg: BPF_PSEUDO_MAP_VALUE -- * insn[0].imm: map fd -+#define BPF_PSEUDO_MAP_IDX 5 -+ -+/* insn[0].src_reg: BPF_PSEUDO_MAP_[IDX_]VALUE -+ * insn[0].imm: map fd or fd_idx - * insn[1].imm: offset into value - * insn[0].off: 0 - * insn[1].off: 0 - * ldimm64 rewrite: address of map[0]+offset - * verifier type: PTR_TO_MAP_VALUE - */ --#define BPF_PSEUDO_MAP_VALUE 2 -+#define BPF_PSEUDO_MAP_VALUE 2 -+#define BPF_PSEUDO_MAP_IDX_VALUE 6 -+ - /* insn[0].src_reg: BPF_PSEUDO_BTF_ID - * insn[0].imm: kernel btd id of VAR - * insn[1].imm: 0 -@@ -1315,6 +1333,8 @@ union bpf_attr { - /* or valid module BTF object fd or 0 to attach to vmlinux */ - __u32 attach_btf_obj_fd; - }; -+ __u32 :32; /* pad */ -+ __aligned_u64 fd_array; /* array of FDs */ - }; - - struct { /* anonymous struct used by BPF_OBJ_* commands */ -@@ -2535,8 +2555,12 @@ union bpf_attr { - * The lower two bits of *flags* are used as the return code if - * the map lookup fails. This is so that the return value can be - * one of the XDP program return codes up to **XDP_TX**, as chosen -- * by the caller. Any higher bits in the *flags* argument must be -- * unset. -+ * by the caller. The higher bits of *flags* can be set to -+ * BPF_F_BROADCAST or BPF_F_EXCLUDE_INGRESS as defined below. -+ * -+ * With BPF_F_BROADCAST the packet will be broadcasted to all the -+ * interfaces in the map, with BPF_F_EXCLUDE_INGRESS the ingress -+ * interface will be excluded when do broadcasting. - * - * See also **bpf_redirect**\ (), which only supports redirecting - * to an ifindex, but doesn't require a map to do so. -@@ -3223,7 +3247,7 @@ union bpf_attr { - * long bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags) - * Description - * Select a **SO_REUSEPORT** socket from a -- * **BPF_MAP_TYPE_REUSEPORT_ARRAY** *map*. -+ * **BPF_MAP_TYPE_REUSEPORT_SOCKARRAY** *map*. - * It checks the selected socket is matching the incoming - * request in the socket buffer. - * Return -@@ -4736,6 +4760,94 @@ union bpf_attr { - * be zero-terminated except when **str_size** is 0. - * - * Or **-EBUSY** if the per-CPU memory copy buffer is busy. -+ * -+ * long bpf_sys_bpf(u32 cmd, void *attr, u32 attr_size) -+ * Description -+ * Execute bpf syscall with given arguments. -+ * Return -+ * A syscall result. -+ * -+ * long bpf_btf_find_by_name_kind(char *name, int name_sz, u32 kind, int flags) -+ * Description -+ * Find BTF type with given name and kind in vmlinux BTF or in module's BTFs. -+ * Return -+ * Returns btf_id and btf_obj_fd in lower and upper 32 bits. -+ * -+ * long bpf_sys_close(u32 fd) -+ * Description -+ * Execute close syscall for given FD. -+ * Return -+ * A syscall result. -+ * -+ * long bpf_timer_init(struct bpf_timer *timer, struct bpf_map *map, u64 flags) -+ * Description -+ * Initialize the timer. -+ * First 4 bits of *flags* specify clockid. -+ * Only CLOCK_MONOTONIC, CLOCK_REALTIME, CLOCK_BOOTTIME are allowed. -+ * All other bits of *flags* are reserved. -+ * The verifier will reject the program if *timer* is not from -+ * the same *map*. -+ * Return -+ * 0 on success. -+ * **-EBUSY** if *timer* is already initialized. -+ * **-EINVAL** if invalid *flags* are passed. -+ * **-EPERM** if *timer* is in a map that doesn't have any user references. -+ * The user space should either hold a file descriptor to a map with timers -+ * or pin such map in bpffs. When map is unpinned or file descriptor is -+ * closed all timers in the map will be cancelled and freed. -+ * -+ * long bpf_timer_set_callback(struct bpf_timer *timer, void *callback_fn) -+ * Description -+ * Configure the timer to call *callback_fn* static function. -+ * Return -+ * 0 on success. -+ * **-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier. -+ * **-EPERM** if *timer* is in a map that doesn't have any user references. -+ * The user space should either hold a file descriptor to a map with timers -+ * or pin such map in bpffs. When map is unpinned or file descriptor is -+ * closed all timers in the map will be cancelled and freed. -+ * -+ * long bpf_timer_start(struct bpf_timer *timer, u64 nsecs, u64 flags) -+ * Description -+ * Set timer expiration N nanoseconds from the current time. The -+ * configured callback will be invoked in soft irq context on some cpu -+ * and will not repeat unless another bpf_timer_start() is made. -+ * In such case the next invocation can migrate to a different cpu. -+ * Since struct bpf_timer is a field inside map element the map -+ * owns the timer. The bpf_timer_set_callback() will increment refcnt -+ * of BPF program to make sure that callback_fn code stays valid. -+ * When user space reference to a map reaches zero all timers -+ * in a map are cancelled and corresponding program's refcnts are -+ * decremented. This is done to make sure that Ctrl-C of a user -+ * process doesn't leave any timers running. If map is pinned in -+ * bpffs the callback_fn can re-arm itself indefinitely. -+ * bpf_map_update/delete_elem() helpers and user space sys_bpf commands -+ * cancel and free the timer in the given map element. -+ * The map can contain timers that invoke callback_fn-s from different -+ * programs. The same callback_fn can serve different timers from -+ * different maps if key/value layout matches across maps. -+ * Every bpf_timer_set_callback() can have different callback_fn. -+ * -+ * Return -+ * 0 on success. -+ * **-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier -+ * or invalid *flags* are passed. -+ * -+ * long bpf_timer_cancel(struct bpf_timer *timer) -+ * Description -+ * Cancel the timer and wait for callback_fn to finish if it was running. -+ * Return -+ * 0 if the timer was not active. -+ * 1 if the timer was active. -+ * **-EINVAL** if *timer* was not initialized with bpf_timer_init() earlier. -+ * **-EDEADLK** if callback_fn tried to call bpf_timer_cancel() on its -+ * own timer which would have led to a deadlock otherwise. -+ * -+ * u64 bpf_get_func_ip(void *ctx) -+ * Description -+ * Get address of the traced function (for tracing and kprobe programs). -+ * Return -+ * Address of the traced function. - */ - #define __BPF_FUNC_MAPPER(FN) \ - FN(unspec), \ -@@ -4904,6 +5016,14 @@ union bpf_attr { - FN(check_mtu), \ - FN(for_each_map_elem), \ - FN(snprintf), \ -+ FN(sys_bpf), \ -+ FN(btf_find_by_name_kind), \ -+ FN(sys_close), \ -+ FN(timer_init), \ -+ FN(timer_set_callback), \ -+ FN(timer_start), \ -+ FN(timer_cancel), \ -+ FN(get_func_ip), \ - /* */ - - /* integer value in 'imm' field of BPF_CALL instruction selects which helper -@@ -5081,6 +5201,12 @@ enum { - BPF_F_BPRM_SECUREEXEC = (1ULL << 0), - }; - -+/* Flags for bpf_redirect_map helper */ -+enum { -+ BPF_F_BROADCAST = (1ULL << 3), -+ BPF_F_EXCLUDE_INGRESS = (1ULL << 4), -+}; -+ - #define __bpf_md_ptr(type, name) \ - union { \ - type name; \ -@@ -5365,6 +5491,20 @@ struct sk_reuseport_md { - __u32 ip_protocol; /* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */ - __u32 bind_inany; /* Is sock bound to an INANY address? */ - __u32 hash; /* A hash of the packet 4 tuples */ -+ /* When reuse->migrating_sk is NULL, it is selecting a sk for the -+ * new incoming connection request (e.g. selecting a listen sk for -+ * the received SYN in the TCP case). reuse->sk is one of the sk -+ * in the reuseport group. The bpf prog can use reuse->sk to learn -+ * the local listening ip/port without looking into the skb. -+ * -+ * When reuse->migrating_sk is not NULL, reuse->sk is closed and -+ * reuse->migrating_sk is the socket that needs to be migrated -+ * to another listening socket. migrating_sk could be a fullsock -+ * sk that is fully established or a reqsk that is in-the-middle -+ * of 3-way handshake. -+ */ -+ __bpf_md_ptr(struct bpf_sock *, sk); -+ __bpf_md_ptr(struct bpf_sock *, migrating_sk); - }; - - #define BPF_TAG_SIZE 8 -@@ -6010,6 +6150,11 @@ struct bpf_spin_lock { - __u32 val; - }; - -+struct bpf_timer { -+ __u64 :64; -+ __u64 :64; -+} __attribute__((aligned(8))); -+ - struct bpf_sysctl { - __u32 write; /* Sysctl is being read (= 0) or written (= 1). - * Allows 1,2,4-byte read, but no write. -diff --git a/src/cc/export/helpers.h b/src/cc/export/helpers.h -index e9137f7f..a4e9b705 100644 ---- a/src/cc/export/helpers.h -+++ b/src/cc/export/helpers.h -@@ -847,6 +847,23 @@ static long (*bpf_snprintf)(char *str, __u32 str_size, const char *fmt, - __u64 *data, __u32 data_len) = - (void *)BPF_FUNC_snprintf; - -+static long (*bpf_sys_bpf)(__u32 cmd, void *attr, __u32 attr_size) = -+ (void *)BPF_FUNC_sys_bpf; -+static long (*bpf_btf_find_by_name_kind)(char *name, int name_sz, __u32 kind, int flags) = -+ (void *)BPF_FUNC_btf_find_by_name_kind; -+static long (*bpf_sys_close)(__u32 fd) = (void *)BPF_FUNC_sys_close; -+ -+struct bpf_timer; -+static long (*bpf_timer_init)(struct bpf_timer *timer, void *map, __u64 flags) = -+ (void *)BPF_FUNC_timer_init; -+static long (*bpf_timer_set_callback)(struct bpf_timer *timer, void *callback_fn) = -+ (void *)BPF_FUNC_timer_set_callback; -+static long (*bpf_timer_start)(struct bpf_timer *timer, __u64 nsecs, __u64 flags) = -+ (void *)BPF_FUNC_timer_start; -+static long (*bpf_timer_cancel)(struct bpf_timer *timer) = (void *)BPF_FUNC_timer_cancel; -+ -+static __u64 (*bpf_get_func_ip)(void *ctx) = (void *)BPF_FUNC_get_func_ip; -+ - /* llvm builtin functions that eBPF C program may use to - * emit BPF_LD_ABS and BPF_LD_IND instructions - */ -diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c -index b83d68fd..f3608cfe 100644 ---- a/src/cc/libbpf.c -+++ b/src/cc/libbpf.c -@@ -270,6 +270,14 @@ static struct bpf_helper helpers[] = { - {"check_mtu", "5.12"}, - {"for_each_map_elem", "5.13"}, - {"snprintf", "5.13"}, -+ {"sys_bpf", "5.14"}, -+ {"btf_find_by_name_kind", "5.14"}, -+ {"sys_close", "5.14"}, -+ {"timer_init", "5.15"}, -+ {"timer_set_callback", "5.15"}, -+ {"timer_start", "5.15"}, -+ {"timer_cancel", "5.15"}, -+ {"get_func_ip", "5.15"}, - }; - - static uint64_t ptr_to_u64(void *ptr) --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-threadsnoop-look-for-pthread_create-in-libc-too.patch b/SOURCES/bcc-0.20.0-threadsnoop-look-for-pthread_create-in-libc-too.patch deleted file mode 100644 index 2170eb8..0000000 --- a/SOURCES/bcc-0.20.0-threadsnoop-look-for-pthread_create-in-libc-too.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 460a71ab24ad511318342077ac9ef57df543375f Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Thu, 16 Sep 2021 14:44:23 +0200 -Subject: [PATCH] threadsnoop: look for pthread_create in libc too - -Since glibc 2.34, pthread features are integrated in libc directly. -Look for pthread_create there too when it is not found in libpthread. - -Fixes #3623 ---- - tools/threadsnoop.py | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/tools/threadsnoop.py b/tools/threadsnoop.py -index 04c5e680..471b0c3c 100755 ---- a/tools/threadsnoop.py -+++ b/tools/threadsnoop.py -@@ -38,7 +38,12 @@ void do_entry(struct pt_regs *ctx) { - events.perf_submit(ctx, &data, sizeof(data)); - }; - """) --b.attach_uprobe(name="pthread", sym="pthread_create", fn_name="do_entry") -+ -+# Since version 2.34, pthread features are integrated in libc -+try: -+ b.attach_uprobe(name="pthread", sym="pthread_create", fn_name="do_entry") -+except Exception: -+ b.attach_uprobe(name="c", sym="pthread_create", fn_name="do_entry") - - print("%-10s %-6s %-16s %s" % ("TIME(ms)", "PID", "COMM", "FUNC")) - --- -2.31.1 - diff --git a/SOURCES/bcc-0.20.0-tools-Fix-BCC-bio-tools-with-recent-kernel-change.patch b/SOURCES/bcc-0.20.0-tools-Fix-BCC-bio-tools-with-recent-kernel-change.patch deleted file mode 100644 index 428499d..0000000 --- a/SOURCES/bcc-0.20.0-tools-Fix-BCC-bio-tools-with-recent-kernel-change.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 59a4e7ea490f78ba289c1ba461bfe1fce9e7ef19 Mon Sep 17 00:00:00 2001 -From: Hengqi Chen -Date: Sat, 11 Dec 2021 17:36:17 +0800 -Subject: [PATCH] tools: Fix BCC bio tools with recent kernel change - -Several BCC bio tools are broken due to kernel change ([0]). -blk_account_io_{start, done} were renamed to __blk_account_io_{start, done}, -and the symbols gone from /proc/kallsyms. Fix them by checking symbol existence. - - [0]: https://github.com/torvalds/linux/commit/be6bfe36db1795babe9d92178a47b2e02193cb0f - -Signed-off-by: Hengqi Chen ---- - tools/biolatency.py | 12 ++++++++---- - tools/biolatpcts.py | 5 ++++- - tools/biosnoop.py | 11 ++++++++--- - tools/biotop.py | 11 ++++++++--- - 4 files changed, 28 insertions(+), 11 deletions(-) - -diff --git a/tools/biolatency.py b/tools/biolatency.py -index 0599609b..2e75a5de 100755 ---- a/tools/biolatency.py -+++ b/tools/biolatency.py -@@ -168,13 +168,18 @@ bpf_text = bpf_text.replace("STORE", store_str) - # load BPF program - b = BPF(text=bpf_text) - if args.queued: -- b.attach_kprobe(event="blk_account_io_start", fn_name="trace_req_start") -+ if BPF.get_kprobe_functions(b'__blk_account_io_start'): -+ b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_req_start") -+ else: -+ b.attach_kprobe(event="blk_account_io_start", fn_name="trace_req_start") - else: - if BPF.get_kprobe_functions(b'blk_start_request'): - b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start") - b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_req_start") --b.attach_kprobe(event="blk_account_io_done", -- fn_name="trace_req_done") -+if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_done") -+else: -+ b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_done") - - if not args.json: - print("Tracing block device I/O... Hit Ctrl-C to end.") -@@ -277,4 +282,3 @@ dist = b.get_table("dist") - countdown -= 1 - if exiting or countdown == 0: - exit() -- -diff --git a/tools/biolatpcts.py b/tools/biolatpcts.py -index 5ab8aa5f..a2f59592 100755 ---- a/tools/biolatpcts.py -+++ b/tools/biolatpcts.py -@@ -142,7 +142,10 @@ bpf_source = bpf_source.replace('__MAJOR__', str(major)) - bpf_source = bpf_source.replace('__MINOR__', str(minor)) - - bpf = BPF(text=bpf_source) --bpf.attach_kprobe(event="blk_account_io_done", fn_name="kprobe_blk_account_io_done") -+if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ bpf.attach_kprobe(event="__blk_account_io_done", fn_name="kprobe_blk_account_io_done") -+else: -+ bpf.attach_kprobe(event="blk_account_io_done", fn_name="kprobe_blk_account_io_done") - - # times are in usecs - MSEC = 1000 -diff --git a/tools/biosnoop.py b/tools/biosnoop.py -index 333949b5..2b954ac9 100755 ---- a/tools/biosnoop.py -+++ b/tools/biosnoop.py -@@ -163,12 +163,17 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) - - # initialize BPF - b = BPF(text=bpf_text) --b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") -+if BPF.get_kprobe_functions(b'__blk_account_io_start'): -+ b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start") -+else: -+ b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") - if BPF.get_kprobe_functions(b'blk_start_request'): - b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start") - b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_req_start") --b.attach_kprobe(event="blk_account_io_done", -- fn_name="trace_req_completion") -+if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_completion") -+else: -+ b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_completion") - - # header - print("%-11s %-14s %-6s %-7s %-1s %-10s %-7s" % ("TIME(s)", "COMM", "PID", -diff --git a/tools/biotop.py b/tools/biotop.py -index 596f0076..0ebfef0e 100755 ---- a/tools/biotop.py -+++ b/tools/biotop.py -@@ -180,12 +180,17 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) - exit() - - b = BPF(text=bpf_text) --b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") -+if BPF.get_kprobe_functions(b'__blk_account_io_start'): -+ b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start") -+else: -+ b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") - if BPF.get_kprobe_functions(b'blk_start_request'): - b.attach_kprobe(event="blk_start_request", fn_name="trace_req_start") - b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_req_start") --b.attach_kprobe(event="blk_account_io_done", -- fn_name="trace_req_completion") -+if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_completion") -+else: -+ b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_completion") - - print('Tracing... Output every %d secs. Hit Ctrl-C to end' % interval) - --- -2.35.1 - diff --git a/SOURCES/bcc-0.20.0-tools-include-blk-mq.h-in-bio-tools.patch b/SOURCES/bcc-0.20.0-tools-include-blk-mq.h-in-bio-tools.patch deleted file mode 100644 index 03e703f..0000000 --- a/SOURCES/bcc-0.20.0-tools-include-blk-mq.h-in-bio-tools.patch +++ /dev/null @@ -1,66 +0,0 @@ -From ee81072e75bcc796b1154c315e2eb0371928a922 Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Wed, 23 Feb 2022 16:04:30 +0100 -Subject: [PATCH] tools: include blk-mq.h in bio tools - -Kernel commit 24b83deb29b ("block: move struct request to blk-mq.h") -has moved struct request from blkdev.h to blk-mq.h. It results in -several bio tools to fail with errors of the following type: - -error: incomplete definition of type 'struct request' - -Since blk-mq.h had always included blkdev.h. it is safe to simply -replace the inclusion of blkdev.h by blk-mq-h. It works on both older -and newer kernel. - -Fixes: #3869 - -Signed-off-by: Jerome Marchand ---- - tools/biolatency.py | 2 +- - tools/biosnoop.py | 2 +- - tools/biotop.py | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/tools/biolatency.py b/tools/biolatency.py -index f4e2c9ea..427cee47 100755 ---- a/tools/biolatency.py -+++ b/tools/biolatency.py -@@ -64,7 +64,7 @@ debug = 0 - # define BPF program - bpf_text = """ - #include --#include -+#include - - typedef struct disk_key { - char disk[DISK_NAME_LEN]; -diff --git a/tools/biosnoop.py b/tools/biosnoop.py -index 2b954ac9..ae38e384 100755 ---- a/tools/biosnoop.py -+++ b/tools/biosnoop.py -@@ -37,7 +37,7 @@ debug = 0 - # define BPF program - bpf_text=""" - #include --#include -+#include - - // for saving the timestamp and __data_len of each request - struct start_req_t { -diff --git a/tools/biotop.py b/tools/biotop.py -index eac4dab9..b3e3ea00 100755 ---- a/tools/biotop.py -+++ b/tools/biotop.py -@@ -54,7 +54,7 @@ diskstats = "/proc/diskstats" - # load BPF program - bpf_text = """ - #include --#include -+#include - - // for saving the timestamp and __data_len of each request - struct start_req_t { --- -2.35.1 - diff --git a/SOURCES/bcc-0.20.0-tools-readahead-compatible-with-kernel-version-5.10-.patch b/SOURCES/bcc-0.20.0-tools-readahead-compatible-with-kernel-version-5.10-.patch deleted file mode 100644 index b658d56..0000000 --- a/SOURCES/bcc-0.20.0-tools-readahead-compatible-with-kernel-version-5.10-.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 6c9d91c2196e69682a611dbfc10a0731f86deada Mon Sep 17 00:00:00 2001 -From: zcy -Date: Fri, 25 Jun 2021 10:16:53 +0800 -Subject: [PATCH] tools/readahead compatible with kernel version >= 5.10 - (#3507) - -After kernel version 5.10, __do_page_cache_readahead() was renamed to do_page_cache_ra(), -let us try both in readahead.py. ---- - tools/readahead.py | 12 ++++++++---- - tools/readahead_example.txt | 22 +++++++++++----------- - 2 files changed, 19 insertions(+), 15 deletions(-) - -diff --git a/tools/readahead.py b/tools/readahead.py -index 14182d5a..b338261f 100755 ---- a/tools/readahead.py -+++ b/tools/readahead.py -@@ -20,7 +20,7 @@ import argparse - - # arguments - examples = """examples: -- ./readahead -d 20 # monitor for 10 seconds and generate stats -+ ./readahead -d 20 # monitor for 20 seconds and generate stats - """ - - parser = argparse.ArgumentParser( -@@ -95,15 +95,19 @@ int entry_mark_page_accessed(struct pt_regs *ctx) { - """ - - b = BPF(text=program) --b.attach_kprobe(event="__do_page_cache_readahead", fn_name="entry__do_page_cache_readahead") --b.attach_kretprobe(event="__do_page_cache_readahead", fn_name="exit__do_page_cache_readahead") -+if BPF.get_kprobe_functions(b"__do_page_cache_readahead"): -+ ra_event = "__do_page_cache_readahead" -+else: -+ ra_event = "do_page_cache_ra" -+b.attach_kprobe(event=ra_event, fn_name="entry__do_page_cache_readahead") -+b.attach_kretprobe(event=ra_event, fn_name="exit__do_page_cache_readahead") - b.attach_kretprobe(event="__page_cache_alloc", fn_name="exit__page_cache_alloc") - b.attach_kprobe(event="mark_page_accessed", fn_name="entry_mark_page_accessed") - - # header - print("Tracing... Hit Ctrl-C to end.") - --# print -+# print - def print_stats(): - print() - print("Read-ahead unused pages: %d" % (b["pages"][ct.c_ulong(0)].value)) -diff --git a/tools/readahead_example.txt b/tools/readahead_example.txt -index 079dbaae..6d675c13 100644 ---- a/tools/readahead_example.txt -+++ b/tools/readahead_example.txt -@@ -2,20 +2,20 @@ Demonstration of readahead, the Linux eBPF/bcc version - - Read-ahead mechanism is used by operation sytems to optimize sequential operations - by reading ahead some pages to avoid more expensive filesystem operations. This tool --shows the performance of the read-ahead caching on the system under a given load to -+shows the performance of the read-ahead caching on the system under a given load to - investigate any caching issues. It shows a count for unused pages in the cache and - also prints a histogram showing how long they have remianed there. - - Usage Scenario - ============== - --Consider that you are developing a React Native application which performs aggressive -+Consider that you are developing a React Native application which performs aggressive - reads while re-encoding a video in local-storage. Usually such an app would be multi- --layered and have transitional library dependencies. The actual read may be performed --by some unknown native library which may or may not be using hints to the OS, such as --madvise(p, LEN, MADV_SEQUENTIAL). If high IOPS is observed in such an app, running --readahead may pin the issue much faster in this case as the developer digs deeper --into what may be causing this. -+layered and have transitional library dependencies. The actual read may be performed -+by some unknown native library which may or may not be using hints to the OS, such as -+madvise(p, LEN, MADV_SEQUENTIAL). If high IOPS is observed in such an app, running -+readahead may pin the issue much faster in this case as the developer digs deeper -+into what may be causing this. - - An example where such an issue can surface is: https://github.com/boltdb/bolt/issues/691 - -@@ -40,7 +40,7 @@ Read-ahead unused pages: 6765 - 2048 -> 4095 : 439 |**** | - 4096 -> 8191 : 188 |* | - --In the example above, we recorded system-wide stats for 30 seconds. We can observe that -+In the example above, we recorded system-wide stats for 30 seconds. We can observe that - while most of the pages stayed in the readahead cache for quite less time, after 30 - seconds 6765 pages still remained in the cache, yet unaccessed. - -@@ -49,12 +49,12 @@ Note on Kprobes Usage - - This tool uses Kprobes on the following kernel functions: - --__do_page_cache_readahead() -+__do_page_cache_readahead()/do_page_cache_ra() (After kernel version 5.10 (include), __do_page_cache_readahead was renamed to do_page_cache_ra) - __page_cache_alloc() - mark_page_accessed() - --Since the tool uses Kprobes, depending on your linux kernel's compilation, these --functions may be inlined and hence not available for Kprobes. To see whether you have -+Since the tool uses Kprobes, depending on your linux kernel's compilation, these -+functions may be inlined and hence not available for Kprobes. To see whether you have - the functions available, check vmlinux source and binary to confirm whether inlining is - happening or not. You can also check /proc/kallsyms on the host and verify if the target - functions are present there before using this tool. --- -2.31.1 - diff --git a/SOURCES/bcc-0.24.0-C9S-Fix-mdflush.patch b/SOURCES/bcc-0.24.0-C9S-Fix-mdflush.patch new file mode 100644 index 0000000..716789e --- /dev/null +++ b/SOURCES/bcc-0.24.0-C9S-Fix-mdflush.patch @@ -0,0 +1,44 @@ +From 5e7543d35596fabd9e5b02b58f8910bf572ca2fa Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Thu, 7 Oct 2021 17:31:53 +0200 +Subject: [PATCH] C9S: Fix mdflush + +Since kernel commit 309dca309fc ("block: store a block_device pointer +in struct bio") struct bio points again to a block_device and not to a +gendisk directly. However mdflush is looking at the presence or not of +the bio_dev macro to check whether to get the gendisk directly from +the bio or not, which doesn't work anymore since the bio_dev macro +still exists. Since we don't have to deal other ekrnel kernel version +but our own, just use the definition that we use in our kernels. + +Signed-off-by: Jerome Marchand +--- + tools/mdflush.py | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/tools/mdflush.py b/tools/mdflush.py +index 8a23520b..3581d1bf 100755 +--- a/tools/mdflush.py ++++ b/tools/mdflush.py +@@ -35,18 +35,7 @@ int kprobe__md_flush_request(struct pt_regs *ctx, void *mddev, struct bio *bio) + u32 pid = bpf_get_current_pid_tgid() >> 32; + data.pid = pid; + bpf_get_current_comm(&data.comm, sizeof(data.comm)); +-/* +- * The following deals with a kernel version change (in mainline 4.14, although +- * it may be backported to earlier kernels) with how the disk name is accessed. +- * We handle both pre- and post-change versions here. Please avoid kernel +- * version tests like this as much as possible: they inflate the code, test, +- * and maintenance burden. +- */ +-#ifdef bio_dev +- struct gendisk *bi_disk = bio->bi_disk; +-#else + struct gendisk *bi_disk = bio->bi_bdev->bd_disk; +-#endif + bpf_probe_read_kernel(&data.disk, sizeof(data.disk), bi_disk->disk_name); + events.perf_submit(ctx, &data, sizeof(data)); + return 0; +-- +2.35.1 + diff --git a/SOURCES/bcc-0.24.0-C9S-libpbf-version-fixes.patch b/SOURCES/bcc-0.24.0-C9S-libpbf-version-fixes.patch new file mode 100644 index 0000000..3c42a52 --- /dev/null +++ b/SOURCES/bcc-0.24.0-C9S-libpbf-version-fixes.patch @@ -0,0 +1,297 @@ +From a81f219d7f2bfc70dba1eb12208e3e6ab7c81b50 Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Thu, 24 Mar 2022 16:08:17 +0100 +Subject: [PATCH] C9S: libpbf version fixes + +Revert "bcc: Replace deprecated libbpf APIs" since the libbpf version +provided in C9S doesn't provide the new APIs. + +Remove BPF_MAP_TYPE_BLOOM_FILTER from bps since the libbpf version in +C9S, doesn't provide bloom filter map. + +Add definition of struct bpf_core_relo. +--- + introspection/bps.c | 1 - + src/cc/bcc_btf.cc | 73 +++++++++++++++++++++++++++++++++++++++- + src/cc/libbpf.c | 82 ++++++--------------------------------------- + 3 files changed, 83 insertions(+), 73 deletions(-) + +diff --git a/introspection/bps.c b/introspection/bps.c +index 232b23d4..6ec02e6c 100644 +--- a/introspection/bps.c ++++ b/introspection/bps.c +@@ -80,7 +80,6 @@ static const char * const map_type_strings[] = { + [BPF_MAP_TYPE_RINGBUF] = "ringbuf", + [BPF_MAP_TYPE_INODE_STORAGE] = "inode_storage", + [BPF_MAP_TYPE_TASK_STORAGE] = "task_storage", +- [BPF_MAP_TYPE_BLOOM_FILTER] = "bloom_filter", + }; + + #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +diff --git a/src/cc/bcc_btf.cc b/src/cc/bcc_btf.cc +index 7f551ae8..c78ba823 100644 +--- a/src/cc/bcc_btf.cc ++++ b/src/cc/bcc_btf.cc +@@ -170,6 +170,77 @@ static int btf_ext_setup_line_info(struct btf_ext *btf_ext) + return btf_ext_setup_info(btf_ext, ¶m); + } + ++/* bpf_core_relo_kind encodes which aspect of captured field/type/enum value ++ * has to be adjusted by relocations. ++ */ ++enum bpf_core_relo_kind { ++ BPF_FIELD_BYTE_OFFSET = 0, /* field byte offset */ ++ BPF_FIELD_BYTE_SIZE = 1, /* field size in bytes */ ++ BPF_FIELD_EXISTS = 2, /* field existence in target kernel */ ++ BPF_FIELD_SIGNED = 3, /* field signedness (0 - unsigned, 1 - signed) */ ++ BPF_FIELD_LSHIFT_U64 = 4, /* bitfield-specific left bitshift */ ++ BPF_FIELD_RSHIFT_U64 = 5, /* bitfield-specific right bitshift */ ++ BPF_TYPE_ID_LOCAL = 6, /* type ID in local BPF object */ ++ BPF_TYPE_ID_TARGET = 7, /* type ID in target kernel */ ++ BPF_TYPE_EXISTS = 8, /* type existence in target kernel */ ++ BPF_TYPE_SIZE = 9, /* type size in bytes */ ++ BPF_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */ ++ BPF_ENUMVAL_VALUE = 11, /* enum value integer value */ ++}; ++ ++/* The minimum bpf_core_relo checked by the loader ++ * ++ * CO-RE relocation captures the following data: ++ * - insn_off - instruction offset (in bytes) within a BPF program that needs ++ * its insn->imm field to be relocated with actual field info; ++ * - type_id - BTF type ID of the "root" (containing) entity of a relocatable ++ * type or field; ++ * - access_str_off - offset into corresponding .BTF string section. String ++ * interpretation depends on specific relocation kind: ++ * - for field-based relocations, string encodes an accessed field using ++ * a sequence of field and array indices, separated by colon (:). It's ++ * conceptually very close to LLVM's getelementptr ([0]) instruction's ++ * arguments for identifying offset to a field. ++ * - for type-based relocations, strings is expected to be just "0"; ++ * - for enum value-based relocations, string contains an index of enum ++ * value within its enum type; ++ * ++ * Example to provide a better feel. ++ * ++ * struct sample { ++ * int a; ++ * struct { ++ * int b[10]; ++ * }; ++ * }; ++ * ++ * struct sample *s = ...; ++ * int x = &s->a; // encoded as "0:0" (a is field #0) ++ * int y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1, ++ * // b is field #0 inside anon struct, accessing elem #5) ++ * int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array) ++ * ++ * type_id for all relocs in this example will capture BTF type id of ++ * `struct sample`. ++ * ++ * Such relocation is emitted when using __builtin_preserve_access_index() ++ * Clang built-in, passing expression that captures field address, e.g.: ++ * ++ * bpf_probe_read(&dst, sizeof(dst), ++ * __builtin_preserve_access_index(&src->a.b.c)); ++ * ++ * In this case Clang will emit field relocation recording necessary data to ++ * be able to find offset of embedded `a.b.c` field within `src` struct. ++ * ++ * [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction ++ */ ++struct bpf_core_relo { ++ __u32 insn_off; ++ __u32 type_id; ++ __u32 access_str_off; ++ enum bpf_core_relo_kind kind; ++}; ++ + static int btf_ext_setup_core_relos(struct btf_ext *btf_ext) + { + struct btf_ext_sec_setup_param param = { +@@ -597,7 +668,7 @@ int BTF::load(uint8_t *btf_sec, uintptr_t btf_sec_size, + return -1; + } + +- if (btf__load_into_kernel(btf)) { ++ if (btf__load(btf)) { + btf__free(btf); + warning("Loading .BTF section failed\n"); + return -1; +diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c +index e6403299..68af4b35 100644 +--- a/src/cc/libbpf.c ++++ b/src/cc/libbpf.c +@@ -297,25 +297,6 @@ static uint64_t ptr_to_u64(void *ptr) + return (uint64_t) (unsigned long) ptr; + } + +-static int libbpf_bpf_map_create(struct bpf_create_map_attr *create_attr) +-{ +- LIBBPF_OPTS(bpf_map_create_opts, p); +- +- p.map_flags = create_attr->map_flags; +- p.numa_node = create_attr->numa_node; +- p.btf_fd = create_attr->btf_fd; +- p.btf_key_type_id = create_attr->btf_key_type_id; +- p.btf_value_type_id = create_attr->btf_value_type_id; +- p.map_ifindex = create_attr->map_ifindex; +- if (create_attr->map_type == BPF_MAP_TYPE_STRUCT_OPS) +- p.btf_vmlinux_value_type_id = create_attr->btf_vmlinux_value_type_id; +- else +- p.inner_map_fd = create_attr->inner_map_fd; +- +- return bpf_map_create(create_attr->map_type, create_attr->name, create_attr->key_size, +- create_attr->value_size, create_attr->max_entries, &p); +-} +- + int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit) + { + unsigned name_len = attr->name ? strlen(attr->name) : 0; +@@ -323,7 +304,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit) + + memcpy(map_name, attr->name, min(name_len, BPF_OBJ_NAME_LEN - 1)); + attr->name = map_name; +- int ret = libbpf_bpf_map_create(attr); ++ int ret = bpf_create_map_xattr(attr); + + if (ret < 0 && errno == EPERM) { + if (!allow_rlimit) +@@ -335,7 +316,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit) + rl.rlim_max = RLIM_INFINITY; + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0) +- ret = libbpf_bpf_map_create(attr); ++ ret = bpf_create_map_xattr(attr); + } + } + +@@ -345,12 +326,12 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit) + attr->btf_fd = 0; + attr->btf_key_type_id = 0; + attr->btf_value_type_id = 0; +- ret = libbpf_bpf_map_create(attr); ++ ret = bpf_create_map_xattr(attr); + } + + if (ret < 0 && name_len && (errno == E2BIG || errno == EINVAL)) { + map_name[0] = '\0'; +- ret = libbpf_bpf_map_create(attr); ++ ret = bpf_create_map_xattr(attr); + } + + if (ret < 0 && errno == EPERM) { +@@ -363,7 +344,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit) + rl.rlim_max = RLIM_INFINITY; + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0) +- ret = libbpf_bpf_map_create(attr); ++ ret = bpf_create_map_xattr(attr); + } + } + return ret; +@@ -627,47 +608,6 @@ int bpf_prog_get_tag(int fd, unsigned long long *ptag) + return 0; + } + +-static int libbpf_bpf_prog_load(const struct bpf_load_program_attr *load_attr, +- char *log_buf, size_t log_buf_sz) +-{ +- LIBBPF_OPTS(bpf_prog_load_opts, p); +- +- if (!load_attr || !log_buf != !log_buf_sz) { +- errno = EINVAL; +- return -EINVAL; +- } +- +- p.expected_attach_type = load_attr->expected_attach_type; +- switch (load_attr->prog_type) { +- case BPF_PROG_TYPE_STRUCT_OPS: +- case BPF_PROG_TYPE_LSM: +- p.attach_btf_id = load_attr->attach_btf_id; +- break; +- case BPF_PROG_TYPE_TRACING: +- case BPF_PROG_TYPE_EXT: +- p.attach_btf_id = load_attr->attach_btf_id; +- p.attach_prog_fd = load_attr->attach_prog_fd; +- break; +- default: +- p.prog_ifindex = load_attr->prog_ifindex; +- p.kern_version = load_attr->kern_version; +- } +- p.log_level = load_attr->log_level; +- p.log_buf = log_buf; +- p.log_size = log_buf_sz; +- p.prog_btf_fd = load_attr->prog_btf_fd; +- p.func_info_rec_size = load_attr->func_info_rec_size; +- p.func_info_cnt = load_attr->func_info_cnt; +- p.func_info = load_attr->func_info; +- p.line_info_rec_size = load_attr->line_info_rec_size; +- p.line_info_cnt = load_attr->line_info_cnt; +- p.line_info = load_attr->line_info; +- p.prog_flags = load_attr->prog_flags; +- +- return bpf_prog_load(load_attr->prog_type, load_attr->name, load_attr->license, +- load_attr->insns, load_attr->insns_cnt, &p); +-} +- + int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len, + char *log_buf, unsigned log_buf_size, bool allow_rlimit) + { +@@ -750,7 +690,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len, + attr->name = prog_name; + } + +- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size); ++ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size); + + // func_info/line_info may not be supported in old kernels. + if (ret < 0 && attr->func_info && errno == EINVAL) { +@@ -761,14 +701,14 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len, + attr->line_info = NULL; + attr->line_info_cnt = 0; + attr->line_info_rec_size = 0; +- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size); ++ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size); + } + + // BPF object name is not supported on older Kernels. + // If we failed due to this, clear the name and try again. + if (ret < 0 && name_len && (errno == E2BIG || errno == EINVAL)) { + prog_name[0] = '\0'; +- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size); ++ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size); + } + + if (ret < 0 && errno == EPERM) { +@@ -787,7 +727,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len, + rl.rlim_max = RLIM_INFINITY; + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0) +- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size); ++ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size); + } + } + +@@ -805,7 +745,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len, + // If logging is not already enabled, enable it and do the syscall again. + if (attr->log_level == 0) { + attr->log_level = 1; +- ret = libbpf_bpf_prog_load(attr, log_buf, log_buf_size); ++ ret = bpf_load_program_xattr(attr, log_buf, log_buf_size); + } + // Print the log message and return. + bpf_print_hints(ret, log_buf); +@@ -829,7 +769,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len, + goto return_result; + } + tmp_log_buf[0] = 0; +- ret = libbpf_bpf_prog_load(attr, tmp_log_buf, tmp_log_buf_size); ++ ret = bpf_load_program_xattr(attr, tmp_log_buf, tmp_log_buf_size); + if (ret < 0 && errno == ENOSPC) { + // Temporary buffer size is not enough. Double it and try again. + free(tmp_log_buf); +-- +2.36.1 + diff --git a/SOURCES/bcc-0.24.0-Revert-libbpf-1.0-changes.patch b/SOURCES/bcc-0.24.0-Revert-libbpf-1.0-changes.patch new file mode 100644 index 0000000..8d86dd9 --- /dev/null +++ b/SOURCES/bcc-0.24.0-Revert-libbpf-1.0-changes.patch @@ -0,0 +1,2331 @@ +From 09cee55c78fe5c165c7d7c21f596c23831f844e1 Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Tue, 19 Apr 2022 18:02:13 +0200 +Subject: [PATCH] Revert libbpf 1.0 changes + +Revert "libbpf-tools: remove now unnecessary bump_memlock_rlimit()" + +This reverts commit 5d8f5c45b16c389bb342d2b80c9f5e13e4f3b112. + +Revert "libbpf-tools: update vfsstat for libbpf 1.0" + +This reverts commit f083d3dc37372e555133519cb417f893c431eef0. + +Revert "libbpf-tools: update tcprtt for libbpf 1.0" + +This reverts commit a5b6c3cb2d20718ef002e7447046fad877590b91. + +Revert "libbpf-tools: update tcpconnlat for libbpf 1.0" + +This reverts commit aae06012af8cc8c2b592340f8783a2873aad2023. + +Revert "libbpf-tools: update tcpconnect for libbpf 1.0" + +This reverts commit 4051a9e83cb68733af20ce263fcc41c8aadc2622. + +Revert "libbpf-tools: update syscount for libbpf 1.0" + +This reverts commit d2dc7bcd0d94ef54e336119a2a79113b87839820. + +Revert "libbpf-tools: update statsnoop for libbpf 1.0" + +This reverts commit 0e348e5ed66aabd0cd5c0c75932f245bd1385b3b. + +Revert "libbpf-tools: update solisten for libbpf 1.0" + +This reverts commit 60dd074e26e762727e685334999bec5851adaef9. + +Revert "libbpf-tools: update softirqs for libbpf 1.0" + +This reverts commit 92806a435c2e1b248acdb9d0dc5b3eedc86994b0. + +Revert "libbpf-tools: update runqslower for libbpf 1.0" + +This reverts commit e6477620ccfc9abe10f7e630e65381204daa5ba8. + +Revert "libbpf-tools: update runqlen for libbpf 1.0" + +This reverts commit a7f0148372018140940d66f8faf53cb5add1e858. + +Revert "libbpf-tools: update runqlat for libbpf 1.0" + +This reverts commit 865f990b7139dca166a43bbc8159f6acd4bfbee6. + +Revert "libbpf-tools: update readahead for libbpf 1.0" + +This reverts commit 3c5dae6380dcc2034a8746c648e3bb24ea61f886. + +Revert "libbpf-tools: update opensnoop for libbpf 1.0" + +This reverts commit 34a680ba8da7e61befad67ebccb69c5041e9e288. + +Revert "libbpf-tools: update offcputime for libbpf 1.0" + +This reverts commit 5ef6d9922841d7cfde1994c25ccbac53858ed99f. + +Revert "libbpf-tools: update numamove for libbpf 1.0" + +This reverts commit 824ffd2a1fbb527f5fd25e2caa4b43fbf1ee858b. + +Revert "libbpf-tools: update mountsnoop for libbpf 1.0" + +This reverts commit 08301e93e5cea8575d5dc4b66fb7a76cebd5969b. + +Revert "libbpf-tools: update llcstat for libbpf 1.0" + +This reverts commit dbee9ea8ede33166fa70ecc33af7d7721ef26280. + +Revert "libbpf-tools: update hardirqs for libbpf 1.0" + +This reverts commit 8fcf08c81d30d80f89f995f79ef3246ce99c72dd. + +Revert "libbpf-tools: update gethostlatency for libbpf 1.0" + +This reverts commit 54a239abd21df9d6fc5d8db7ae7a26c5d8db2440. + +Revert "libbpf-tools: update funclatency for libbpf 1.0" + +This reverts commit d7b3ed3a8b2169087534738670d108489711f2d1. + +Revert "libbpf-tools: update fsslower for libbpf 1.0" + +This reverts commit 511ab72f046848d6df3f7c6ec0411b1609e165fb. + +Revert "libbpf-tools: update fsdist for libbpf 1.0" + +This reverts commit 21586658c86e1a20e9195d8715d37d714be93bb6. + +Revert "libbpf-tools: update filetop for libbpf 1.0" + +This reverts commit e6d151227f56433a317790d56ba7875ccae00448. + +Revert "libbpf-tools: update filelife for libbpf 1.0" + +This reverts commit 4ca8dd95efb7c4f149b889b700beeda036ebe822. + +Revert "libbpf-tools: update exitsnoop for libbpf 1.0" + +This reverts commit 0a035be644cf818354f3faab25a74e005a66d954. + +Revert "libbpf-tools: update execsnoop for libbpf 1.0" + +This reverts commit 7da38aabbefa41b8553e9fdec7744a5e423b5119. + +Revert "libbpf-tools: update cpudist for libbpf 1.0" + +This reverts commit dab1d09ef49e74c4c95f933e97e16dfc074338c2. + +Revert "libbpf-tools: update drsnoop for libbpf 1.0" + +This reverts commit 9cfdf5e04b32ca079a634ff60de7c08e3c41ccf5. + +Revert "libbpf-tools: fix cpufreq.bpf.c and update cpufreq for libbpf 1.0" + +This reverts commit f2006eaa5901d6ccf51d24b18c644f2fb1d41757. + +Revert "libbpf-tools: update cachestat for libbpf 1.0" + +This reverts commit 4970d23f9ff308c5860612ad6395d7692b05104e. + +Revert "libbpf-tools: update bitesize for libbpf 1.0" + +This reverts commit 7bea6c4ad9a460fc34eb618e488e44ca014e8ac7. + +Revert "libbpf-tools: update biostacks for libbpf 1.0" + +This reverts commit 49bb367628500104411d42851194162bec5d1f4c. + +Revert "libbpf-tools: update biosnoop for libbpf 1.0" + +This reverts commit 519ed8cf9c0daff75ecb3f435a3efec2087945a6. + +Revert "libbpf-tools: update biopattern for libbpf 1.0" + +This reverts commit c5b17e65a6e59fae1223bf493648050643ad9179. + +Revert "libbpf-tools: update biolatency for libbpf 1.0" + +This reverts commit 24d723699fbeeb8686acabc09ecefcceb749b9e0. + +Revert "libbpf-tools: update bindsnoop for libbpf 1.0" + +This reverts commit 7f2f4c4123a55438754b1a29f7ad3d3cfdbc7373. + +Revert "libbpf-tools: update ksnoop for libbpf 1.0" + +This reverts commit 18dc2ac7d84a854e2f5ac9ce1b532a0c59acf49e. + +Revert "libbpf-tools: update bashreadline for libbpf 1.0" + +This reverts commit 2cf0ba491d16386529c50ff0a9ec3eb9f86a2493. + +Signed-off-by: Jerome Marchand +--- + libbpf-tools/bashreadline.c | 24 ++++++++----- + libbpf-tools/bindsnoop.c | 21 +++++++---- + libbpf-tools/biolatency.c | 28 +++++++++------ + libbpf-tools/biopattern.c | 7 +++- + libbpf-tools/biosnoop.c | 67 +++++++++++++++++++++-------------- + libbpf-tools/biostacks.c | 39 ++++++++++++-------- + libbpf-tools/bitesize.c | 7 +++- + libbpf-tools/cachestat.c | 7 +++- + libbpf-tools/cpudist.c | 7 +++- + libbpf-tools/cpufreq.bpf.c | 11 ------ + libbpf-tools/cpufreq.c | 15 +++++--- + libbpf-tools/drsnoop.c | 21 +++++++---- + libbpf-tools/execsnoop.c | 22 ++++++++---- + libbpf-tools/exitsnoop.c | 20 +++++++---- + libbpf-tools/filelife.c | 21 +++++++---- + libbpf-tools/filetop.c | 6 +++- + libbpf-tools/fsdist.c | 38 +++++++++++++------- + libbpf-tools/fsslower.c | 46 ++++++++++++++++-------- + libbpf-tools/funclatency.c | 32 ++++++++++------- + libbpf-tools/gethostlatency.c | 49 +++++++++++++++---------- + libbpf-tools/hardirqs.c | 34 +++++++++++------- + libbpf-tools/ksnoop.c | 65 ++++++++++++++++----------------- + libbpf-tools/llcstat.bpf.c | 4 +-- + libbpf-tools/llcstat.c | 13 +++++-- + libbpf-tools/mountsnoop.c | 20 +++++++---- + libbpf-tools/numamove.c | 16 ++++++--- + libbpf-tools/offcputime.c | 7 +++- + libbpf-tools/opensnoop.c | 21 +++++++---- + libbpf-tools/readahead.c | 7 +++- + libbpf-tools/runqlat.c | 7 +++- + libbpf-tools/runqlen.c | 13 +++++-- + libbpf-tools/runqslower.c | 22 ++++++++---- + libbpf-tools/softirqs.c | 7 +++- + libbpf-tools/solisten.c | 20 +++++++---- + libbpf-tools/statsnoop.c | 20 +++++++---- + libbpf-tools/syscount.c | 18 ++++++---- + libbpf-tools/tcpconnect.c | 25 ++++++++----- + libbpf-tools/tcpconnlat.c | 24 +++++++++---- + libbpf-tools/tcprtt.c | 7 +++- + libbpf-tools/trace_helpers.c | 22 ++++++++---- + libbpf-tools/trace_helpers.h | 1 + + libbpf-tools/vfsstat.c | 8 ++++- + 42 files changed, 576 insertions(+), 293 deletions(-) + +diff --git a/libbpf-tools/bashreadline.c b/libbpf-tools/bashreadline.c +index 2fcb2e2c..ab3b955e 100644 +--- a/libbpf-tools/bashreadline.c ++++ b/libbpf-tools/bashreadline.c +@@ -149,6 +149,7 @@ int main(int argc, char **argv) + .doc = argp_program_doc, + }; + struct bashreadline_bpf *obj = NULL; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + char *readline_so_path; + off_t func_off; +@@ -165,7 +166,11 @@ int main(int argc, char **argv) + return 1; + } + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ goto cleanup; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = bashreadline_bpf__open_and_load(); +@@ -182,16 +187,17 @@ int main(int argc, char **argv) + + obj->links.printret = bpf_program__attach_uprobe(obj->progs.printret, true, -1, + readline_so_path, func_off); +- if (!obj->links.printret) { +- err = -errno; ++ err = libbpf_get_error(obj->links.printret); ++ if (err) { + warn("failed to attach readline: %d\n", err); + goto cleanup; + } + +- pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; ++ pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -205,8 +211,8 @@ int main(int argc, char **argv) + printf("%-9s %-7s %s\n", "TIME", "PID", "COMMAND"); + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- warn("error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ warn("error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + err = 0; +diff --git a/libbpf-tools/bindsnoop.c b/libbpf-tools/bindsnoop.c +index 5d87d484..c75b57e0 100644 +--- a/libbpf-tools/bindsnoop.c ++++ b/libbpf-tools/bindsnoop.c +@@ -174,6 +174,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct bindsnoop_bpf *obj; + int err, port_map_fd; +@@ -184,7 +185,11 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = bindsnoop_bpf__open(); +@@ -219,10 +224,12 @@ int main(int argc, char **argv) + goto cleanup; + } + +- pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; ++ pb = perf_buffer__new(bpf_map__fd(obj->maps.events), ++ PERF_BUFFER_PAGES, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -240,8 +247,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- warn("error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ warn("error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/biolatency.c b/libbpf-tools/biolatency.c +index 51afa509..f2cf5ffd 100644 +--- a/libbpf-tools/biolatency.c ++++ b/libbpf-tools/biolatency.c +@@ -255,9 +255,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = biolatency_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -308,22 +313,25 @@ int main(int argc, char **argv) + } + + if (env.queued) { +- obj->links.block_rq_insert = bpf_program__attach(obj->progs.block_rq_insert); +- if (!obj->links.block_rq_insert) { +- err = -errno; ++ obj->links.block_rq_insert = ++ bpf_program__attach(obj->progs.block_rq_insert); ++ err = libbpf_get_error(obj->links.block_rq_insert); ++ if (err) { + fprintf(stderr, "failed to attach: %s\n", strerror(-err)); + goto cleanup; + } + } +- obj->links.block_rq_issue = bpf_program__attach(obj->progs.block_rq_issue); +- if (!obj->links.block_rq_issue) { +- err = -errno; ++ obj->links.block_rq_issue = ++ bpf_program__attach(obj->progs.block_rq_issue); ++ err = libbpf_get_error(obj->links.block_rq_issue); ++ if (err) { + fprintf(stderr, "failed to attach: %s\n", strerror(-err)); + goto cleanup; + } +- obj->links.block_rq_complete = bpf_program__attach(obj->progs.block_rq_complete); +- if (!obj->links.block_rq_complete) { +- err = -errno; ++ obj->links.block_rq_complete = ++ bpf_program__attach(obj->progs.block_rq_complete); ++ err = libbpf_get_error(obj->links.block_rq_complete); ++ if (err) { + fprintf(stderr, "failed to attach: %s\n", strerror(-err)); + goto cleanup; + } +diff --git a/libbpf-tools/biopattern.c b/libbpf-tools/biopattern.c +index 92324702..2cc0d9a3 100644 +--- a/libbpf-tools/biopattern.c ++++ b/libbpf-tools/biopattern.c +@@ -172,9 +172,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = biopattern_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/biosnoop.c b/libbpf-tools/biosnoop.c +index f0f665a6..618af38e 100644 +--- a/libbpf-tools/biosnoop.c ++++ b/libbpf-tools/biosnoop.c +@@ -190,6 +190,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct ksyms *ksyms = NULL; + struct biosnoop_bpf *obj; +@@ -202,9 +203,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = biosnoop_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -251,55 +257,64 @@ int main(int argc, char **argv) + } + } + +- obj->links.blk_account_io_start = bpf_program__attach(obj->progs.blk_account_io_start); +- if (!obj->links.blk_account_io_start) { +- err = -errno; ++ obj->links.blk_account_io_start = ++ bpf_program__attach(obj->progs.blk_account_io_start); ++ err = libbpf_get_error(obj->links.blk_account_io_start); ++ if (err) { + fprintf(stderr, "failed to attach blk_account_io_start: %s\n", +- strerror(-err)); ++ strerror(err)); + goto cleanup; + } + ksyms = ksyms__load(); + if (!ksyms) { +- err = -ENOMEM; + fprintf(stderr, "failed to load kallsyms\n"); + goto cleanup; + } + if (ksyms__get_symbol(ksyms, "blk_account_io_merge_bio")) { + obj->links.blk_account_io_merge_bio = + bpf_program__attach(obj->progs.blk_account_io_merge_bio); +- if (!obj->links.blk_account_io_merge_bio) { +- err = -errno; +- fprintf(stderr, "failed to attach blk_account_io_merge_bio: %s\n", +- strerror(-err)); ++ err = libbpf_get_error(obj->links.blk_account_io_merge_bio); ++ if (err) { ++ fprintf(stderr, "failed to attach " ++ "blk_account_io_merge_bio: %s\n", ++ strerror(err)); + goto cleanup; + } + } + if (env.queued) { + obj->links.block_rq_insert = + bpf_program__attach(obj->progs.block_rq_insert); +- if (!obj->links.block_rq_insert) { +- err = -errno; +- fprintf(stderr, "failed to attach block_rq_insert: %s\n", strerror(-err)); ++ err = libbpf_get_error(obj->links.block_rq_insert); ++ if (err) { ++ fprintf(stderr, "failed to attach block_rq_insert: %s\n", ++ strerror(err)); + goto cleanup; + } + } +- obj->links.block_rq_issue = bpf_program__attach(obj->progs.block_rq_issue); +- if (!obj->links.block_rq_issue) { +- err = -errno; +- fprintf(stderr, "failed to attach block_rq_issue: %s\n", strerror(-err)); ++ obj->links.block_rq_issue = ++ bpf_program__attach(obj->progs.block_rq_issue); ++ err = libbpf_get_error(obj->links.block_rq_issue); ++ if (err) { ++ fprintf(stderr, "failed to attach block_rq_issue: %s\n", ++ strerror(err)); + goto cleanup; + } +- obj->links.block_rq_complete = bpf_program__attach(obj->progs.block_rq_complete); +- if (!obj->links.block_rq_complete) { +- err = -errno; +- fprintf(stderr, "failed to attach block_rq_complete: %s\n", strerror(-err)); ++ obj->links.block_rq_complete = ++ bpf_program__attach(obj->progs.block_rq_complete); ++ err = libbpf_get_error(obj->links.block_rq_complete); ++ if (err) { ++ fprintf(stderr, "failed to attach block_rq_complete: %s\n", ++ strerror(err)); + goto cleanup; + } + ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + fprintf(stderr, "failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -323,8 +338,8 @@ int main(int argc, char **argv) + /* main: poll */ + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + if (env.duration && get_ktime_ns() > time_end) +diff --git a/libbpf-tools/biostacks.c b/libbpf-tools/biostacks.c +index 260bc235..c98fd532 100644 +--- a/libbpf-tools/biostacks.c ++++ b/libbpf-tools/biostacks.c +@@ -145,9 +145,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = biostacks_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -179,10 +184,12 @@ int main(int argc, char **argv) + goto cleanup; + } + +- obj->links.blk_account_io_start = bpf_program__attach(obj->progs.blk_account_io_start); +- if (!obj->links.blk_account_io_start) { +- err = -errno; +- fprintf(stderr, "failed to attach blk_account_io_start: %s\n", strerror(-err)); ++ obj->links.blk_account_io_start = ++ bpf_program__attach(obj->progs.blk_account_io_start); ++ err = libbpf_get_error(obj->links.blk_account_io_start); ++ if (err) { ++ fprintf(stderr, "failed to attach blk_account_io_start: %s\n", ++ strerror(err)); + goto cleanup; + } + ksyms = ksyms__load(); +@@ -192,19 +199,23 @@ int main(int argc, char **argv) + } + if (ksyms__get_symbol(ksyms, "blk_account_io_merge_bio")) { + obj->links.blk_account_io_merge_bio = +- bpf_program__attach(obj->progs.blk_account_io_merge_bio); +- if (!obj->links.blk_account_io_merge_bio) { +- err = -errno; +- fprintf(stderr, "failed to attach blk_account_io_merge_bio: %s\n", +- strerror(-err)); ++ bpf_program__attach(obj-> ++ progs.blk_account_io_merge_bio); ++ err = libbpf_get_error(obj-> ++ links.blk_account_io_merge_bio); ++ if (err) { ++ fprintf(stderr, "failed to attach " ++ "blk_account_io_merge_bio: %s\n", ++ strerror(err)); + goto cleanup; + } + } +- obj->links.blk_account_io_done = bpf_program__attach(obj->progs.blk_account_io_done); +- if (!obj->links.blk_account_io_done) { +- err = -errno; ++ obj->links.blk_account_io_done = ++ bpf_program__attach(obj->progs.blk_account_io_done); ++ err = libbpf_get_error(obj->links.blk_account_io_done); ++ if (err) { + fprintf(stderr, "failed to attach blk_account_io_done: %s\n", +- strerror(-err)); ++ strerror(err)); + goto cleanup; + } + +diff --git a/libbpf-tools/bitesize.c b/libbpf-tools/bitesize.c +index 4c371508..41b1a7db 100644 +--- a/libbpf-tools/bitesize.c ++++ b/libbpf-tools/bitesize.c +@@ -167,9 +167,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = bitesize_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/cachestat.c b/libbpf-tools/cachestat.c +index 05785251..abc81878 100644 +--- a/libbpf-tools/cachestat.c ++++ b/libbpf-tools/cachestat.c +@@ -139,9 +139,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = cachestat_bpf__open_and_load(); + if (!obj) { + fprintf(stderr, "failed to open and/or load BPF object\n"); +diff --git a/libbpf-tools/cpudist.c b/libbpf-tools/cpudist.c +index f76d8a67..035100ea 100644 +--- a/libbpf-tools/cpudist.c ++++ b/libbpf-tools/cpudist.c +@@ -197,9 +197,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = cpudist_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/cpufreq.bpf.c b/libbpf-tools/cpufreq.bpf.c +index 88a1bd25..697620ba 100644 +--- a/libbpf-tools/cpufreq.bpf.c ++++ b/libbpf-tools/cpufreq.bpf.c +@@ -17,21 +17,11 @@ struct { + __type(value, struct hist); + } hists SEC(".maps"); + +-#define clamp_umax(VAR, UMAX) \ +- asm volatile ( \ +- "if %0 <= %[max] goto +1\n" \ +- "%0 = %[max]\n" \ +- : "+r"(VAR) \ +- : [max]"i"(UMAX) \ +- ) +- + SEC("tp_btf/cpu_frequency") + int BPF_PROG(cpu_frequency, unsigned int state, unsigned int cpu_id) + { + if (cpu_id >= MAX_CPU_NR) + return 0; +- +- clamp_umax(cpu_id, MAX_CPU_NR - 1); + freqs_mhz[cpu_id] = state / 1000; + return 0; + } +@@ -46,7 +36,6 @@ int do_sample(struct bpf_perf_event_data *ctx) + + if (cpu >= MAX_CPU_NR) + return 0; +- clamp_umax(cpu, MAX_CPU_NR - 1); + freq_mhz = freqs_mhz[cpu]; + if (!freq_mhz) + return 0; +diff --git a/libbpf-tools/cpufreq.c b/libbpf-tools/cpufreq.c +index c5839560..65876587 100644 +--- a/libbpf-tools/cpufreq.c ++++ b/libbpf-tools/cpufreq.c +@@ -102,8 +102,10 @@ static int open_and_attach_perf_event(int freq, struct bpf_program *prog, + return -1; + } + links[i] = bpf_program__attach_perf_event(prog, fd); +- if (!links[i]) { +- fprintf(stderr, "failed to attach perf event on cpu: %d\n", i); ++ if (libbpf_get_error(links[i])) { ++ fprintf(stderr, "failed to attach perf event on cpu: " ++ "%d\n", i); ++ links[i] = NULL; + close(fd); + return -1; + } +@@ -173,7 +175,7 @@ static void print_linear_hists(struct bpf_map *hists, + + printf("\n"); + print_linear_hist(bss->syswide.slots, MAX_SLOTS, 0, HIST_STEP_SIZE, +- "syswide"); ++ "syswide"); + } + + int main(int argc, char **argv) +@@ -191,9 +193,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + nr_cpus = libbpf_num_possible_cpus(); + if (nr_cpus < 0) { + fprintf(stderr, "failed to get # of possible cpus: '%s'!\n", +diff --git a/libbpf-tools/drsnoop.c b/libbpf-tools/drsnoop.c +index 705db9a4..89285871 100644 +--- a/libbpf-tools/drsnoop.c ++++ b/libbpf-tools/drsnoop.c +@@ -146,6 +146,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct ksyms *ksyms = NULL; + const struct ksym *ksym; +@@ -157,9 +158,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = drsnoop_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -207,10 +213,13 @@ int main(int argc, char **argv) + printf(" %8s", "FREE(KB)"); + printf("\n"); + ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + fprintf(stderr, "failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -228,8 +237,8 @@ int main(int argc, char **argv) + /* main: poll */ + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + if (env.duration && get_ktime_ns() > time_end) +diff --git a/libbpf-tools/execsnoop.c b/libbpf-tools/execsnoop.c +index 38294816..1fd573da 100644 +--- a/libbpf-tools/execsnoop.c ++++ b/libbpf-tools/execsnoop.c +@@ -263,6 +263,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct execsnoop_bpf *obj; + int err; +@@ -271,9 +272,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = execsnoop_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -311,10 +317,12 @@ int main(int argc, char **argv) + printf("%-16s %-6s %-6s %3s %s\n", "PCOMM", "PID", "PPID", "RET", "ARGS"); + + /* setup event callbacks */ +- pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; ++ pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + fprintf(stderr, "failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -328,8 +336,8 @@ int main(int argc, char **argv) + /* main: poll */ + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/exitsnoop.c b/libbpf-tools/exitsnoop.c +index bca9d4d3..410e00da 100644 +--- a/libbpf-tools/exitsnoop.c ++++ b/libbpf-tools/exitsnoop.c +@@ -152,6 +152,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct exitsnoop_bpf *obj; + int err; +@@ -160,7 +161,11 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = exitsnoop_bpf__open(); +@@ -185,10 +190,11 @@ int main(int argc, char **argv) + goto cleanup; + } + +- pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; ++ pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -206,8 +212,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- warn("error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ warn("error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/filelife.c b/libbpf-tools/filelife.c +index ba6b9440..1f94039e 100644 +--- a/libbpf-tools/filelife.c ++++ b/libbpf-tools/filelife.c +@@ -110,6 +110,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct filelife_bpf *obj; + int err; +@@ -118,9 +119,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = filelife_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -145,10 +151,13 @@ int main(int argc, char **argv) + printf("Tracing the lifespan of short-lived files ... Hit Ctrl-C to end.\n"); + printf("%-8s %-6s %-16s %-7s %s\n", "TIME", "PID", "COMM", "AGE(s)", "FILE"); + ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + fprintf(stderr, "failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -161,8 +170,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/filetop.c b/libbpf-tools/filetop.c +index 70240d85..f1f7ba96 100644 +--- a/libbpf-tools/filetop.c ++++ b/libbpf-tools/filetop.c +@@ -268,7 +268,11 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = filetop_bpf__open(); +diff --git a/libbpf-tools/fsdist.c b/libbpf-tools/fsdist.c +index f411d162..782a0e6a 100644 +--- a/libbpf-tools/fsdist.c ++++ b/libbpf-tools/fsdist.c +@@ -299,44 +299,53 @@ static int attach_kprobes(struct fsdist_bpf *obj) + + /* READ */ + obj->links.file_read_entry = bpf_program__attach_kprobe(obj->progs.file_read_entry, false, cfg->op_funcs[READ]); +- if (!obj->links.file_read_entry) ++ err = libbpf_get_error(obj->links.file_read_entry); ++ if (err) + goto errout; + obj->links.file_read_exit = bpf_program__attach_kprobe(obj->progs.file_read_exit, true, cfg->op_funcs[READ]); +- if (!obj->links.file_read_exit) ++ err = libbpf_get_error(obj->links.file_read_exit); ++ if (err) + goto errout; + /* WRITE */ + obj->links.file_write_entry = bpf_program__attach_kprobe(obj->progs.file_write_entry, false, cfg->op_funcs[WRITE]); +- if (!obj->links.file_write_entry) ++ err = libbpf_get_error(obj->links.file_write_entry); ++ if (err) + goto errout; + obj->links.file_write_exit = bpf_program__attach_kprobe(obj->progs.file_write_exit, true, cfg->op_funcs[WRITE]); +- if (!obj->links.file_write_exit) ++ err = libbpf_get_error(obj->links.file_write_exit); ++ if (err) + goto errout; + /* OPEN */ + obj->links.file_open_entry = bpf_program__attach_kprobe(obj->progs.file_open_entry, false, cfg->op_funcs[OPEN]); +- if (!obj->links.file_open_entry) ++ err = libbpf_get_error(obj->links.file_open_entry); ++ if (err) + goto errout; + obj->links.file_open_exit = bpf_program__attach_kprobe(obj->progs.file_open_exit, true, cfg->op_funcs[OPEN]); +- if (!obj->links.file_open_exit) ++ err = libbpf_get_error(obj->links.file_open_exit); ++ if (err) + goto errout; + /* FSYNC */ + obj->links.file_sync_entry = bpf_program__attach_kprobe(obj->progs.file_sync_entry, false, cfg->op_funcs[FSYNC]); +- if (!obj->links.file_sync_entry) ++ err = libbpf_get_error(obj->links.file_sync_entry); ++ if (err) + goto errout; + obj->links.file_sync_exit = bpf_program__attach_kprobe(obj->progs.file_sync_exit, true, cfg->op_funcs[FSYNC]); +- if (!obj->links.file_sync_exit) ++ err = libbpf_get_error(obj->links.file_sync_exit); ++ if (err) + goto errout; + /* GETATTR */ + if (!cfg->op_funcs[GETATTR]) + return 0; + obj->links.getattr_entry = bpf_program__attach_kprobe(obj->progs.getattr_entry, false, cfg->op_funcs[GETATTR]); +- if (!obj->links.getattr_entry) ++ err = libbpf_get_error(obj->links.getattr_entry); ++ if (err) + goto errout; + obj->links.getattr_exit = bpf_program__attach_kprobe(obj->progs.getattr_exit, true, cfg->op_funcs[GETATTR]); +- if (!obj->links.getattr_exit) ++ err = libbpf_get_error(obj->links.getattr_exit); ++ if (err) + goto errout; + return 0; + errout: +- err = -errno; + warn("failed to attach kprobe: %ld\n", err); + return err; + } +@@ -364,9 +373,14 @@ int main(int argc, char **argv) + return 1; + } + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + skel = fsdist_bpf__open(); + if (!skel) { + warn("failed to open BPF object\n"); +diff --git a/libbpf-tools/fsslower.c b/libbpf-tools/fsslower.c +index e96c9efa..2975b493 100644 +--- a/libbpf-tools/fsslower.c ++++ b/libbpf-tools/fsslower.c +@@ -256,36 +256,43 @@ static int attach_kprobes(struct fsslower_bpf *obj) + + /* READ */ + obj->links.file_read_entry = bpf_program__attach_kprobe(obj->progs.file_read_entry, false, cfg->op_funcs[READ]); +- if (!obj->links.file_read_entry) ++ err = libbpf_get_error(obj->links.file_read_entry); ++ if (err) + goto errout; + obj->links.file_read_exit = bpf_program__attach_kprobe(obj->progs.file_read_exit, true, cfg->op_funcs[READ]); +- if (!obj->links.file_read_exit) ++ err = libbpf_get_error(obj->links.file_read_exit); ++ if (err) + goto errout; + /* WRITE */ + obj->links.file_write_entry = bpf_program__attach_kprobe(obj->progs.file_write_entry, false, cfg->op_funcs[WRITE]); +- if (!obj->links.file_write_entry) ++ err = libbpf_get_error(obj->links.file_write_entry); ++ if (err) + goto errout; + obj->links.file_write_exit = bpf_program__attach_kprobe(obj->progs.file_write_exit, true, cfg->op_funcs[WRITE]); +- if (!obj->links.file_write_exit) ++ err = libbpf_get_error(obj->links.file_write_exit); ++ if (err) + goto errout; + /* OPEN */ + obj->links.file_open_entry = bpf_program__attach_kprobe(obj->progs.file_open_entry, false, cfg->op_funcs[OPEN]); +- if (!obj->links.file_open_entry) ++ err = libbpf_get_error(obj->links.file_open_entry); ++ if (err) + goto errout; + obj->links.file_open_exit = bpf_program__attach_kprobe(obj->progs.file_open_exit, true, cfg->op_funcs[OPEN]); +- if (!obj->links.file_open_exit) ++ err = libbpf_get_error(obj->links.file_open_exit); ++ if (err) + goto errout; + /* FSYNC */ + obj->links.file_sync_entry = bpf_program__attach_kprobe(obj->progs.file_sync_entry, false, cfg->op_funcs[FSYNC]); +- if (!obj->links.file_sync_entry) ++ err = libbpf_get_error(obj->links.file_sync_entry); ++ if (err) + goto errout; + obj->links.file_sync_exit = bpf_program__attach_kprobe(obj->progs.file_sync_exit, true, cfg->op_funcs[FSYNC]); +- if (!obj->links.file_sync_exit) ++ err = libbpf_get_error(obj->links.file_sync_exit); ++ if (err) + goto errout; + return 0; + + errout: +- err = -errno; + warn("failed to attach kprobe: %ld\n", err); + return err; + } +@@ -354,6 +361,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct fsslower_bpf *skel; + __u64 time_end = 0; +@@ -369,9 +377,14 @@ int main(int argc, char **argv) + return 1; + } + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + skel = fsslower_bpf__open(); + if (!skel) { + warn("failed to open BPF object\n"); +@@ -415,10 +428,13 @@ int main(int argc, char **argv) + goto cleanup; + } + ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(skel->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -437,8 +453,8 @@ int main(int argc, char **argv) + /* main: poll */ + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + if (duration && get_ktime_ns() > time_end) +diff --git a/libbpf-tools/funclatency.c b/libbpf-tools/funclatency.c +index 3ea0fec3..b079292e 100644 +--- a/libbpf-tools/funclatency.c ++++ b/libbpf-tools/funclatency.c +@@ -185,18 +185,20 @@ static int attach_kprobes(struct funclatency_bpf *obj) + { + long err; + +- obj->links.dummy_kprobe = bpf_program__attach_kprobe(obj->progs.dummy_kprobe, false, +- env.funcname); +- if (!obj->links.dummy_kprobe) { +- err = -errno; ++ obj->links.dummy_kprobe = ++ bpf_program__attach_kprobe(obj->progs.dummy_kprobe, false, ++ env.funcname); ++ err = libbpf_get_error(obj->links.dummy_kprobe); ++ if (err) { + warn("failed to attach kprobe: %ld\n", err); + return -1; + } + +- obj->links.dummy_kretprobe = bpf_program__attach_kprobe(obj->progs.dummy_kretprobe, true, +- env.funcname); +- if (!obj->links.dummy_kretprobe) { +- err = -errno; ++ obj->links.dummy_kretprobe = ++ bpf_program__attach_kprobe(obj->progs.dummy_kretprobe, true, ++ env.funcname); ++ err = libbpf_get_error(obj->links.dummy_kretprobe); ++ if (err) { + warn("failed to attach kretprobe: %ld\n", err); + return -1; + } +@@ -237,8 +239,8 @@ static int attach_uprobes(struct funclatency_bpf *obj) + obj->links.dummy_kprobe = + bpf_program__attach_uprobe(obj->progs.dummy_kprobe, false, + env.pid ?: -1, bin_path, func_off); +- if (!obj->links.dummy_kprobe) { +- err = -errno; ++ err = libbpf_get_error(obj->links.dummy_kprobe); ++ if (err) { + warn("Failed to attach uprobe: %ld\n", err); + goto out_binary; + } +@@ -246,8 +248,8 @@ static int attach_uprobes(struct funclatency_bpf *obj) + obj->links.dummy_kretprobe = + bpf_program__attach_uprobe(obj->progs.dummy_kretprobe, true, + env.pid ?: -1, bin_path, func_off); +- if (!obj->links.dummy_kretprobe) { +- err = -errno; ++ err = libbpf_get_error(obj->links.dummy_kretprobe); ++ if (err) { + warn("Failed to attach uretprobe: %ld\n", err); + goto out_binary; + } +@@ -296,7 +298,11 @@ int main(int argc, char **argv) + + sigaction(SIGINT, &sigact, 0); + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = funclatency_bpf__open(); +diff --git a/libbpf-tools/gethostlatency.c b/libbpf-tools/gethostlatency.c +index 9b3ebc28..12076e6a 100644 +--- a/libbpf-tools/gethostlatency.c ++++ b/libbpf-tools/gethostlatency.c +@@ -164,14 +164,16 @@ static int attach_uprobes(struct gethostlatency_bpf *obj, struct bpf_link *links + } + links[0] = bpf_program__attach_uprobe(obj->progs.handle_entry, false, + target_pid ?: -1, libc_path, func_off); +- if (!links[0]) { +- warn("failed to attach getaddrinfo: %d\n", -errno); ++ err = libbpf_get_error(links[0]); ++ if (err) { ++ warn("failed to attach getaddrinfo: %d\n", err); + return -1; + } + links[1] = bpf_program__attach_uprobe(obj->progs.handle_return, true, + target_pid ?: -1, libc_path, func_off); +- if (!links[1]) { +- warn("failed to attach getaddrinfo: %d\n", -errno); ++ err = libbpf_get_error(links[1]); ++ if (err) { ++ warn("failed to attach getaddrinfo: %d\n", err); + return -1; + } + +@@ -182,14 +184,16 @@ static int attach_uprobes(struct gethostlatency_bpf *obj, struct bpf_link *links + } + links[2] = bpf_program__attach_uprobe(obj->progs.handle_entry, false, + target_pid ?: -1, libc_path, func_off); +- if (!links[2]) { +- warn("failed to attach gethostbyname: %d\n", -errno); ++ err = libbpf_get_error(links[2]); ++ if (err) { ++ warn("failed to attach gethostbyname: %d\n", err); + return -1; + } + links[3] = bpf_program__attach_uprobe(obj->progs.handle_return, true, + target_pid ?: -1, libc_path, func_off); +- if (!links[3]) { +- warn("failed to attach gethostbyname: %d\n", -errno); ++ err = libbpf_get_error(links[3]); ++ if (err) { ++ warn("failed to attach gethostbyname: %d\n", err); + return -1; + } + +@@ -200,14 +204,16 @@ static int attach_uprobes(struct gethostlatency_bpf *obj, struct bpf_link *links + } + links[4] = bpf_program__attach_uprobe(obj->progs.handle_entry, false, + target_pid ?: -1, libc_path, func_off); +- if (!links[4]) { +- warn("failed to attach gethostbyname2: %d\n", -errno); ++ err = libbpf_get_error(links[4]); ++ if (err) { ++ warn("failed to attach gethostbyname2: %d\n", err); + return -1; + } + links[5] = bpf_program__attach_uprobe(obj->progs.handle_return, true, + target_pid ?: -1, libc_path, func_off); +- if (!links[5]) { +- warn("failed to attach gethostbyname2: %d\n", -errno); ++ err = libbpf_get_error(links[5]); ++ if (err) { ++ warn("failed to attach gethostbyname2: %d\n", err); + return -1; + } + +@@ -221,6 +227,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct bpf_link *links[6] = {}; + struct gethostlatency_bpf *obj; +@@ -230,7 +237,11 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = gethostlatency_bpf__open(); +@@ -251,10 +262,12 @@ int main(int argc, char **argv) + if (err) + goto cleanup; + ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -270,8 +283,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- warn("error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ warn("error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/hardirqs.c b/libbpf-tools/hardirqs.c +index a2475ef1..759b3949 100644 +--- a/libbpf-tools/hardirqs.c ++++ b/libbpf-tools/hardirqs.c +@@ -185,9 +185,14 @@ int main(int argc, char **argv) + return 1; + } + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = hardirqs_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -207,27 +212,30 @@ 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; ++ obj->links.handle__irq_handler = ++ bpf_program__attach(obj->progs.handle__irq_handler); ++ err = libbpf_get_error(obj->links.handle__irq_handler); ++ if (err) { + fprintf(stderr, + "failed to attach irq/irq_handler_entry: %s\n", +- strerror(-err)); ++ strerror(err)); + } + } else { +- obj->links.irq_handler_entry = bpf_program__attach(obj->progs.irq_handler_entry); +- if (!obj->links.irq_handler_entry) { +- err = -errno; ++ obj->links.irq_handler_entry = ++ bpf_program__attach(obj->progs.irq_handler_entry); ++ err = libbpf_get_error(obj->links.irq_handler_entry); ++ if (err) { + fprintf(stderr, + "failed to attach irq_handler_entry: %s\n", +- strerror(-err)); ++ 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; ++ obj->links.irq_handler_exit_exit = ++ bpf_program__attach(obj->progs.irq_handler_exit_exit); ++ err = libbpf_get_error(obj->links.irq_handler_exit_exit); ++ if (err) { + fprintf(stderr, + "failed to attach irq_handler_exit: %s\n", +- strerror(-err)); ++ strerror(err)); + } + } + +diff --git a/libbpf-tools/ksnoop.c b/libbpf-tools/ksnoop.c +index a6ea6107..a5f59a0f 100644 +--- a/libbpf-tools/ksnoop.c ++++ b/libbpf-tools/ksnoop.c +@@ -38,6 +38,7 @@ static bool verbose = false; + static __u32 filter_pid; + static bool stack_mode; + ++#define libbpf_errstr(val) strerror(-libbpf_get_error(val)) + + static void __p(enum log_level level, char *level_str, char *fmt, ...) + { +@@ -222,12 +223,14 @@ static int get_func_btf(struct btf *btf, struct func *func) + return -ENOENT; + } + type = btf__type_by_id(btf, func->id); +- if (!type || BTF_INFO_KIND(type->info) != BTF_KIND_FUNC) { ++ if (libbpf_get_error(type) || ++ BTF_INFO_KIND(type->info) != BTF_KIND_FUNC) { + p_err("Error looking up function type via id '%d'", func->id); + return -EINVAL; + } + type = btf__type_by_id(btf, type->type); +- if (!type || BTF_INFO_KIND(type->info) != BTF_KIND_FUNC_PROTO) { ++ if (libbpf_get_error(type) || ++ BTF_INFO_KIND(type->info) != BTF_KIND_FUNC_PROTO) { + p_err("Error looking up function proto type via id '%d'", + func->id); + return -EINVAL; +@@ -341,16 +344,15 @@ static int trace_to_value(struct btf *btf, struct func *func, char *argname, + static struct btf *get_btf(const char *name) + { + struct btf *mod_btf; +- int err; + + p_debug("getting BTF for %s", + name && strlen(name) > 0 ? name : "vmlinux"); + + if (!vmlinux_btf) { + vmlinux_btf = btf__load_vmlinux_btf(); +- if (!vmlinux_btf) { +- err = -errno; +- p_err("No BTF, cannot determine type info: %s", strerror(-err)); ++ if (libbpf_get_error(vmlinux_btf)) { ++ p_err("No BTF, cannot determine type info: %s", ++ libbpf_errstr(vmlinux_btf)); + return NULL; + } + } +@@ -358,9 +360,9 @@ static struct btf *get_btf(const char *name) + return vmlinux_btf; + + mod_btf = btf__load_module_btf(name, vmlinux_btf); +- if (!mod_btf) { +- err = -errno; +- p_err("No BTF for module '%s': %s", name, strerror(-err)); ++ if (libbpf_get_error(mod_btf)) { ++ p_err("No BTF for module '%s': %s", ++ name, libbpf_errstr(mod_btf)); + return NULL; + } + return mod_btf; +@@ -394,11 +396,11 @@ static char *type_id_to_str(struct btf *btf, __s32 type_id, char *str) + default: + do { + type = btf__type_by_id(btf, type_id); +- if (!type) { ++ ++ if (libbpf_get_error(type)) { + name = "?"; + break; + } +- + switch (BTF_INFO_KIND(type->info)) { + case BTF_KIND_CONST: + case BTF_KIND_VOLATILE: +@@ -553,17 +555,16 @@ static int parse_trace(char *str, struct trace *trace) + return ret; + } + trace->btf = get_btf(func->mod); +- if (!trace->btf) { +- ret = -errno; ++ if (libbpf_get_error(trace->btf)) { + p_err("could not get BTF for '%s': %s", + strlen(func->mod) ? func->mod : "vmlinux", +- strerror(-ret)); ++ libbpf_errstr(trace->btf)); + return -ENOENT; + } + trace->dump = btf_dump__new(trace->btf, NULL, &opts, trace_printf); +- if (!trace->dump) { +- ret = -errno; +- p_err("could not create BTF dump : %n", strerror(-ret)); ++ if (libbpf_get_error(trace->dump)) { ++ p_err("could not create BTF dump : %n", ++ libbpf_errstr(trace->btf)); + return -EINVAL; + } + +@@ -823,20 +824,20 @@ static int attach_traces(struct ksnoop_bpf *skel, struct trace *traces, + bpf_program__attach_kprobe(skel->progs.kprobe_entry, + false, + traces[i].func.name); +- if (!traces[i].links[0]) { +- ret = -errno; ++ ret = libbpf_get_error(traces[i].links[0]); ++ if (ret) { + p_err("Could not attach kprobe to '%s': %s", + traces[i].func.name, strerror(-ret)); + return ret; +- } ++ } + p_debug("Attached kprobe for '%s'", traces[i].func.name); + + traces[i].links[1] = + bpf_program__attach_kprobe(skel->progs.kprobe_return, + true, + traces[i].func.name); +- if (!traces[i].links[1]) { +- ret = -errno; ++ ret = libbpf_get_error(traces[i].links[1]); ++ if (ret) { + p_err("Could not attach kretprobe to '%s': %s", + traces[i].func.name, strerror(-ret)); + return ret; +@@ -848,6 +849,7 @@ static int attach_traces(struct ksnoop_bpf *skel, struct trace *traces, + + static int cmd_trace(int argc, char **argv) + { ++ struct perf_buffer_opts pb_opts = {}; + struct bpf_map *perf_map, *func_map; + struct perf_buffer *pb = NULL; + struct ksnoop_bpf *skel; +@@ -860,8 +862,7 @@ static int cmd_trace(int argc, char **argv) + + skel = ksnoop_bpf__open_and_load(); + if (!skel) { +- ret = -errno; +- p_err("Could not load ksnoop BPF: %s", strerror(-ret)); ++ p_err("Could not load ksnoop BPF: %s", libbpf_errstr(skel)); + return 1; + } + +@@ -886,11 +887,12 @@ static int cmd_trace(int argc, char **argv) + goto cleanup; + } + +- pb = perf_buffer__new(bpf_map__fd(perf_map), pages, +- trace_handler, lost_handler, NULL, NULL); +- if (!pb) { +- ret = -errno; +- p_err("Could not create perf buffer: %s", strerror(-ret)); ++ pb_opts.sample_cb = trace_handler; ++ pb_opts.lost_cb = lost_handler; ++ pb = perf_buffer__new(bpf_map__fd(perf_map), pages, &pb_opts); ++ if (libbpf_get_error(pb)) { ++ p_err("Could not create perf buffer: %s", ++ libbpf_errstr(pb)); + goto cleanup; + } + +@@ -904,8 +906,8 @@ static int cmd_trace(int argc, char **argv) + + while (!exiting) { + ret = perf_buffer__poll(pb, 1); +- if (ret < 0 && ret != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-ret)); ++ if (ret < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset ret to return 0 if exiting */ +@@ -1005,7 +1007,6 @@ int main(int argc, char *argv[]) + if (argc < 0) + usage(); + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + + return cmd_select(argc, argv); +diff --git a/libbpf-tools/llcstat.bpf.c b/libbpf-tools/llcstat.bpf.c +index a36fc2df..fbd5b6c4 100644 +--- a/libbpf-tools/llcstat.bpf.c ++++ b/libbpf-tools/llcstat.bpf.c +@@ -36,13 +36,13 @@ int trace_event(__u64 sample_period, bool miss) + return 0; + } + +-SEC("perf_event") ++SEC("perf_event/1") + int on_cache_miss(struct bpf_perf_event_data *ctx) + { + return trace_event(ctx->sample_period, true); + } + +-SEC("perf_event") ++SEC("perf_event/2") + int on_cache_ref(struct bpf_perf_event_data *ctx) + { + return trace_event(ctx->sample_period, false); +diff --git a/libbpf-tools/llcstat.c b/libbpf-tools/llcstat.c +index be437bc2..150dd38b 100644 +--- a/libbpf-tools/llcstat.c ++++ b/libbpf-tools/llcstat.c +@@ -106,8 +106,10 @@ static int open_and_attach_perf_event(__u64 config, int period, + return -1; + } + links[i] = bpf_program__attach_perf_event(prog, fd); +- if (!links[i]) { +- fprintf(stderr, "failed to attach perf event on cpu: %d\n", i); ++ if (libbpf_get_error(links[i])) { ++ fprintf(stderr, "failed to attach perf event on cpu: " ++ "%d\n", i); ++ links[i] = NULL; + close(fd); + return -1; + } +@@ -182,9 +184,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + nr_cpus = libbpf_num_possible_cpus(); + if (nr_cpus < 0) { + fprintf(stderr, "failed to get # of possible cpus: '%s'!\n", +diff --git a/libbpf-tools/mountsnoop.c b/libbpf-tools/mountsnoop.c +index ac2acc45..0955f59e 100644 +--- a/libbpf-tools/mountsnoop.c ++++ b/libbpf-tools/mountsnoop.c +@@ -249,6 +249,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct mountsnoop_bpf *obj; + int err; +@@ -257,7 +258,11 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = mountsnoop_bpf__open(); +@@ -280,10 +285,11 @@ int main(int argc, char **argv) + goto cleanup; + } + +- pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; ++ pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -302,8 +308,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/numamove.c b/libbpf-tools/numamove.c +index 0747f841..66a53ed6 100644 +--- a/libbpf-tools/numamove.c ++++ b/libbpf-tools/numamove.c +@@ -80,9 +80,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = numamove_bpf__open_and_load(); + if (!obj) { + fprintf(stderr, "failed to open and/or load BPF object\n"); +@@ -102,15 +107,18 @@ int main(int argc, char **argv) + + signal(SIGINT, sig_handler); + +- printf("%-10s %18s %18s\n", "TIME", "NUMA_migrations", "NUMA_migrations_ms"); ++ printf("%-10s %18s %18s\n", "TIME", "NUMA_migrations", ++ "NUMA_migrations_ms"); + while (!exiting) { + sleep(1); + time(&t); + tm = localtime(&t); + strftime(ts, sizeof(ts), "%H:%M:%S", tm); + printf("%-10s %18lld %18lld\n", ts, +- __atomic_exchange_n(&obj->bss->num, 0, __ATOMIC_RELAXED), +- __atomic_exchange_n(&obj->bss->latency, 0, __ATOMIC_RELAXED)); ++ __atomic_exchange_n(&obj->bss->num, 0, ++ __ATOMIC_RELAXED), ++ __atomic_exchange_n(&obj->bss->latency, 0, ++ __ATOMIC_RELAXED)); + } + + cleanup: +diff --git a/libbpf-tools/offcputime.c b/libbpf-tools/offcputime.c +index 37a8ec2c..0582b158 100644 +--- a/libbpf-tools/offcputime.c ++++ b/libbpf-tools/offcputime.c +@@ -279,9 +279,14 @@ int main(int argc, char **argv) + return 1; + } + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = offcputime_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/opensnoop.c b/libbpf-tools/opensnoop.c +index 557a63cd..5cdac0e5 100644 +--- a/libbpf-tools/opensnoop.c ++++ b/libbpf-tools/opensnoop.c +@@ -219,6 +219,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct opensnoop_bpf *obj; + __u64 time_end = 0; +@@ -228,9 +229,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = opensnoop_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -276,10 +282,13 @@ int main(int argc, char **argv) + printf("%s\n", "PATH"); + + /* setup event callbacks */ ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + fprintf(stderr, "failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -297,8 +306,8 @@ int main(int argc, char **argv) + /* main: poll */ + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + if (env.duration && get_ktime_ns() > time_end) +diff --git a/libbpf-tools/readahead.c b/libbpf-tools/readahead.c +index 17079389..77986011 100644 +--- a/libbpf-tools/readahead.c ++++ b/libbpf-tools/readahead.c +@@ -109,9 +109,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = readahead_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/runqlat.c b/libbpf-tools/runqlat.c +index 5a60b874..249bf794 100644 +--- a/libbpf-tools/runqlat.c ++++ b/libbpf-tools/runqlat.c +@@ -193,9 +193,14 @@ int main(int argc, char **argv) + return 1; + } + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = runqlat_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/runqlen.c b/libbpf-tools/runqlen.c +index 9cbbc739..2f6c5789 100644 +--- a/libbpf-tools/runqlen.c ++++ b/libbpf-tools/runqlen.c +@@ -145,8 +145,10 @@ static int open_and_attach_perf_event(int freq, struct bpf_program *prog, + return -1; + } + links[i] = bpf_program__attach_perf_event(prog, fd); +- if (!links[i]) { +- fprintf(stderr, "failed to attach perf event on cpu: %d\n", i); ++ if (libbpf_get_error(links[i])) { ++ fprintf(stderr, "failed to attach perf event on cpu: " ++ "%d\n", i); ++ links[i] = NULL; + close(fd); + return -1; + } +@@ -229,9 +231,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + nr_cpus = libbpf_num_possible_cpus(); + if (nr_cpus < 0) { + printf("failed to get # of possible cpus: '%s'!\n", +diff --git a/libbpf-tools/runqslower.c b/libbpf-tools/runqslower.c +index b038173e..b21894ca 100644 +--- a/libbpf-tools/runqslower.c ++++ b/libbpf-tools/runqslower.c +@@ -145,6 +145,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct runqslower_bpf *obj; + int err; +@@ -153,9 +154,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = runqslower_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -185,10 +191,12 @@ int main(int argc, char **argv) + else + printf("%-8s %-16s %-6s %14s\n", "TIME", "COMM", "TID", "LAT(us)"); + +- pb = perf_buffer__new(bpf_map__fd(obj->maps.events), 64, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; ++ pb = perf_buffer__new(bpf_map__fd(obj->maps.events), 64, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + fprintf(stderr, "failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -201,8 +209,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, 100); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/softirqs.c b/libbpf-tools/softirqs.c +index 34cfdb77..f1678d4c 100644 +--- a/libbpf-tools/softirqs.c ++++ b/libbpf-tools/softirqs.c +@@ -195,9 +195,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = softirqs_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/solisten.c b/libbpf-tools/solisten.c +index adaa668d..e5812f0c 100644 +--- a/libbpf-tools/solisten.c ++++ b/libbpf-tools/solisten.c +@@ -137,6 +137,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct solisten_bpf *obj; + int err; +@@ -145,7 +146,11 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + + obj = solisten_bpf__open(); +@@ -175,10 +180,11 @@ int main(int argc, char **argv) + goto cleanup; + } + +- pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; ++ pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -196,8 +202,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- warn("error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ warn("error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/statsnoop.c b/libbpf-tools/statsnoop.c +index 3f8f5c58..76779da6 100644 +--- a/libbpf-tools/statsnoop.c ++++ b/libbpf-tools/statsnoop.c +@@ -127,6 +127,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct statsnoop_bpf *obj; + int err; +@@ -135,9 +136,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %d\n", err); ++ return 1; ++ } + libbpf_set_print(libbpf_print_fn); + ++ + obj = statsnoop_bpf__open(); + if (!obj) { + warn("failed to open BPF object\n"); +@@ -159,10 +165,12 @@ int main(int argc, char **argv) + goto cleanup; + } + ++ pb_opts.sample_cb = handle_event; ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -180,8 +188,8 @@ int main(int argc, char **argv) + + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- warn("error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ warn("error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/syscount.c b/libbpf-tools/syscount.c +index 2d687573..35c0e095 100644 +--- a/libbpf-tools/syscount.c ++++ b/libbpf-tools/syscount.c +@@ -390,9 +390,14 @@ int main(int argc, char **argv) + goto free_names; + } + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %s\n", strerror(errno)); ++ goto free_names; ++ } ++ + obj = syscount_bpf__open(); + if (!obj) { + warn("failed to open BPF object\n"); +@@ -418,15 +423,16 @@ int main(int argc, char **argv) + } + + obj->links.sys_exit = bpf_program__attach(obj->progs.sys_exit); +- if (!obj->links.sys_exit) { +- err = -errno; +- warn("failed to attach sys_exit program: %s\n", strerror(-err)); ++ err = libbpf_get_error(obj->links.sys_exit); ++ if (err) { ++ warn("failed to attach sys_exit program: %s\n", ++ strerror(-err)); + goto cleanup_obj; + } + if (env.latency) { + obj->links.sys_enter = bpf_program__attach(obj->progs.sys_enter); +- if (!obj->links.sys_enter) { +- err = -errno; ++ err = libbpf_get_error(obj->links.sys_enter); ++ if (err) { + warn("failed to attach sys_enter programs: %s\n", + strerror(-err)); + goto cleanup_obj; +diff --git a/libbpf-tools/tcpconnect.c b/libbpf-tools/tcpconnect.c +index 101cf72b..82b2bebb 100644 +--- a/libbpf-tools/tcpconnect.c ++++ b/libbpf-tools/tcpconnect.c +@@ -324,13 +324,17 @@ static void handle_lost_events(void *ctx, int cpu, __u64 lost_cnt) + + static void print_events(int perf_map_fd) + { +- struct perf_buffer *pb; ++ struct perf_buffer_opts pb_opts = { ++ .sample_cb = handle_event, ++ .lost_cb = handle_lost_events, ++ }; ++ struct perf_buffer *pb = NULL; + int err; + +- pb = perf_buffer__new(perf_map_fd, 128, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- err = -errno; ++ pb = perf_buffer__new(perf_map_fd, 128, &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; + warn("failed to open perf buffer: %d\n", err); + goto cleanup; + } +@@ -338,8 +342,8 @@ static void print_events(int perf_map_fd) + print_events_header(); + while (!exiting) { + err = perf_buffer__poll(pb, 100); +- if (err < 0 && err != -EINTR) { +- warn("error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ warn("error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +@@ -365,9 +369,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ warn("failed to increase rlimit: %s\n", strerror(errno)); ++ return 1; ++ } ++ + obj = tcpconnect_bpf__open(); + if (!obj) { + warn("failed to open BPF object\n"); +diff --git a/libbpf-tools/tcpconnlat.c b/libbpf-tools/tcpconnlat.c +index 8eae76ae..3cab2115 100644 +--- a/libbpf-tools/tcpconnlat.c ++++ b/libbpf-tools/tcpconnlat.c +@@ -161,6 +161,7 @@ int main(int argc, char **argv) + .parser = parse_arg, + .doc = argp_program_doc, + }; ++ struct perf_buffer_opts pb_opts; + struct perf_buffer *pb = NULL; + struct tcpconnlat_bpf *obj; + int err; +@@ -169,9 +170,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = tcpconnlat_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +@@ -193,10 +199,15 @@ int main(int argc, char **argv) + goto cleanup; + } + ++ pb_opts.sample_cb = handle_event; ++ ++ pb_opts.lost_cb = handle_lost_events; + pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, +- handle_event, handle_lost_events, NULL, NULL); +- if (!pb) { +- fprintf(stderr, "failed to open perf buffer: %d\n", errno); ++ &pb_opts); ++ err = libbpf_get_error(pb); ++ if (err) { ++ pb = NULL; ++ fprintf(stderr, "failed to open perf buffer: %d\n", err); + goto cleanup; + } + +@@ -211,6 +222,7 @@ int main(int argc, char **argv) + "PID", "COMM", "IP", "SADDR", "DADDR", "DPORT", "LAT(ms)"); + } + ++ + if (signal(SIGINT, sig_int) == SIG_ERR) { + fprintf(stderr, "can't set signal handler: %s\n", strerror(errno)); + err = 1; +@@ -220,8 +232,8 @@ int main(int argc, char **argv) + /* main: poll */ + while (!exiting) { + err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); +- if (err < 0 && err != -EINTR) { +- fprintf(stderr, "error polling perf buffer: %s\n", strerror(-err)); ++ if (err < 0 && errno != EINTR) { ++ fprintf(stderr, "error polling perf buffer: %s\n", strerror(errno)); + goto cleanup; + } + /* reset err to return 0 if exiting */ +diff --git a/libbpf-tools/tcprtt.c b/libbpf-tools/tcprtt.c +index bed6efa7..bdff55bb 100644 +--- a/libbpf-tools/tcprtt.c ++++ b/libbpf-tools/tcprtt.c +@@ -225,9 +225,14 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %d\n", err); ++ return 1; ++ } ++ + obj = tcprtt_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); +diff --git a/libbpf-tools/trace_helpers.c b/libbpf-tools/trace_helpers.c +index 322b3c4f..f37015e7 100644 +--- a/libbpf-tools/trace_helpers.c ++++ b/libbpf-tools/trace_helpers.c +@@ -967,6 +967,16 @@ unsigned long long get_ktime_ns(void) + return ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec; + } + ++int bump_memlock_rlimit(void) ++{ ++ struct rlimit rlim_new = { ++ .rlim_cur = RLIM_INFINITY, ++ .rlim_max = RLIM_INFINITY, ++ }; ++ ++ return setrlimit(RLIMIT_MEMLOCK, &rlim_new); ++} ++ + bool is_kernel_module(const char *name) + { + bool found = false; +@@ -997,22 +1007,20 @@ bool fentry_exists(const char *name, const char *mod) + const struct btf_type *type; + const struct btf_enum *e; + char sysfs_mod[80]; +- int id = -1, i, err; ++ int id = -1, i; + + base = btf__parse(sysfs_vmlinux, NULL); +- if (!base) { +- err = -errno; ++ if (libbpf_get_error(base)) { + fprintf(stderr, "failed to parse vmlinux BTF at '%s': %s\n", +- sysfs_vmlinux, strerror(-err)); ++ sysfs_vmlinux, strerror(-libbpf_get_error(base))); + goto err_out; + } + if (mod && module_btf_exists(mod)) { + snprintf(sysfs_mod, sizeof(sysfs_mod), "/sys/kernel/btf/%s", mod); + btf = btf__parse_split(sysfs_mod, base); +- if (!btf) { +- err = -errno; ++ if (libbpf_get_error(btf)) { + fprintf(stderr, "failed to load BTF from %s: %s\n", +- sysfs_mod, strerror(-err)); ++ sysfs_mod, strerror(-libbpf_get_error(btf))); + btf = base; + base = NULL; + } +diff --git a/libbpf-tools/trace_helpers.h b/libbpf-tools/trace_helpers.h +index 98fd640f..61cbe433 100644 +--- a/libbpf-tools/trace_helpers.h ++++ b/libbpf-tools/trace_helpers.h +@@ -58,6 +58,7 @@ void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, + unsigned int step, const char *val_type); + + unsigned long long get_ktime_ns(void); ++int bump_memlock_rlimit(void); + + bool is_kernel_module(const char *name); + +diff --git a/libbpf-tools/vfsstat.c b/libbpf-tools/vfsstat.c +index 5519c366..3a8a51d8 100644 +--- a/libbpf-tools/vfsstat.c ++++ b/libbpf-tools/vfsstat.c +@@ -150,9 +150,15 @@ int main(int argc, char **argv) + if (err) + return err; + +- libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + ++ err = bump_memlock_rlimit(); ++ if (err) { ++ fprintf(stderr, "failed to increase rlimit: %s\n", ++ strerror(errno)); ++ return 1; ++ } ++ + skel = vfsstat_bpf__open(); + if (!skel) { + fprintf(stderr, "failed to open BPF skelect\n"); +-- +2.35.1 + diff --git a/SOURCES/bcc-0.24.0-biolatency-biolatpcts-biosnoop-biotop-Build-fix-for-.patch b/SOURCES/bcc-0.24.0-biolatency-biolatpcts-biosnoop-biotop-Build-fix-for-.patch new file mode 100644 index 0000000..da15c6e --- /dev/null +++ b/SOURCES/bcc-0.24.0-biolatency-biolatpcts-biosnoop-biotop-Build-fix-for-.patch @@ -0,0 +1,125 @@ +From 879792d2d47c1308e884fb59d92fe535f7bb8d71 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Thu, 10 Mar 2022 08:37:21 -1000 +Subject: [PATCH 1/2] biolatency, biolatpcts, biosnoop, biotop: Build fix for + v5.17+ + +During 5.17 dev cycle, the kernel dropped request->rq_disk. It can now be +accessed through request->q->disk. Fix the python ones in tools/. There are +more usages in other places which need to be fixed too. + +Signed-off-by: Tejun Heo +Signed-off-by: Jerome Marchand +--- + tools/biolatency.py | 8 ++++++-- + tools/biolatpcts.py | 11 ++++++++--- + tools/biosnoop.py | 6 +++++- + tools/biotop.py | 9 +++++++-- + 4 files changed, 26 insertions(+), 8 deletions(-) + +diff --git a/tools/biolatency.py b/tools/biolatency.py +index 427cee47..10c852ac 100755 +--- a/tools/biolatency.py ++++ b/tools/biolatency.py +@@ -128,12 +128,16 @@ storage_str = "" + store_str = "" + if args.disks: + storage_str += "BPF_HISTOGRAM(dist, disk_key_t);" +- store_str += """ ++ disks_str = """ + disk_key_t key = {.slot = bpf_log2l(delta)}; +- void *__tmp = (void *)req->rq_disk->disk_name; ++ void *__tmp = (void *)req->__RQ_DISK__->disk_name; + bpf_probe_read(&key.disk, sizeof(key.disk), __tmp); + dist.atomic_increment(key); + """ ++ if BPF.kernel_struct_has_field(b'request', b'rq_disk'): ++ store_str += disks_str.replace('__RQ_DISK__', 'rq_disk') ++ else: ++ store_str += disks_str.replace('__RQ_DISK__', 'q->disk') + elif args.flags: + storage_str += "BPF_HISTOGRAM(dist, flag_key_t);" + store_str += """ +diff --git a/tools/biolatpcts.py b/tools/biolatpcts.py +index 0f334419..ea8b1ce6 100755 +--- a/tools/biolatpcts.py ++++ b/tools/biolatpcts.py +@@ -72,9 +72,9 @@ void kprobe_blk_account_io_done(struct pt_regs *ctx, struct request *rq, u64 now + if (!rq->__START_TIME_FIELD__) + return; + +- if (!rq->rq_disk || +- rq->rq_disk->major != __MAJOR__ || +- rq->rq_disk->first_minor != __MINOR__) ++ if (!rq->__RQ_DISK__ || ++ rq->__RQ_DISK__->major != __MAJOR__ || ++ rq->__RQ_DISK__->first_minor != __MINOR__) + return; + + cmd_flags = rq->cmd_flags; +@@ -142,6 +142,11 @@ bpf_source = bpf_source.replace('__START_TIME_FIELD__', start_time_field) + bpf_source = bpf_source.replace('__MAJOR__', str(major)) + bpf_source = bpf_source.replace('__MINOR__', str(minor)) + ++if BPF.kernel_struct_has_field(b'request', b'rq_disk'): ++ bpf_source = bpf_source.replace('__RQ_DISK__', 'rq_disk') ++else: ++ bpf_source = bpf_source.replace('__RQ_DISK__', 'q->disk') ++ + bpf = BPF(text=bpf_source) + if BPF.get_kprobe_functions(b'__blk_account_io_done'): + bpf.attach_kprobe(event="__blk_account_io_done", fn_name="kprobe_blk_account_io_done") +diff --git a/tools/biosnoop.py b/tools/biosnoop.py +index ae38e384..a2b636aa 100755 +--- a/tools/biosnoop.py ++++ b/tools/biosnoop.py +@@ -125,7 +125,7 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) + data.pid = valp->pid; + data.sector = req->__sector; + bpf_probe_read_kernel(&data.name, sizeof(data.name), valp->name); +- struct gendisk *rq_disk = req->rq_disk; ++ struct gendisk *rq_disk = req->__RQ_DISK__; + bpf_probe_read_kernel(&data.disk_name, sizeof(data.disk_name), + rq_disk->disk_name); + } +@@ -156,6 +156,10 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) + bpf_text = bpf_text.replace('##QUEUE##', '1') + else: + bpf_text = bpf_text.replace('##QUEUE##', '0') ++if BPF.kernel_struct_has_field(b'request', b'rq_disk'): ++ bpf_text = bpf_text.replace('__RQ_DISK__', 'rq_disk') ++else: ++ bpf_text = bpf_text.replace('__RQ_DISK__', 'q->disk') + if debug or args.ebpf: + print(bpf_text) + if args.ebpf: +diff --git a/tools/biotop.py b/tools/biotop.py +index b3e3ea00..882835f6 100755 +--- a/tools/biotop.py ++++ b/tools/biotop.py +@@ -129,8 +129,8 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) + + // setup info_t key + struct info_t info = {}; +- info.major = req->rq_disk->major; +- info.minor = req->rq_disk->first_minor; ++ info.major = req->__RQ_DISK__->major; ++ info.minor = req->__RQ_DISK__->first_minor; + /* + * The following deals with a kernel version change (in mainline 4.7, although + * it may be backported to earlier kernels) with how block request write flags +@@ -174,6 +174,11 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) + print(bpf_text) + exit() + ++if BPF.kernel_struct_has_field(b'request', b'rq_disk'): ++ bpf_text = bpf_text.replace('__RQ_DISK__', 'rq_disk') ++else: ++ bpf_text = bpf_text.replace('__RQ_DISK__', 'q->disk') ++ + b = BPF(text=bpf_text) + if BPF.get_kprobe_functions(b'__blk_account_io_start'): + b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start") +-- +2.35.1 + diff --git a/SOURCES/bcc-0.24.0-biolatpcts-Build-fixes-on-recent-kernels.patch b/SOURCES/bcc-0.24.0-biolatpcts-Build-fixes-on-recent-kernels.patch new file mode 100644 index 0000000..e190cd5 --- /dev/null +++ b/SOURCES/bcc-0.24.0-biolatpcts-Build-fixes-on-recent-kernels.patch @@ -0,0 +1,60 @@ +From 2ada4cee035c4d07391faa870a5df1874d657b65 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Thu, 27 Jan 2022 06:25:31 -1000 +Subject: [PATCH 2/3] biolatpcts: Build fixes on recent kernels + +* `struct request` definition recently moved from blkdev.h to blk-mq.h + breaking both tools/biolatpcts and examples/tracing/biolatpcts. Fix them + by also including blk-mq.h. + +* blk_account_io_done() got split into two parts - inline condition checks + and the actual accounting with the latter now done in + __blk_account_io_done(). The kprobe attachment needs to be conditionalized + to work across the change. tools/biolatpcts was already updated but + examples/tracing/biolatpcts wasn't. Fix it. + +Signed-off-by: Tejun Heo +--- + examples/tracing/biolatpcts.py | 6 +++++- + tools/biolatpcts.py | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/examples/tracing/biolatpcts.py b/examples/tracing/biolatpcts.py +index c9bb834e..68a59516 100755 +--- a/examples/tracing/biolatpcts.py ++++ b/examples/tracing/biolatpcts.py +@@ -11,6 +11,7 @@ from time import sleep + + bpf_source = """ + #include ++#include + #include + #include + +@@ -45,7 +46,10 @@ void kprobe_blk_account_io_done(struct pt_regs *ctx, struct request *rq, u64 now + """ + + bpf = BPF(text=bpf_source) +-bpf.attach_kprobe(event='blk_account_io_done', fn_name='kprobe_blk_account_io_done') ++if BPF.get_kprobe_functions(b'__blk_account_io_done'): ++ bpf.attach_kprobe(event="__blk_account_io_done", fn_name="kprobe_blk_account_io_done") ++else: ++ bpf.attach_kprobe(event="blk_account_io_done", fn_name="kprobe_blk_account_io_done") + + cur_lat_100ms = bpf['lat_100ms'] + cur_lat_1ms = bpf['lat_1ms'] +diff --git a/tools/biolatpcts.py b/tools/biolatpcts.py +index a2f59592..0f334419 100755 +--- a/tools/biolatpcts.py ++++ b/tools/biolatpcts.py +@@ -56,6 +56,7 @@ parser.add_argument('--verbose', '-v', action='count', default = 0) + bpf_source = """ + #include + #include ++#include + #include + + BPF_PERCPU_ARRAY(rwdf_100ms, u64, 400); +-- +2.35.1 + diff --git a/SOURCES/bcc-0.24.0-libbpf-tools-Allow-to-use-different-cflags-for-bpf-t.patch b/SOURCES/bcc-0.24.0-libbpf-tools-Allow-to-use-different-cflags-for-bpf-t.patch new file mode 100644 index 0000000..5d40363 --- /dev/null +++ b/SOURCES/bcc-0.24.0-libbpf-tools-Allow-to-use-different-cflags-for-bpf-t.patch @@ -0,0 +1,49 @@ +From a6a5dba23d19f6a900b0359a7390df4a6b9a42f4 Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Tue, 15 Mar 2022 17:59:24 +0100 +Subject: [PATCH 1/3] libbpf-tools: Allow to use different cflags for bpf + targets + +commit 531b698cdc20 ("libbpf-tools: Enable compilation warnings for +BPF programs") applies CFLAGS to all targets. However, some of the c +flags typically used by distribution are not available to the bpf +target. Add a new BPFCFLAGS macro to take care of that. + +Fixes the following compilation error on fedora: + + BPF bashreadline.bpf.o +clang-13: warning: optimization flag '-ffat-lto-objects' is not supported [-Wignored-optimization-argument] +clang-13: warning: argument unused during compilation: '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1' [-Wunused-command-line-argument] +clang-13: warning: argument unused during compilation: '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1' [-Wunused-command-line-argument] +clang-13: warning: argument unused during compilation: '-fstack-clash-protection' [-Wunused-command-line-argument] +error: option 'cf-protection=return' cannot be specified on this target +error: option 'cf-protection=branch' cannot be specified on this target +2 errors generated. +--- + libbpf-tools/Makefile | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libbpf-tools/Makefile b/libbpf-tools/Makefile +index 6bf1ed08..39af95ec 100644 +--- a/libbpf-tools/Makefile ++++ b/libbpf-tools/Makefile +@@ -7,6 +7,7 @@ LIBBPF_SRC := $(abspath ../src/cc/libbpf/src) + LIBBPF_OBJ := $(abspath $(OUTPUT)/libbpf.a) + INCLUDES := -I$(OUTPUT) -I../src/cc/libbpf/include/uapi + CFLAGS := -g -O2 -Wall ++BPFCFLAGS := -g -O2 -Wall + INSTALL ?= install + prefix ?= /usr/local + ARCH := $(shell uname -m | sed 's/x86_64/x86/' | sed 's/aarch64/arm64/' | sed 's/ppc64le/powerpc/' | sed 's/mips.*/mips/') +@@ -106,7 +107,7 @@ $(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT) + + $(OUTPUT)/%.bpf.o: %.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(ARCH)/vmlinux.h | $(OUTPUT) + $(call msg,BPF,$@) +- $(Q)$(CLANG) $(CFLAGS) -target bpf -D__TARGET_ARCH_$(ARCH) \ ++ $(Q)$(CLANG) $(BPFCFLAGS) -target bpf -D__TARGET_ARCH_$(ARCH) \ + -I$(ARCH)/ $(INCLUDES) -c $(filter %.c,$^) -o $@ && \ + $(LLVM_STRIP) -g $@ + +-- +2.35.1 + diff --git a/SOURCES/bcc-0.24.0-libbpf-tools-Fix-dropped-request-rq_disk-for-kernel-.patch b/SOURCES/bcc-0.24.0-libbpf-tools-Fix-dropped-request-rq_disk-for-kernel-.patch new file mode 100644 index 0000000..8134d1f --- /dev/null +++ b/SOURCES/bcc-0.24.0-libbpf-tools-Fix-dropped-request-rq_disk-for-kernel-.patch @@ -0,0 +1,158 @@ +From 50480835adf15a389267393674504551b68987a2 Mon Sep 17 00:00:00 2001 +From: xingfeng2510 +Date: Wed, 30 Mar 2022 16:10:51 +0800 +Subject: [PATCH 2/2] libbpf-tools: Fix dropped request->rq_disk for kernel + 5.17+ + +Signed-off-by: Jerome Marchand +--- + libbpf-tools/biolatency.bpf.c | 20 ++++++++++++++++++-- + libbpf-tools/biosnoop.bpf.c | 12 +++++++++++- + libbpf-tools/biostacks.bpf.c | 12 +++++++++++- + libbpf-tools/bitesize.bpf.c | 12 +++++++++++- + 4 files changed, 51 insertions(+), 5 deletions(-) + +diff --git a/libbpf-tools/biolatency.bpf.c b/libbpf-tools/biolatency.bpf.c +index 648dda78..8f325046 100644 +--- a/libbpf-tools/biolatency.bpf.c ++++ b/libbpf-tools/biolatency.bpf.c +@@ -19,6 +19,10 @@ const volatile bool targ_ms = false; + const volatile bool filter_dev = false; + const volatile __u32 targ_dev = 0; + ++struct request_queue___x { ++ struct gendisk *disk; ++} __attribute__((preserve_access_index)); ++ + struct { + __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); + __type(key, u32); +@@ -53,9 +57,15 @@ int trace_rq_start(struct request *rq, int issue) + u64 ts = bpf_ktime_get_ns(); + + if (filter_dev) { +- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk); ++ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q); ++ struct gendisk *disk; + u32 dev; + ++ if (bpf_core_field_exists(q->disk)) ++ disk = BPF_CORE_READ(q, disk); ++ else ++ disk = BPF_CORE_READ(rq, rq_disk); ++ + dev = disk ? MKDEV(BPF_CORE_READ(disk, major), + BPF_CORE_READ(disk, first_minor)) : 0; + if (targ_dev != dev) +@@ -119,7 +129,13 @@ int BPF_PROG(block_rq_complete, struct request *rq, int error, + goto cleanup; + + if (targ_per_disk) { +- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk); ++ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q); ++ struct gendisk *disk; ++ ++ if (bpf_core_field_exists(q->disk)) ++ disk = BPF_CORE_READ(q, disk); ++ else ++ disk = BPF_CORE_READ(rq, rq_disk); + + hkey.dev = disk ? MKDEV(BPF_CORE_READ(disk, major), + BPF_CORE_READ(disk, first_minor)) : 0; +diff --git a/libbpf-tools/biosnoop.bpf.c b/libbpf-tools/biosnoop.bpf.c +index 54226e43..05903473 100644 +--- a/libbpf-tools/biosnoop.bpf.c ++++ b/libbpf-tools/biosnoop.bpf.c +@@ -15,6 +15,10 @@ const volatile __u32 targ_dev = 0; + + extern __u32 LINUX_KERNEL_VERSION __kconfig; + ++struct request_queue___x { ++ struct gendisk *disk; ++} __attribute__((preserve_access_index)); ++ + struct { + __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); + __type(key, u32); +@@ -92,7 +96,13 @@ int trace_rq_start(struct request *rq, bool insert) + + stagep = bpf_map_lookup_elem(&start, &rq); + if (!stagep) { +- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk); ++ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q); ++ struct gendisk *disk; ++ ++ if (bpf_core_field_exists(q->disk)) ++ disk = BPF_CORE_READ(q, disk); ++ else ++ disk = BPF_CORE_READ(rq, rq_disk); + + stage.dev = disk ? MKDEV(BPF_CORE_READ(disk, major), + BPF_CORE_READ(disk, first_minor)) : 0; +diff --git a/libbpf-tools/biostacks.bpf.c b/libbpf-tools/biostacks.bpf.c +index 01993737..c13975fa 100644 +--- a/libbpf-tools/biostacks.bpf.c ++++ b/libbpf-tools/biostacks.bpf.c +@@ -14,6 +14,10 @@ const volatile bool targ_ms = false; + const volatile bool filter_dev = false; + const volatile __u32 targ_dev = -1; + ++struct request_queue___x { ++ struct gendisk *disk; ++} __attribute__((preserve_access_index)); ++ + struct internal_rqinfo { + u64 start_ts; + struct rqinfo rqinfo; +@@ -41,9 +45,15 @@ static __always_inline + int trace_start(void *ctx, struct request *rq, bool merge_bio) + { + struct internal_rqinfo *i_rqinfop = NULL, i_rqinfo = {}; +- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk); ++ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q); ++ struct gendisk *disk; + u32 dev; + ++ if (bpf_core_field_exists(q->disk)) ++ disk = BPF_CORE_READ(q, disk); ++ else ++ disk = BPF_CORE_READ(rq, rq_disk); ++ + dev = disk ? MKDEV(BPF_CORE_READ(disk, major), + BPF_CORE_READ(disk, first_minor)) : 0; + if (filter_dev && targ_dev != dev) +diff --git a/libbpf-tools/bitesize.bpf.c b/libbpf-tools/bitesize.bpf.c +index 80672c9b..5066ca33 100644 +--- a/libbpf-tools/bitesize.bpf.c ++++ b/libbpf-tools/bitesize.bpf.c +@@ -13,6 +13,10 @@ const volatile __u32 targ_dev = 0; + + extern __u32 LINUX_KERNEL_VERSION __kconfig; + ++struct request_queue___x { ++ struct gendisk *disk; ++} __attribute__((preserve_access_index)); ++ + struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 10240); +@@ -41,9 +45,15 @@ static int trace_rq_issue(struct request *rq) + u64 slot; + + if (filter_dev) { +- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk); ++ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q); ++ struct gendisk *disk; + u32 dev; + ++ if (bpf_core_field_exists(q->disk)) ++ disk = BPF_CORE_READ(q, disk); ++ else ++ disk = BPF_CORE_READ(rq, rq_disk); ++ + dev = disk ? MKDEV(BPF_CORE_READ(disk, major), + BPF_CORE_READ(disk, first_minor)) : 0; + if (targ_dev != dev) +-- +2.35.1 + diff --git a/SOURCES/bcc-0.24.0-tools-include-blk-mq.h-in-bio-tools.patch b/SOURCES/bcc-0.24.0-tools-include-blk-mq.h-in-bio-tools.patch new file mode 100644 index 0000000..1f7ce06 --- /dev/null +++ b/SOURCES/bcc-0.24.0-tools-include-blk-mq.h-in-bio-tools.patch @@ -0,0 +1,66 @@ +From 1eafb1f5aa0d3a9f60f89aad0ea55ae93899baff Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Wed, 23 Feb 2022 16:04:30 +0100 +Subject: [PATCH 3/3] tools: include blk-mq.h in bio tools + +Kernel commit 24b83deb29b ("block: move struct request to blk-mq.h") +has moved struct request from blkdev.h to blk-mq.h. It results in +several bio tools to fail with errors of the following type: + +error: incomplete definition of type 'struct request' + +Since blk-mq.h had always included blkdev.h. it is safe to simply +replace the inclusion of blkdev.h by blk-mq-h. It works on both older +and newer kernel. + +Fixes: #3869 + +Signed-off-by: Jerome Marchand +--- + tools/biolatency.py | 2 +- + tools/biosnoop.py | 2 +- + tools/biotop.py | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/biolatency.py b/tools/biolatency.py +index f4e2c9ea..427cee47 100755 +--- a/tools/biolatency.py ++++ b/tools/biolatency.py +@@ -64,7 +64,7 @@ debug = 0 + # define BPF program + bpf_text = """ + #include +-#include ++#include + + typedef struct disk_key { + char disk[DISK_NAME_LEN]; +diff --git a/tools/biosnoop.py b/tools/biosnoop.py +index 2b954ac9..ae38e384 100755 +--- a/tools/biosnoop.py ++++ b/tools/biosnoop.py +@@ -37,7 +37,7 @@ debug = 0 + # define BPF program + bpf_text=""" + #include +-#include ++#include + + // for saving the timestamp and __data_len of each request + struct start_req_t { +diff --git a/tools/biotop.py b/tools/biotop.py +index eac4dab9..b3e3ea00 100755 +--- a/tools/biotop.py ++++ b/tools/biotop.py +@@ -54,7 +54,7 @@ diskstats = "/proc/diskstats" + # load BPF program + bpf_text = """ + #include +-#include ++#include + + // for saving the timestamp and __data_len of each request + struct start_req_t { +-- +2.35.1 + diff --git a/SOURCES/bcc-0.24.0-tools-mdflush-include-blkdev.h-instead-of-genhd.h.patch b/SOURCES/bcc-0.24.0-tools-mdflush-include-blkdev.h-instead-of-genhd.h.patch new file mode 100644 index 0000000..18edfb4 --- /dev/null +++ b/SOURCES/bcc-0.24.0-tools-mdflush-include-blkdev.h-instead-of-genhd.h.patch @@ -0,0 +1,30 @@ +From 93a464e2ef05b7ef78b5679e366b89fcddf6a575 Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Mon, 1 Aug 2022 11:45:41 +0200 +Subject: [PATCH] tools/mdflush: include blkdev.h instead of genhd.h + +In recent kernels, i.e. since commit 322cbb50de71 ("block: remove +genhd.h"), genhd.h header has been removed and its content moved to +blkdev.h. Since genhd.h has been included in blkdev.h since forever, +including blkdev instead of genhd in the mdflush tool works for both +older and newer kernel. +--- + tools/mdflush.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/mdflush.py b/tools/mdflush.py +index 3581d1bf..6741d563 100755 +--- a/tools/mdflush.py ++++ b/tools/mdflush.py +@@ -19,7 +19,7 @@ from time import strftime + b = BPF(text=""" + #include + #include +-#include ++#include + #include + + struct data_t { +-- +2.37.1 + diff --git a/SPECS/bcc.spec b/SPECS/bcc.spec index ada1d4e..42396df 100644 --- a/SPECS/bcc.spec +++ b/SPECS/bcc.spec @@ -22,31 +22,23 @@ %global with_llvm_shared 1 %endif -# Force out of source build -%undefine __cmake_in_source_build Name: bcc -Version: 0.20.0 -Release: 10%{?dist} +Version: 0.24.0 +Release: 4%{?dist} Summary: BPF Compiler Collection (BCC) License: ASL 2.0 URL: https://github.com/iovisor/bcc Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz -Patch0: %{name}-%{version}-libbpf-tool-don-t-ignore-LDFLAGS.patch -Patch1: %{name}-%{version}-libbpf-tools-readahead-don-t-mark-struct-hist-as-sta.patch -Patch2: %{name}-%{version}-Define-KERNEL_VERSION.patch -Patch3: %{name}-%{version}-Revert-libbpf-tools-remove-unecessary-custom-NULL-de.patch -Patch4: %{name}-%{version}-sync-with-latest-libbpf-repo-3529.patch -Patch5: %{name}-%{version}-threadsnoop-look-for-pthread_create-in-libc-too.patch -Patch6: %{name}-%{version}-Update-cpudist.py.patch -Patch7: %{name}-%{version}-tools-readahead-compatible-with-kernel-version-5.10-.patch -Patch8: %{name}-%{version}-Fix-mdflush-on-RHEL9.patch -Patch9: %{name}-%{version}-Handle-renaming-of-task_struct_-state-field-on-RHEL-.patch -Patch10: %{name}-%{version}-Fix-a-llvm-compilation-error.patch -Patch11: %{name}-%{version}-Remove-APInt-APSInt-toString-std-string-variants.patch -Patch12: %{name}-%{version}-tools-Fix-BCC-bio-tools-with-recent-kernel-change.patch -Patch13: %{name}-%{version}-biolatpcts-Build-fixes-on-recent-kernels.patch -Patch14: %{name}-%{version}-tools-include-blk-mq.h-in-bio-tools.patch +Patch0: %{name}-%{version}-libbpf-tools-Allow-to-use-different-cflags-for-bpf-t.patch +Patch1: %{name}-%{version}-biolatpcts-Build-fixes-on-recent-kernels.patch +Patch2: %{name}-%{version}-tools-include-blk-mq.h-in-bio-tools.patch +Patch3: %{name}-%{version}-C9S-libpbf-version-fixes.patch +Patch4: %{name}-%{version}-Revert-libbpf-1.0-changes.patch +Patch5: %{name}-%{version}-C9S-Fix-mdflush.patch +Patch6: %{name}-%{version}-biolatency-biolatpcts-biosnoop-biotop-Build-fix-for-.patch +Patch7: %{name}-%{version}-libbpf-tools-Fix-dropped-request-rq_disk-for-kernel-.patch +Patch8: %{name}-%{version}-tools-mdflush-include-blkdev.h-instead-of-genhd.h.patch # Arches will be included as upstream support is added and dependencies are # satisfied in the respective arches @@ -58,6 +50,7 @@ BuildRequires: flex BuildRequires: libxml2-devel BuildRequires: python3-devel BuildRequires: elfutils-libelf-devel +BuildRequires: elfutils-debuginfod-client-devel BuildRequires: llvm-devel BuildRequires: clang-devel %if %{with llvm_static} @@ -67,9 +60,9 @@ BuildRequires: ncurses-devel %if %{with lua} BuildRequires: pkgconfig(luajit) %endif -BuildRequires: libbpf-devel >= 0.0.5-3, libbpf-static >= 0.0.5-3 +BuildRequires: libbpf-devel >= 0.6.0, libbpf-static >= 0.6.0 -Requires: libbpf >= 0.0.5-3 +Requires: libbpf >= 0.6.0 Requires: tar Recommends: kernel-devel @@ -88,6 +81,7 @@ performance analysis and network traffic control. %package devel Summary: Shared library for BPF Compiler Collection (BCC) Requires: %{name}%{?_isa} = %{version}-%{release} +Suggests: elfutils-debuginfod-client %description devel The %{name}-devel package contains libraries and header files for developing @@ -135,7 +129,6 @@ Command line tools for BPF Compiler Collection (BCC) %if %{with libbpf_tools} %package -n libbpf-tools Summary: Command line libbpf tools for BPF Compiler Collection (BCC) -BuildRequires: libbpf-devel >= 0.0.5-3, libbpf-static >= 0.0.5-3 BuildRequires: bpftool %description -n libbpf-tools @@ -147,11 +140,10 @@ Command line libbpf tools for BPF Compiler Collection (BCC) %build -%cmake . \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DREVISION_LAST=%{version} -DREVISION=%{version} -DPYTHON_CMD=python3 \ - -DCMAKE_USE_LIBBPF_PACKAGE:BOOL=TRUE \ - %{?with_llvm_shared:-DENABLE_LLVM_SHARED=1} +%cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DREVISION_LAST=%{version} -DREVISION=%{version} -DPYTHON_CMD=python3 \ + -DCMAKE_USE_LIBBPF_PACKAGE:BOOL=TRUE \ + %{?with_llvm_shared:-DENABLE_LLVM_SHARED=1} %cmake_build # It was discussed and agreed to package libbpf-tools with @@ -163,7 +155,17 @@ Command line libbpf tools for BPF Compiler Collection (BCC) pushd libbpf-tools; make BPFTOOL=bpftool LIBBPF_OBJ=%{_libdir}/libbpf.a CFLAGS="%{optflags}" LDFLAGS="%{build_ldflags}" make DESTDIR=./tmp-install prefix= install -(cd tmp-install/bin; for file in *; do mv $file bpf-$file; done;) +( + cd tmp-install/bin + for file in *; do + mv $file bpf-$file + done + # now fix the broken symlinks + for file in `find . -type l`; do + dest=$(readlink "$file") + ln -s -f bpf-$dest $file + done +) popd %endif @@ -197,7 +199,10 @@ rm -rf %{buildroot}%{_datadir}/%{name}/tools/old/ %if %{with libbpf_tools} mkdir -p %{buildroot}/%{_sbindir} -install libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir} +# We cannot use `install` because some of the tools are symlinks and `install` +# follows those. Since all the tools already have the correct permissions set, +# we just need to copy them to the right place while preserving those +cp -a libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir}/ %endif %ldconfig_scriptlets @@ -257,6 +262,19 @@ install libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir} %endif %changelog +* Tue Aug 23 2022 Jerome Marchand - 0.24.1-4 +- Fix mdflush tool (rhbz#2108001) + +* Fri Jul 01 2022 Jerome Marchand - 0.24.1-3 +- Rebuild for libbpf 0.6.0 + +* Wed May 18 2022 Jerome Marchand - 0.24.1-2 +- Rebuild (previous build failed with UNKNOWN_KOJI_ERROR) + +* Thu Mar 24 2022 Jerome Marchand - 0.24.0-1 +- Rebase to v0.24.0 +- Fix cmake build + * Fri Feb 25 2022 Jerome Marchand - 0.20.0-10 - Remove deprecated python_provides macro (needed for gating)