diff --git a/.gitignore b/.gitignore index 3663236..5c79ee1 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ /bcc-0.32.0.tar.gz /bcc-0.34.0.tar.gz /bcc-0.35.0.tar.gz +/bcc-0.36.1.tar.gz diff --git a/bcc-0.35.0-Fix-a-build-failure-with-clang21-5369.patch b/bcc-0.35.0-Fix-a-build-failure-with-clang21-5369.patch deleted file mode 100644 index 9a60277..0000000 --- a/bcc-0.35.0-Fix-a-build-failure-with-clang21-5369.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 6a0030da509eb0c28d2d8a5ccc2f07c9fd9d4e45 Mon Sep 17 00:00:00 2001 -From: yonghong-song -Date: Mon, 14 Jul 2025 20:21:59 -0700 -Subject: [PATCH 3/6] Fix a build failure with clang21 (#5369) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The build error message: - src/cc/frontends/clang/loader.cc:400:73: error: no matching function for - call to ‘clang::TextDiagnosticPrinter::TextDiagnosticPrinter( - llvm::raw_fd_ostream&, clang::DiagnosticOptions*)’ - 400 | auto diag_client = new TextDiagnosticPrinter(llvm::errs(), &*diag_opts); - | ^ -The llvm commit - https://github.com/llvm/llvm-project/pull/139584 -caused the build failure. - -Adjust the code properly and the error is fixed. ---- - src/cc/frontends/clang/loader.cc | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/src/cc/frontends/clang/loader.cc b/src/cc/frontends/clang/loader.cc -index 07dc9d6a..6f8387aa 100644 ---- a/src/cc/frontends/clang/loader.cc -+++ b/src/cc/frontends/clang/loader.cc -@@ -396,11 +396,19 @@ int ClangLoader::do_compile( - flags_cstr_rem.end()); - - // set up the error reporting class -+#if LLVM_VERSION_MAJOR >= 21 -+ DiagnosticOptions diag_opts; -+ auto diag_client = new TextDiagnosticPrinter(llvm::errs(), diag_opts); -+ -+ IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); -+ DiagnosticsEngine diags(DiagID, diag_opts, diag_client); -+#else - IntrusiveRefCntPtr diag_opts(new DiagnosticOptions()); - auto diag_client = new TextDiagnosticPrinter(llvm::errs(), &*diag_opts); - - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - DiagnosticsEngine diags(DiagID, &*diag_opts, diag_client); -+#endif - - // set up the command line argument wrapper - --- -2.51.0 - diff --git a/bcc-0.35.0-libbpf-tools-javagc-Include-usdt.bpf.h-header.patch b/bcc-0.35.0-libbpf-tools-javagc-Include-usdt.bpf.h-header.patch deleted file mode 100644 index de4a754..0000000 --- a/bcc-0.35.0-libbpf-tools-javagc-Include-usdt.bpf.h-header.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 43e4e1e12a00366fb29126f8929a7678bbca8323 Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Tue, 7 Oct 2025 15:32:36 +0200 -Subject: [PATCH 5/6] libbpf-tools/javagc: Include usdt.bpf.h header - -Include usdt.bpf.h header to javagc.bpf.c. - -Fixes the following error: -libbpf: usdt: failed to find USDT support BPF maps, did you forget to include bpf/usdt.bpf.h? -attach usdt mem__pool__gc__begin failed: No such process - -Signed-off-by: Jerome Marchand ---- - libbpf-tools/javagc.bpf.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libbpf-tools/javagc.bpf.c b/libbpf-tools/javagc.bpf.c -index 5bfe635c..35535d92 100644 ---- a/libbpf-tools/javagc.bpf.c -+++ b/libbpf-tools/javagc.bpf.c -@@ -3,6 +3,7 @@ - #include - #include - #include -+#include - #include "javagc.h" - - struct { --- -2.51.0 - diff --git a/bcc-0.35.0-libbpf-tools-ksnoop-Fix-two-invalid-access-to-map-va.patch b/bcc-0.35.0-libbpf-tools-ksnoop-Fix-two-invalid-access-to-map-va.patch deleted file mode 100644 index a7c17c8..0000000 --- a/bcc-0.35.0-libbpf-tools-ksnoop-Fix-two-invalid-access-to-map-va.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 7804b1238f6cb1a874a2c4a06caeac928412d0f5 Mon Sep 17 00:00:00 2001 -From: Rong Tao -Date: Sun, 13 Jul 2025 12:26:14 +0800 -Subject: [PATCH 4/6] libbpf-tools: ksnoop: Fix two invalid access to map value - (#5361) - -On fedora42, llvm 20.1.7, kernel 6.15.4-200.fc42.x86_64 has two verifier -errors. Test with command: - - $ sudo ./ksnoop trace do_sys_openat2 - -1st: - ; last_stack_depth = stack_depth - 1; @ ksnoop.bpf.c:102 - 108: (bc) w3 = w6 ; frame1: R3_w=scalar(id=5,smin=smin32=0,smax=umax=smax32=umax32=14,var_off=(0x0; 0xf)) R6=scalar(id=5,smin=smin32=0,smax=umax=smax32=umax32=14,var_off=(0x0; 0xf)) - 109: (04) w3 += -1 ; frame1: R3_w=scalar(smin=0,smax=umax=0xffffffff,smin32=-1,smax32=13,var_off=(0x0; 0xffffffff)) - 110: (bc) w4 = w3 ; frame1: R3_w=scalar(id=6,smin=0,smax=umax=0xffffffff,smin32=-1,smax32=13,var_off=(0x0; 0xffffffff)) R4_w=scalar(id=6,smin=0,smax=umax=0xffffffff,smin32=-1,smax32=13,var_off=(0x0; 0xffffffff)) - 111: (54) w4 &= 255 ; frame1: R4_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) - 112: (b7) r7 = 0 ; frame1: R7=0 - ; if (last_stack_depth >= 0 && @ ksnoop.bpf.c:104 - 113: (26) if w4 > 0xf goto pc+5 ; frame1: R4=scalar(smin=smin32=0,smax=umax=smax32=umax32=15,var_off=(0x0; 0xf)) - ; last_ip = func_stack->ips[last_stack_depth]; @ ksnoop.bpf.c:106 - 114: (57) r3 &= 255 ; frame1: R3_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) - 115: (67) r3 <<= 3 ; frame1: R3_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=2040,var_off=(0x0; 0x7f8)) - 116: (bf) r4 = r2 ; frame1: R2=map_value(map=ksnoop_func_sta,ks=8,vs=144) R4_w=map_value(map=ksnoop_func_sta,ks=8,vs=144) - 117: (0f) r4 += r3 ; frame1: R3_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=2040,var_off=(0x0; 0x7f8)) R4_w=map_value(map=ksnoop_func_sta,ks=8,vs=144,smin=smin32=0,smax=umax=smax32=umax32=2040,var_off=(0x0; 0x7f8)) - 118: (79) r7 = *(u64 *)(r4 +8) - invalid access to map value, value_size=144 off=2048 size=8 - - The last_stack_depth use 'w4 > 0xf' check boundary, but 'r3 &= 255' - is beyond 0xf (0~15). - -2nd: - ; trace_len = sizeof(*trace) + trace->buf_len - MAX_TRACE_BUF; @ ksnoop.bpf.c:222 - 502: (04) w5 += 4008 ; frame1: R5_w=scalar(smin=umin=smin32=umin32=4009,smax=umax=smax32=umax32=0x10fa7,var_off=(0x0; 0x1ffff)) - 503: (bc) w2 = w5 ; frame1: R2_w=scalar(id=27,smin=umin=smin32=umin32=4009,smax=umax=smax32=umax32=0x10fa7,var_off=(0x0; 0x1ffff)) R5_w=scalar(id=27,smin=umin=smin32=umin32=4009,smax=umax=smax32=umax32=0x10fa7,var_off=(0x0; 0x1ffff)) - 504: (54) w2 &= 65535 ; frame1: R2_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=0xffff,var_off=(0x0; 0xffff)) - ; if (trace_len <= sizeof(*trace)) @ ksnoop.bpf.c:224 - 505: (26) if w2 > 0x3fa8 goto pc+7 ; frame1: R2_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=16296,var_off=(0x0; 0x3fff)) - 506: (57) r5 &= 65535 ; frame1: R5_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=0xffff,var_off=(0x0; 0xffff)) - 507: (18) r2 = 0xffff8ec554700c00 ; frame1: R2_w=map_ptr(map=ksnoop_perf_map,ks=4,vs=4) - 509: (18) r3 = 0xffffffff ; frame1: R3_w=0xffffffff - 511: (bf) r4 = r9 ; frame1: R4_w=map_value(map=ksnoop_func_map,ks=8,vs=16296) R9=map_value(map=ksnoop_func_map,ks=8,vs=16296) - 512: (85) call bpf_perf_event_output#25 - invalid access to map value, value_size=16296 off=0 size=65535 - - Just fix it with size type 'u64' instead of 'u32', see: - long bpf_perf_event_output(void *ctx, struct bpf_map *map, u64 flags, void *data, u64 size) - -Signed-off-by: Rong Tao ---- - libbpf-tools/ksnoop.bpf.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/libbpf-tools/ksnoop.bpf.c b/libbpf-tools/ksnoop.bpf.c -index f07ff561..15aa7d75 100644 ---- a/libbpf-tools/ksnoop.bpf.c -+++ b/libbpf-tools/ksnoop.bpf.c -@@ -103,7 +103,8 @@ static struct trace *get_trace(struct pt_regs *ctx, bool entry) - /* get address of last function we called */ - if (last_stack_depth >= 0 && - last_stack_depth < FUNC_MAX_STACK_DEPTH) -- last_ip = func_stack->ips[last_stack_depth]; -+ bpf_probe_read_kernel(&last_ip, sizeof(last_ip), -+ &func_stack->ips[last_stack_depth]); - /* push ip onto stack. return will pop it. */ - func_stack->ips[stack_depth] = ip; - /* mask used in case bounds checks are optimized out */ -@@ -202,7 +203,7 @@ static struct trace *get_trace(struct pt_regs *ctx, bool entry) - - static void output_trace(struct pt_regs *ctx, struct trace *trace) - { -- __u16 trace_len; -+ __u64 trace_len; - - if (trace->buf_len == 0) - goto skip; --- -2.51.0 - diff --git a/bcc-0.35.0-tools-biolatency-biosnoop-biotop-use-TRACEPOINT_PROB.patch b/bcc-0.35.0-tools-biolatency-biosnoop-biotop-use-TRACEPOINT_PROB.patch deleted file mode 100644 index 87a8398..0000000 --- a/bcc-0.35.0-tools-biolatency-biosnoop-biotop-use-TRACEPOINT_PROB.patch +++ /dev/null @@ -1,425 +0,0 @@ -From cdd2ade85acd05c8c7af17b0802163ad6fcb8ec7 Mon Sep 17 00:00:00 2001 -From: Jerome Marchand -Date: Tue, 15 Jul 2025 02:25:38 +0200 -Subject: [PATCH] tools/{biolatency,biosnoop,biotop}: use TRACEPOINT_PROBE() - for tracepoints (#5366) - -When support for block_io_* tracepoint was added, it used -attach_tracepoint() since it was closer to the existing code that -attached to kprobes. However, that meant we have to rely on a local -prototype of the args structure and the tool can be broken by a -change of the tracepoints format, which is what happens with kernel -commit aa6ff4eb7c10d ("block: Add ioprio to block_rq tracepoint") -which added a new argument to block tracepoints. - -Replace attach_tracepoint() by TRACEPOINT_PROBE() so we don't have to -deal with the tracepoint format changes. - -Signed-off-by: Jerome Marchand ---- - tools/biolatency.py | 102 +++++++++++++++++++++++--------------------- - tools/biosnoop.py | 86 +++++++++++++++++++------------------ - tools/biotop.py | 81 ++++++++++++++++++----------------- - 3 files changed, 141 insertions(+), 128 deletions(-) - -diff --git a/tools/biolatency.py b/tools/biolatency.py -index 3ba1b237..1d3f2d80 100755 ---- a/tools/biolatency.py -+++ b/tools/biolatency.py -@@ -87,17 +87,6 @@ typedef struct ext_val { - u64 count; - } ext_val_t; - --struct tp_args { -- u64 __unused__; -- dev_t dev; -- sector_t sector; -- unsigned int nr_sector; -- unsigned int bytes; -- char rwbs[8]; -- char comm[16]; -- char cmd[]; --}; -- - struct start_key { - dev_t dev; - u32 _pad; -@@ -134,16 +123,6 @@ int trace_req_start(struct pt_regs *ctx, struct request *req) - return __trace_req_start(key); - } - --int trace_req_start_tp(struct tp_args *args) --{ -- struct start_key key = { -- .dev = args->dev, -- .sector = args->sector -- }; -- -- return __trace_req_start(key); --} -- - // output - static int __trace_req_done(struct start_key key) - { -@@ -176,8 +155,22 @@ int trace_req_done(struct pt_regs *ctx, struct request *req) - - return __trace_req_done(key); - } -+""" -+ -+tp_start_text = """ -+TRACEPOINT_PROBE(block, START_TP) -+{ -+ struct start_key key = { -+ .dev = args->dev, -+ .sector = args->sector -+ }; -+ -+ return __trace_req_start(key); -+} -+""" - --int trace_req_done_tp(struct tp_args *args) -+tp_done_text = """ -+TRACEPOINT_PROBE(block, DONE_TP) - { - struct start_key key = { - .dev = args->dev, -@@ -266,41 +259,54 @@ bpf_text = bpf_text.replace("STORE", store_str) - if args.ebpf: - exit() - --# load BPF program --b = BPF(text=bpf_text) -+# Which kprobe/tracepoint to attach to. -+# We can attach to two IO start kprobes but only one of the other types. -+kprobe_start = set() -+tp_start = None -+kprobe_done = None -+tp_done = None -+ - if args.queued: -- if BPF.tracepoint_exists("block", "block_io_start"): -- b.attach_tracepoint(tp="block:block_io_start", fn_name="trace_req_start_tp") -- elif BPF.get_kprobe_functions(b'__blk_account_io_start'): -- b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_req_start") -+ if BPF.get_kprobe_functions(b'__blk_account_io_start'): -+ kprobe_start.add("__blk_account_io_start") - elif BPF.get_kprobe_functions(b'blk_account_io_start'): -- b.attach_kprobe(event="blk_account_io_start", fn_name="trace_req_start") -+ kprobe_start.add("blk_account_io_start") -+ elif BPF.tracepoint_exists("block", "block_io_start"): -+ tp_start = "block_io_start" - elif BPF.tracepoint_exists("block", "block_bio_queue"): -- b.attach_tracepoint(tp="block:block_bio_queue", fn_name="trace_req_start_tp") -- else: -- if args.flags: -- # Some flags are accessible in the rwbs field (RAHEAD, SYNC and META) -- # but other aren't. Disable the -F option for tracepoint for now. -- print("ERROR: blk_account_io_start probe not available. Can't use -F.") -- exit() -+ tp_start = "block_bio_queue" -+ - 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") -+ kprobe_start.add("blk_start_request") -+ kprobe_start.add("blk_mq_start_request") - --if BPF.tracepoint_exists("block", "block_io_done"): -- b.attach_tracepoint(tp="block:block_io_done", fn_name="trace_req_done_tp") --elif BPF.get_kprobe_functions(b'__blk_account_io_done'): -- b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_done") -+if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ kprobe_done = "__blk_account_io_done" - elif BPF.get_kprobe_functions(b'blk_account_io_done'): -- b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_done") -+ kprobe_done = "blk_account_io_done" -+elif BPF.tracepoint_exists("block", "block_io_done"): -+ tp_done = "block_io_done" - elif BPF.tracepoint_exists("block", "block_rq_complete"): -- b.attach_tracepoint(tp="block:block_rq_complete", fn_name="trace_req_done_tp") --else: -- if args.flags: -- print("ERROR: blk_account_io_done probe not available. Can't use -F.") -- exit() -+ tp_done = "block_rq_complete" -+ -+if args.flags and (tp_start or tp_done): -+ # Some flags are accessible in the rwbs field (RAHEAD, SYNC and META) -+ # but other aren't. Disable the -F option for tracepoint for now. -+ print("ERROR: blk_account_io_start/done probes not available. Can't use -F.") -+ exit() -+ -+if tp_start: -+ bpf_text += tp_start_text.replace("START_TP", tp_start) -+if tp_done: -+ bpf_text += tp_done_text.replace("DONE_TP", tp_done) - -+# load BPF program -+b = BPF(text=bpf_text) -+for i in kprobe_start: -+ b.attach_kprobe(event=i, fn_name="trace_req_start") -+if kprobe_done: -+ b.attach_kprobe(event=kprobe_done, fn_name="trace_req_done") - - if not args.json: - print("Tracing block device I/O... Hit Ctrl-C to end.") -diff --git a/tools/biosnoop.py b/tools/biosnoop.py -index 045e1f9d..65df90c3 100755 ---- a/tools/biosnoop.py -+++ b/tools/biosnoop.py -@@ -65,17 +65,6 @@ struct val_t { - char name[TASK_COMM_LEN]; - }; - --struct tp_args { -- u64 __unused__; -- dev_t dev; -- sector_t sector; -- unsigned int nr_sector; -- unsigned int bytes; -- char rwbs[8]; -- char comm[16]; -- char cmd[]; --}; -- - struct hash_key { - dev_t dev; - u32 rwflag; -@@ -182,17 +171,6 @@ int trace_pid_start(struct pt_regs *ctx, struct request *req) - return __trace_pid_start(key); - } - --int trace_pid_start_tp(struct tp_args *args) --{ -- struct hash_key key = { -- .dev = args->dev, -- .rwflag = get_rwflag_tp(args->rwbs), -- .sector = args->sector -- }; -- -- return __trace_pid_start(key); --} -- - // time block I/O - int trace_req_start(struct pt_regs *ctx, struct request *req) - { -@@ -284,8 +262,23 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) - - return __trace_req_completion(ctx, key); - } -+""" - --int trace_req_completion_tp(struct tp_args *args) -+tp_start_text = """ -+TRACEPOINT_PROBE(block, block_io_start) -+{ -+ struct hash_key key = { -+ .dev = args->dev, -+ .rwflag = get_rwflag_tp(args->rwbs), -+ .sector = args->sector -+ }; -+ -+ return __trace_pid_start(key); -+} -+""" -+ -+tp_done_text = """ -+TRACEPOINT_PROBE(block, block_io_done) - { - struct hash_key key = { - .dev = args->dev, -@@ -296,6 +289,7 @@ int trace_req_completion_tp(struct tp_args *args) - return __trace_req_completion(args, key); - } - """ -+ - if args.queue: - bpf_text = bpf_text.replace('##QUEUE##', '1') - else: -@@ -329,31 +323,41 @@ int trace_req_completion_tp(struct tp_args *args) - if args.ebpf: - exit() - --# initialize BPF --b = BPF(text=bpf_text) - if BPF.tracepoint_exists("block", "block_io_start"): -- b.attach_tracepoint(tp="block:block_io_start", fn_name="trace_pid_start_tp") --elif BPF.get_kprobe_functions(b'__blk_account_io_start'): -- b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start") --elif BPF.get_kprobe_functions(b'blk_account_io_start'): -- b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") -+ bpf_text += tp_start_text -+ tp_start = True -+else: -+ tp_start = False -+ -+if BPF.tracepoint_exists("block", "block_io_done"): -+ bpf_text += tp_done_text -+ tp_done = True - else: -- print("ERROR: No found any block io start probe/tp.") -- exit() -+ tp_done = False -+ -+# initialize BPF -+b = BPF(text=bpf_text) -+if not tp_start: -+ if BPF.get_kprobe_functions(b'__blk_account_io_start'): -+ b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start") -+ elif BPF.get_kprobe_functions(b'blk_account_io_start'): -+ b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") -+ else: -+ print("ERROR: No found any block io start probe/tp.") -+ exit() - - 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") - --if BPF.tracepoint_exists("block", "block_io_done"): -- b.attach_tracepoint(tp="block:block_io_done", fn_name="trace_req_completion_tp") --elif BPF.get_kprobe_functions(b'__blk_account_io_done'): -- b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_completion") --elif BPF.get_kprobe_functions(b'blk_account_io_done'): -- b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_completion") --else: -- print("ERROR: No found any block io done probe/tp.") -- exit() -+if not tp_done: -+ if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_completion") -+ elif BPF.get_kprobe_functions(b'blk_account_io_done'): -+ b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_completion") -+ else: -+ print("ERROR: No found any block io done probe/tp.") -+ exit() - - - # header -diff --git a/tools/biotop.py b/tools/biotop.py -index 480c37a4..4281b742 100755 ---- a/tools/biotop.py -+++ b/tools/biotop.py -@@ -90,17 +90,6 @@ struct val_t { - u32 io; - }; - --struct tp_args { -- u64 __unused__; -- dev_t dev; -- sector_t sector; -- unsigned int nr_sector; -- unsigned int bytes; -- char rwbs[8]; -- char comm[16]; -- char cmd[]; --}; -- - struct hash_key { - dev_t dev; - u32 _pad; -@@ -143,16 +132,6 @@ int trace_pid_start(struct pt_regs *ctx, struct request *req) - return __trace_pid_start(key); - } - --int trace_pid_start_tp(struct tp_args *args) --{ -- struct hash_key key = { -- .dev = args->dev, -- .sector = args->sector -- }; -- -- return __trace_pid_start(key); --} -- - // time block I/O - int trace_req_start(struct pt_regs *ctx, struct request *req) - { -@@ -246,8 +225,22 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req) - - return __trace_req_completion(key); - } -+""" -+ -+tp_start_text = """ -+TRACEPOINT_PROBE(block, block_io_start) -+{ -+ struct hash_key key = { -+ .dev = args->dev, -+ .sector = args->sector -+ }; -+ -+ return __trace_pid_start(key); -+} -+""" - --int trace_req_completion_tp(struct tp_args *args) -+tp_done_text = """ -+TRACEPOINT_PROBE(block, block_io_done) - { - struct hash_key key = { - .dev = args->dev, -@@ -272,30 +265,40 @@ int trace_req_completion_tp(struct tp_args *args) - else: - bpf_text = bpf_text.replace('FILTER_PID', '0') - --b = BPF(text=bpf_text) - if BPF.tracepoint_exists("block", "block_io_start"): -- b.attach_tracepoint(tp="block:block_io_start", fn_name="trace_pid_start_tp") --elif BPF.get_kprobe_functions(b'__blk_account_io_start'): -- b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start") --elif BPF.get_kprobe_functions(b'blk_account_io_start'): -- b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") -+ bpf_text += tp_start_text -+ tp_start = True - else: -- print("ERROR: No found any block io start probe/tp.") -- exit() -+ tp_start = False -+ -+if BPF.tracepoint_exists("block", "block_io_done"): -+ bpf_text += tp_done_text -+ tp_done = True -+else: -+ tp_done = False -+ -+b = BPF(text=bpf_text) -+if not tp_start: -+ if BPF.get_kprobe_functions(b'__blk_account_io_start'): -+ b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start") -+ elif BPF.get_kprobe_functions(b'blk_account_io_start'): -+ b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start") -+ else: -+ print("ERROR: No found any block io start probe/tp.") -+ exit() - - 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") - --if BPF.tracepoint_exists("block", "block_io_done"): -- b.attach_tracepoint(tp="block:block_io_done", fn_name="trace_req_completion_tp") --elif BPF.get_kprobe_functions(b'__blk_account_io_done'): -- b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_completion") --elif BPF.get_kprobe_functions(b'blk_account_io_done'): -- b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_completion") --else: -- print("ERROR: No found any block io done probe/tp.") -- exit() -+if not tp_done: -+ if BPF.get_kprobe_functions(b'__blk_account_io_done'): -+ b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_req_completion") -+ elif BPF.get_kprobe_functions(b'blk_account_io_done'): -+ b.attach_kprobe(event="blk_account_io_done", fn_name="trace_req_completion") -+ else: -+ print("ERROR: No found any block io done probe/tp.") -+ exit() - - # check whether hash table batch ops is supported - htab_batch_ops = True if BPF.kernel_struct_has_field(b'bpf_map_ops', --- -2.50.1 - diff --git a/bcc-0.35.0-tools-tcpconnect-fix-iov-field-for-DNS-with-Linux-6..patch b/bcc-0.35.0-tools-tcpconnect-fix-iov-field-for-DNS-with-Linux-6..patch deleted file mode 100644 index d4c6ea4..0000000 --- a/bcc-0.35.0-tools-tcpconnect-fix-iov-field-for-DNS-with-Linux-6..patch +++ /dev/null @@ -1,64 +0,0 @@ -From 4af39db87ffbc8ae8f4e868da7fa076858f0c734 Mon Sep 17 00:00:00 2001 -From: Francois Lesueur <11961066+flesueur@users.noreply.github.com> -Date: Wed, 6 Aug 2025 06:11:02 +0200 -Subject: [PATCH 6/6] tools/tcpconnect: fix iov field for DNS with Linux>=6.4 - (#5382) - -Tcpconnect with DNS (-d flag) does not work with Linux>=6.4. The kernel representation of struct iov_iter changed in 6.4. - -This PR adapts the iov field depending on the structure. It also removes inet_sk() which did not work on a recent kernel (6.6). ---- - tools/tcpconnect.py | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/tools/tcpconnect.py b/tools/tcpconnect.py -index a38bad8d..dc35cb28 100755 ---- a/tools/tcpconnect.py -+++ b/tools/tcpconnect.py -@@ -276,7 +276,7 @@ int trace_udp_recvmsg(struct pt_regs *ctx) - { - __u64 pid_tgid = bpf_get_current_pid_tgid(); - struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx); -- struct inet_sock *is = inet_sk(sk); -+ struct inet_sock *is = (struct inet_sock *)sk; - - // only grab port 53 packets, 13568 is ntohs(53) - if (is->inet_dport == 13568) { -@@ -303,7 +303,7 @@ int trace_udp_ret_recvmsg(struct pt_regs *ctx) - goto delete_and_return; - size_t buflen = (size_t)copied; - -- if (buflen > msghdr->msg_iter.iov->iov_len) -+ if (buflen > msghdr->msg_iter.IOV_FIELD->iov_len) - goto delete_and_return; - - if (buflen > MAX_PKT) -@@ -313,7 +313,7 @@ int trace_udp_ret_recvmsg(struct pt_regs *ctx) - if (!data) // this should never happen, just making the verifier happy - return 0; - -- void *iovbase = msghdr->msg_iter.iov->iov_base; -+ void *iovbase = msghdr->msg_iter.IOV_FIELD->iov_base; - bpf_probe_read(data->pkt, buflen, iovbase); - dns_events.perf_submit(ctx, data, buflen); - -@@ -386,10 +386,14 @@ bpf_text = bpf_text.replace('FILTER_FAMILY', '') - bpf_text = bpf_text.replace('FILTER_UID', '') - - if args.dns: -- if BPF.kernel_struct_has_field(b'iov_iter', b'iter_type') == 1: -+ if BPF.kernel_struct_has_field(b'iov_iter', b'type') == 1: -+ dns_bpf_text = dns_bpf_text.replace('TYPE_FIELD', 'type') -+ else: - dns_bpf_text = dns_bpf_text.replace('TYPE_FIELD', 'iter_type') -+ if BPF.kernel_struct_has_field(b'iov_iter', b'iov') == 1: -+ dns_bpf_text = dns_bpf_text.replace('IOV_FIELD', 'iov') - else: -- dns_bpf_text = dns_bpf_text.replace('TYPE_FIELD', 'type') -+ dns_bpf_text = dns_bpf_text.replace('IOV_FIELD', '__iov') - bpf_text += dns_bpf_text - - if debug or args.ebpf: --- -2.51.0 - diff --git a/bcc-0.36.1-Fix-build-with-LLVM-22.patch b/bcc-0.36.1-Fix-build-with-LLVM-22.patch new file mode 100644 index 0000000..d901d4b --- /dev/null +++ b/bcc-0.36.1-Fix-build-with-LLVM-22.patch @@ -0,0 +1,63 @@ +From 6c966fe58767354225cf01a908ec5a9b78c403dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Holger=20Hoffst=C3=A4tte?= +Date: Mon, 2 Mar 2026 10:03:15 +0100 +Subject: [PATCH] Fix build with LLVM-22 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +LLVM-22 changed the signatures of various createDiagnostics() calls [1]. +Introduce a new version macro guard and adapt the code to the changed API. + +Fixes #5483 + +[1] https://github.com/llvm/llvm-project/commit/30633f30894129919050f24fdd1f8f6bc46beae0 + +Signed-off-by: Holger Hoffstätte +--- + src/cc/frontends/clang/loader.cc | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/cc/frontends/clang/loader.cc b/src/cc/frontends/clang/loader.cc +index 6f8387aa..1f706344 100644 +--- a/src/cc/frontends/clang/loader.cc ++++ b/src/cc/frontends/clang/loader.cc +@@ -464,7 +464,10 @@ int ClangLoader::do_compile( + } + invocation0.getFrontendOpts().DisableFree = false; + +-#if LLVM_VERSION_MAJOR >= 20 ++#if LLVM_VERSION_MAJOR >= 22 ++ compiler0.setVirtualFileSystem(llvm::vfs::getRealFileSystem()); ++ compiler0.createDiagnostics(new IgnoringDiagConsumer()); ++#elif LLVM_VERSION_MAJOR >= 20 + compiler0.createDiagnostics(*llvm::vfs::getRealFileSystem(), new IgnoringDiagConsumer()); + #else + compiler0.createDiagnostics(new IgnoringDiagConsumer()); +@@ -487,7 +490,10 @@ int ClangLoader::do_compile( + add_main_input(invocation1, main_path, &*out_buf); + invocation1.getFrontendOpts().DisableFree = false; + +-#if LLVM_VERSION_MAJOR >= 20 ++#if LLVM_VERSION_MAJOR >= 22 ++ compiler1.setVirtualFileSystem(llvm::vfs::getRealFileSystem()); ++ compiler1.createDiagnostics(); ++#elif LLVM_VERSION_MAJOR >= 20 + compiler1.createDiagnostics(*llvm::vfs::getRealFileSystem()); + #else + compiler1.createDiagnostics(); +@@ -517,7 +523,10 @@ int ClangLoader::do_compile( + invocation2.getCodeGenOpts().setInlining(CodeGenOptions::NormalInlining); + // suppress warnings in the 2nd pass, but bail out on errors (our fault) + invocation2.getDiagnosticOpts().IgnoreWarnings = true; +-#if LLVM_VERSION_MAJOR >= 20 ++#if LLVM_VERSION_MAJOR >= 22 ++ compiler2.setVirtualFileSystem(llvm::vfs::getRealFileSystem()); ++ compiler2.createDiagnostics(); ++#elif LLVM_VERSION_MAJOR >= 20 + compiler2.createDiagnostics(*llvm::vfs::getRealFileSystem()); + #else + compiler2.createDiagnostics(); +-- +2.54.0 + diff --git a/bcc-0.35.0-Revert-Fix-bashreadline-4903.patch b/bcc-0.36.1-Revert-Fix-bashreadline-4903.patch similarity index 100% rename from bcc-0.35.0-Revert-Fix-bashreadline-4903.patch rename to bcc-0.36.1-Revert-Fix-bashreadline-4903.patch diff --git a/bcc-0.36.1-clang-Add-microsoft-extensions-build-flags.patch b/bcc-0.36.1-clang-Add-microsoft-extensions-build-flags.patch new file mode 100644 index 0000000..7bb2373 --- /dev/null +++ b/bcc-0.36.1-clang-Add-microsoft-extensions-build-flags.patch @@ -0,0 +1,59 @@ +From 922a47200c19a0b6e436194712886ee082fd9f0a Mon Sep 17 00:00:00 2001 +From: Avinesh Kumar +Date: Fri, 6 Mar 2026 16:00:01 +0100 +Subject: [PATCH 2/2] clang: Add microsoft extensions build flags + +Starting in Linux 6.19, `struct ns_common` fields were moved into an +anonymous nested forward declaration (`struct ns_tree;`) within a +union.[1] +This causes Clang to throw a `[-Wmissing-declarations]` warning and +fail with missing member errors. + +This affects tools pulling in `` directly or +transitively (e.g. filetop, runqlat) + +Errors encountered: +include/linux/ns/ns_common_types.h:117:3: warning: declaration does not declare anything [-Wmissing-declarations] + 117 | struct ns_tree; + | ^~~~~~~~~~~~~~ +In file included from /virtual/main.c:5: +In file included from include/linux/pid_namespace.h:11: +include/linux/ns_common.h:25:23: error: no member named 'ns_id' in 'struct ns_common' + 25 | VFS_WARN_ON_ONCE(ns->ns_id == 0); + | ~~ ^ +include/linux/ns_common.h:26:13: error: no member named 'ns_id' in 'struct ns_common' + 26 | return ns->ns_id <= NS_LAST_INIT_ID; + | ~~ ^ +include/linux/ns_common.h:60:26: error: no member named '__ns_ref_active' in 'struct ns_common' + 60 | return atomic_read(&ns->__ns_ref_active); + +This patch fixes the issue globally by turning on microsoft extensions +flags. These flags have already been in the linux kernel. [2] + +[1] https://github.com/torvalds/linux/commit/a657bc8a75cf40c3d0814fe6488ba4af56528f42 +[2] https://github.com/torvalds/linux/commit/c4781dc3d1cf0e017e1f290607ddc56cfe187afc + +Signed-off-by: Avinesh Kumar +Fixes: #5488 +--- + src/cc/frontends/clang/kbuild_helper.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/cc/frontends/clang/kbuild_helper.cc b/src/cc/frontends/clang/kbuild_helper.cc +index 4f09a398..b5d6a55e 100644 +--- a/src/cc/frontends/clang/kbuild_helper.cc ++++ b/src/cc/frontends/clang/kbuild_helper.cc +@@ -137,6 +137,10 @@ int KBuildHelper::get_flags(const char *uname_machine, vector *cflags) { + cflags->push_back("-Wno-pointer-sign"); + cflags->push_back("-fno-stack-protector"); + ++ // Align with Linux kernel's -fms-extensions flags adopted since v6.19 ++ cflags->push_back("-fms-extensions"); ++ cflags->push_back("-Wno-microsoft-anon-tag"); ++ + /* + * kernel is usually build with gcc and the kernel devel header + * reflects that fact. However we build with clang and this must be +-- +2.54.0 + diff --git a/bcc.spec b/bcc.spec index 4d5f849..475b9bf 100644 --- a/bcc.spec +++ b/bcc.spec @@ -24,18 +24,15 @@ Name: bcc -Version: 0.35.0 -Release: 3%{?dist} +Version: 0.36.1 +Release: 1%{?dist} Summary: BPF Compiler Collection (BCC) License: Apache-2.0 URL: https://github.com/iovisor/bcc Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz Patch0: %%{name}-%%{version}-Revert-Fix-bashreadline-4903.patch -Patch1: %%{name}-%%{version}-tools-biolatency-biosnoop-biotop-use-TRACEPOINT_PROB.patch -Patch2: %%{name}-%%{version}-Fix-a-build-failure-with-clang21-5369.patch -Patch3: %%{name}-%%{version}-libbpf-tools-ksnoop-Fix-two-invalid-access-to-map-va.patch -Patch4: %%{name}-%%{version}-libbpf-tools-javagc-Include-usdt.bpf.h-header.patch -Patch5: %%{name}-%%{version}-tools-tcpconnect-fix-iov-field-for-DNS-with-Linux-6..patch +Patch1: %%{name}-%%{version}-Fix-build-with-LLVM-22.patch +Patch2: %%{name}-%%{version}-clang-Add-microsoft-extensions-build-flags.patch # Arches will be included as upstream support is added and dependencies are # satisfied in the respective arches @@ -135,6 +132,7 @@ Command line libbpf tools for BPF Compiler Collection (BCC) %endif %prep +# mv bcc-0.36.0/ bcc-0.36.1/ %autosetup -p1 @@ -268,6 +266,17 @@ cp -a libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir}/ %endif %changelog +* Mon May 18 2026 Jerome Marchand - 0.36.1-1 +- Rebase to version 0.36.1 (RHEL-162980) +- Rebuild with LLVM 22 (RHEL-140402) +- Fix multiple failure introduced by BPF 6.19 update (RHEL-174797) +- Fix klockstat (RHEL-174798) +- Fix bpf-cpufreq (RHEL-93855) +- Fix bpf-syncsnoop (RHEL-93854) +- Fix tcpaccept (RHEL-93424) +- Fix filegone, kvmexit, netqtop and tcpconnect on s390x (RHEL-75515) +- Fix profile on s390x (RHEL-68950) + * Wed Jan 07 2026 Jerome Marchand - 0.35.0-3 - Rebuild with LLVM 21 (RHEL-108333) diff --git a/sources b/sources index 21ac951..a4ea5bc 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (bcc-0.35.0.tar.gz) = 23cc1413fef785165fe9fd29a242fb13e4e56da7d63699dbed3d6d12902a1de392b412cb0e5754eff5aeecf0a023568d593c9f4cb5bca7a88013aadfaef4fa3d +SHA512 (bcc-0.36.1.tar.gz) = bada939f35deb806989a6f8b04943aecde472a4a85cd781861c67051a75fd197988090e67f5f937080b8d47643bc209cf7e83fbd6d811d727484d03f7be92092