Rebuild bcc with LLVM16 and misc fixes

Fixes the following issue:
- compactsnoop
- killsnoop documentation
- funcslower
- deadlock memory usage issue
- nfsslower
Also, use upstream fix for nfsslower unititialized struct issue.

Resolves: rhbz#2192952
Resolves: rhbz#2042236
Resolves: rhbz#2075500
Resolves: rhbz#2180934
Resolves: rhbz#2075415
Resolves: rhbz#2050112

Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
This commit is contained in:
Jerome Marchand 2023-03-22 15:21:36 +01:00
parent e35359999f
commit d4b938c7f2
7 changed files with 362 additions and 66 deletions

View File

@ -0,0 +1,58 @@
From 64f9c355a62f78000270d025b479b7eeba7349e9 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Wed, 11 Jan 2023 16:46:32 +0100
Subject: [PATCH] killsnoop: add missing -s and -T options to the synopsis
The -s option is missing from the synopsis of the killsnoop manpage,
example file and the comment on top of the tool itself.
Also, -T option is missing from the example file.
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
man/man8/killsnoop.8 | 2 +-
tools/killsnoop.py | 2 +-
tools/killsnoop_example.txt | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/man/man8/killsnoop.8 b/man/man8/killsnoop.8
index 3f63d2ee..cb2a975e 100644
--- a/man/man8/killsnoop.8
+++ b/man/man8/killsnoop.8
@@ -2,7 +2,7 @@
.SH NAME
killsnoop \- Trace signals issued by the kill() syscall. Uses Linux eBPF/bcc.
.SH SYNOPSIS
-.B killsnoop [\-h] [\-x] [-p PID] [-T PID]
+.B killsnoop [\-h] [\-x] [-p PID] [-T PID] [-s SIGNAL]
.SH DESCRIPTION
killsnoop traces the kill() syscall, to show signals sent via this method. This
may be useful to troubleshoot failing applications, where an unknown mechanism
diff --git a/tools/killsnoop.py b/tools/killsnoop.py
index c0166f1d..9cce8dcc 100755
--- a/tools/killsnoop.py
+++ b/tools/killsnoop.py
@@ -4,7 +4,7 @@
# killsnoop Trace signals issued by the kill() syscall.
# For Linux, uses BCC, eBPF. Embedded C.
#
-# USAGE: killsnoop [-h] [-x] [-p PID] [-T PID]
+# USAGE: killsnoop [-h] [-x] [-p PID] [-T PID] [-s SIGNAL]
#
# Copyright (c) 2015 Brendan Gregg.
# Licensed under the Apache License, Version 2.0 (the "License")
diff --git a/tools/killsnoop_example.txt b/tools/killsnoop_example.txt
index 904fe6ef..97c3ad70 100644
--- a/tools/killsnoop_example.txt
+++ b/tools/killsnoop_example.txt
@@ -19,7 +19,7 @@ The second line showed the same signal sent, this time resulting in a -3
USAGE message:
# ./killsnoop -h
-usage: killsnoop [-h] [-x] [-p PID]
+usage: killsnoop [-h] [-x] [-p PID] [-T PID] [-s SIGNAL]
Trace signals issued by the kill() syscall
--
2.39.2

View File

@ -0,0 +1,71 @@
From cc35f70515cb0f3b8032b8fb68f9f37a844e74c8 Mon Sep 17 00:00:00 2001
From: Rong Tao <rongtao@cestc.cn>
Date: Fri, 10 Feb 2023 23:28:55 +0800
Subject: [PATCH] tools/compactsnoop.py: Fix raw_tracepoint Invalid argument
error
kernel commit abd4349ff9b8("mm: compaction: cleanup the compaction trace
events") change the arguments of 'mm_compaction_begin' from (start_pfn,
migrate_pfn, free_pfn, end_pfn, sync) to (cc, start_pfn, end_pfn, sync),
and change the arguments of 'mm_compaction_end' from (start_pfn,
migrate_pfn, free_pfn, end_pfn, sync, ret) to (cc, start_pfn, end_pfn,
sync, ret).
Replacing RAW_TRACEPOINT_PROBE with TRACEPOINT_PROBE solves this problem
and guarantees compatibility.
$ sudo ./compactsnoop.py
bpf_attach_raw_tracepoint (mm_compaction_begin): Invalid argument
Traceback (most recent call last):
File "/home/sdb/Git/bcc/tools/./compactsnoop.py", line 292, in <module>
b = BPF(text=bpf_text)
^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/bcc/__init__.py", line 483, in __init__
self._trace_autoload()
File "/usr/lib/python3.11/site-packages/bcc/__init__.py", line 1462, in _trace_autoload
self.attach_raw_tracepoint(tp=tp, fn_name=fn.name)
File "/usr/lib/python3.11/site-packages/bcc/__init__.py", line 1055, in attach_raw_tracepoint
raise Exception("Failed to attach BPF to raw tracepoint")
Exception: Failed to attach BPF to raw tracepoint
Signed-off-by: Rong Tao <rongtao@cestc.cn>
---
tools/compactsnoop.py | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/tools/compactsnoop.py b/tools/compactsnoop.py
index 2643e8ed..2b395dec 100755
--- a/tools/compactsnoop.py
+++ b/tools/compactsnoop.py
@@ -237,11 +237,9 @@ RAW_TRACEPOINT_PROBE(mm_compaction_suitable)
return 0;
}
-RAW_TRACEPOINT_PROBE(mm_compaction_begin)
+TRACEPOINT_PROBE(compaction, mm_compaction_begin)
{
- // TP_PROTO(unsigned long zone_start, unsigned long migrate_pfn,
- // unsigned long free_pfn, unsigned long zone_end, bool sync)
- bool sync = (bool)ctx->args[4];
+ bool sync = args->sync;
u64 id = bpf_get_current_pid_tgid();
struct val_t *valp = start.lookup(&id);
@@ -255,12 +253,9 @@ RAW_TRACEPOINT_PROBE(mm_compaction_begin)
return 0;
}
-RAW_TRACEPOINT_PROBE(mm_compaction_end)
+TRACEPOINT_PROBE(compaction, mm_compaction_end)
{
- // TP_PROTO(unsigned long zone_start, unsigned long migrate_pfn,
- // unsigned long free_pfn, unsigned long zone_end, bool sync,
- // int status)
- submit_event(ctx, ctx->args[5]);
+ submit_event(args, args->status);
return 0;
}
"""
--
2.39.2

View File

@ -0,0 +1,76 @@
From 0e9384ec4c88d2da2d23475f58ec9bff7eb48639 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Tue, 25 Apr 2023 16:04:05 +0200
Subject: [PATCH] tools/deadlock: Add an option to set the maximum number of
stack traces
Commit 77f5252d ("tools/deadlock: support specifies maxnum of threads
and edge cases (#3455)") allow to set the maximum number of threads
and edge cases to be able to reduce the memory usage of the deadlock
tool. It however let the size of the map of stack traces fixed. It's
current size, 640k (actually rounded up to 1M) takes 1Gb of vmalloced
kernel memory.
This patch adds an option to make the maximum number of stack traces
user defined. It also set the default value to 64k, in line with the
current default for the number of edge cases and threads.
It fix the following issue on system with limited memory ressources:
could not open bpf map: stack_traces, error: Cannot allocate memory
Traceback (most recent call last):
File "/tmp/./deadlock.py", line 577, in <module>
main()
File "/tmp/./deadlock.py", line 489, in main
bpf = BPF(text=text)
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 479, in __init__
raise Exception("Failed to compile BPF module %s" % (src_file or "<text>"))
Exception: Failed to compile BPF module <text>
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
tools/deadlock.c | 2 +-
tools/deadlock.py | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/tools/deadlock.c b/tools/deadlock.c
index 006dc121..6ae405ba 100644
--- a/tools/deadlock.c
+++ b/tools/deadlock.c
@@ -60,7 +60,7 @@ struct thread_created_leaf_t {
BPF_HASH(thread_to_parent, u32, struct thread_created_leaf_t);
// Stack traces when threads are created and when mutexes are locked/unlocked.
-BPF_STACK_TRACE(stack_traces, 655360);
+BPF_STACK_TRACE(stack_traces, MAX_TRACES);
// The first argument to the user space function we are tracing
// is a pointer to the mutex M held by thread T.
diff --git a/tools/deadlock.py b/tools/deadlock.py
index 12de099f..f7eb4ce0 100755
--- a/tools/deadlock.py
+++ b/tools/deadlock.py
@@ -467,6 +467,13 @@ import time
help='Specifies the maximum number of edge cases that can be recorded. '
'default 65536. Note. 88 bytes per edge case.'
)
+ parser.add_argument(
+ '-s', '--stacktraces', type=int, default=65536,
+ help='Specifies the maximum number of stack traces that can be recorded. '
+ 'This number is rounded up to the next power of two.'
+ 'default 65536. Note. 1 kbytes vmalloced per stack trace.'
+ )
+
args = parser.parse_args()
if not args.binary:
try:
@@ -479,6 +486,7 @@ import time
text = f.read()
text = text.replace('MAX_THREADS', str(args.threads));
text = text.replace('MAX_EDGES', str(args.edges));
+ text = text.replace('MAX_TRACES', str(args.stacktraces));
bpf = BPF(text=text)
# Trace where threads are created
--
2.39.2

View File

@ -0,0 +1,57 @@
From 29f0fa3693d679102680fece9ed5e606e291c5fa Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Fri, 7 Apr 2023 14:30:54 +0200
Subject: [PATCH] tools/funcslower: fix printing of folded stacks
When trying to print folded stack, funcslower tries to join bytes to a
string. Let's perform that operation with bytes only, and decode
before printing.
Also, decode symbols name before printing for the default stack
format, to avoid unsightly b'xxx' output.
It fixes the following error:
Exception ignored on calling ctypes callback function: <function PerfEventArray._open_perf_buffer.<locals>.raw_cb_ at 0x7f200541e5e0>
Traceback (most recent call last):
File "/usr/lib/python3.9/site-packages/bcc/table.py", line 982, in raw_cb_
callback(cpu, data, size)
File "/usr/share/bcc/tools/funcslower", line 340, in print_event
print_stack(event)
File "/usr/share/bcc/tools/funcslower", line 324, in print_stack
print("%s %d" % (";".join(line), 1))
TypeError: sequence item 1: expected str instance, bytes found
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
tools/funcslower.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/funcslower.py b/tools/funcslower.py
index 6df7f24c..4b3798a0 100755
--- a/tools/funcslower.py
+++ b/tools/funcslower.py
@@ -317,17 +317,17 @@ earliest_ts = 0
# print folded stack output
user_stack = list(user_stack)
kernel_stack = list(kernel_stack)
- line = [event.comm.decode('utf-8', 'replace')] + \
+ line = [event.comm] + \
[b.sym(addr, event.tgid_pid) for addr in reversed(user_stack)] + \
(do_delimiter and ["-"] or []) + \
[b.ksym(addr) for addr in reversed(kernel_stack)]
- print("%s %d" % (";".join(line), 1))
+ print("%s %d" % (b';'.join(line).decode('utf-8', 'replace'), 1))
else:
# print default multi-line stack output.
for addr in kernel_stack:
- print(" %s" % b.ksym(addr))
+ print(" %s" % b.ksym(addr).decode('utf-8', 'replace'))
for addr in user_stack:
- print(" %s" % b.sym(addr, event.tgid_pid))
+ print(" %s" % b.sym(addr, event.tgid_pid).decode('utf-8', 'replace'))
def print_event(cpu, data, size):
event = b["events"].event(data)
--
2.39.2

View File

@ -1,64 +0,0 @@
From acc8800b6f4380b6f4c7f04ee9a1263cf11deb35 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Tue, 20 Dec 2022 11:33:51 +0100
Subject: [PATCH] tools: nfsslower: fix an uninitialized struct error
Fixes the following error:
bpf: Failed to load program: Permission denied
reg type unsupported for arg#0 function trace_read_return#22
0: R1=ctx(off=0,imm=0) R10=fp0
; int trace_read_return(struct pt_regs *ctx)
0: (bf) r6 = r1 ; R1=ctx(off=0,imm=0) R6_w=ctx(off=0,imm=0)
[...]
; bpf_probe_read_kernel(&data.file, sizeof(data.file), (void *)qs.name);
75: (b7) r2 = 32 ; R2_w=32
76: (85) call bpf_probe_read_kernel#113 ; R0_w=scalar() fp-16=????mmmm fp-24=mmmmmmmm fp-32=mmmmmmmm fp-40=mmmmmmmm fp-48=mmmmmmmm
; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
77: (18) r2 = 0xffff9a0a42177200 ; R2_w=map_ptr(off=0,ks=4,vs=4,imm=0)
79: (bf) r4 = r10 ; R4_w=fp0 R10=fp0
; bpf_probe_read_kernel(&data.file, sizeof(data.file), (void *)qs.name);
80: (07) r4 += -104 ; R4_w=fp-104
; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
81: (bf) r1 = r6 ; R1_w=ctx(off=0,imm=0) R6=ctx(off=0,imm=0)
82: (18) r3 = 0xffffffff ; R3_w=4294967295
84: (b7) r5 = 96 ; R5_w=96
85: (85) call bpf_perf_event_output#25
invalid indirect read from stack R4 off -104+92 size 96
processed 82 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 3
Traceback (most recent call last):
File "/usr/share/bcc/tools/nfsslower", line 283, in <module>
b.attach_kretprobe(event="nfs_file_read", fn_name="trace_read_return")
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 872, in attach_kretprobe
fn = self.load_func(fn_name, BPF.KPROBE)
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 523, in load_func
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'trace_read_return': Permission denied
---
tools/nfsslower.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/nfsslower.py b/tools/nfsslower.py
index b5df8f19..682a3fb7 100755
--- a/tools/nfsslower.py
+++ b/tools/nfsslower.py
@@ -179,8 +179,12 @@ static int trace_exit(struct pt_regs *ctx, int type)
// populate output struct
u32 size = PT_REGS_RC(ctx);
- struct data_t data = {.type = type, .size = size, .delta_us = delta_us,
- .pid = pid};
+ struct data_t data;
+ __builtin_memset(&data, 0, sizeof(data));
+ data.type = type;
+ data.size = size;
+ data.delta_us = delta_us;
+ data.pid = pid;
data.ts_us = ts / 1000;
data.offset = valp->offset;
bpf_get_current_comm(&data.task, sizeof(data.task));
--
2.38.1

View File

@ -0,0 +1,85 @@
From 9965f8397950d8aa1bc1a5decbc2250d0627a798 Mon Sep 17 00:00:00 2001
From: Rong Tao <rongtao@cestc.cn>
Date: Fri, 10 Feb 2023 22:16:56 +0800
Subject: [PATCH] tools/nfsslower.py: Fix uninitialized struct pad error
The verifier is unhappy, if data struct _pad_ is not initialized, see [0][1].
$ sudo ./nfsslower.py
...
; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
83: (79) r1 = *(u64 *)(r10 -144) ; R1_w=ctx(off=0,imm=0) R10=fp0
84: (18) r3 = 0xffffffff ; R3_w=4294967295
86: (b7) r5 = 96 ; R5_w=96
87: (85) call bpf_perf_event_output#25
invalid indirect read from stack R4 off -136+92 size 96
processed 84 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 4
...
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'raw_tracepoint__nfs_commit_done': Permission denied
[0] https://github.com/iovisor/bcc/issues/2623
[1] https://github.com/iovisor/bcc/pull/4453
Signed-off-by: Rong Tao <rongtao@cestc.cn>
---
tools/nfsslower.py | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/tools/nfsslower.py b/tools/nfsslower.py
index 34756f72..99f63f0f 100755
--- a/tools/nfsslower.py
+++ b/tools/nfsslower.py
@@ -195,8 +195,11 @@ static int trace_exit(struct pt_regs *ctx, int type)
// populate output struct
u32 size = PT_REGS_RC(ctx);
- struct data_t data = {.type = type, .size = size, .delta_us = delta_us,
- .pid = pid};
+ struct data_t data = {};
+ data.type = type;
+ data.size = size;
+ data.delta_us = delta_us;
+ data.pid = pid;
data.ts_us = ts / 1000;
data.offset = valp->offset;
bpf_get_current_comm(&data.task, sizeof(data.task));
@@ -280,9 +283,14 @@ RAW_TRACEPOINT_PROBE(nfs_commit_done)
u64 ts = bpf_ktime_get_ns();
u64 delta_us = (ts - cp->ts) / 1000;
u32 pid = bpf_get_current_pid_tgid() >> 32;
- struct data_t data = {.type = TRACE_COMMIT, .offset = cp->offset,
- .size = cp->count, .ts_us = ts/1000, .delta_us = delta_us,
- .pid = pid};
+
+ struct data_t data = {};
+ data.type = TRACE_COMMIT;
+ data.offset = cp->offset;
+ data.size = cp->count;
+ data.ts_us = ts/1000;
+ data.delta_us = delta_us;
+ data.pid = pid;
commitinfo.delete(&key);
bpf_get_current_comm(&data.task, sizeof(data.task));
@@ -325,9 +333,14 @@ int trace_nfs_commit_done(struct pt_regs *ctx, void *task, void *calldata)
u64 ts = bpf_ktime_get_ns();
u64 delta_us = (ts - cp->ts) / 1000;
u32 pid = bpf_get_current_pid_tgid() >> 32;
- struct data_t data = {.type = TRACE_COMMIT, .offset = cp->offset,
- .size = cp->count, .ts_us = ts/1000, .delta_us = delta_us,
- .pid = pid};
+
+ struct data_t data = {};
+ data.type = TRACE_COMMIT;
+ data.offset = cp->offset;
+ data.size = cp->count;
+ data.ts_us = ts/1000;
+ data.delta_us = delta_us;
+ data.pid = pid;
commitinfo.delete(&key);
bpf_get_current_comm(&data.task, sizeof(data.task));
--
2.39.2

View File

@ -25,14 +25,18 @@
Name: bcc
Version: 0.26.0
Release: 2%{?dist}
Release: 3%{?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}-tools-nfsslower-fix-an-uninitialized-struct-error.patch
Patch0: %%{name}-%%{version}-tools-nfsslower.py-Fix-uninitialized-struct-pad-erro.patch
Patch1: %%{name}-%%{version}-tools-slabratetop-Fix-error-incomplete-definition-of.patch
Patch2: %%{name}-%%{version}-tools-readahead-Fix-Failed-to-attach-BPF-program-ent.patch
Patch3: %%{name}-%%{version}-tools-compactsnoop.py-Fix-raw_tracepoint-Invalid-arg.patch
Patch4: %%{name}-%%{version}-killsnoop-add-missing-s-and-T-options-to-the-synopsi.patch
Patch5: %%{name}-%%{version}-tools-funcslower-fix-printing-of-folded-stacks.patch
Patch6: %%{name}-%%{version}-tools-deadlock-Add-an-option-to-set-the-maximum-numb.patch
# Arches will be included as upstream support is added and dependencies are
# satisfied in the respective arches
@ -256,6 +260,15 @@ cp -a libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir}/
%endif
%changelog
* Fri May 12 2023 Jerome Marchand <jmarchan@redhat.com> - 0.26.0-3
- Rebuild with LLVM 16 (rhbz#2050112)
- Fix compactsnoop (rhbz#2042236)
- Fix killsnoop documentation (rhbz#2075500)
- Fix funcslower (rhbz#2075415)
- Fix deadlock memory usage issue (rhbz#2050112)
- Fix nfsslower (rhbz#2180934)
- Use upstream fix for nfsslower unititialized struct issue
* Wed Mar 15 2023 Jerome Marchand <jmarchan@redhat.com> - 0.26.0-2
- Rebuild with the right rhel-target