Skip to content

Commit

Permalink
bcc/tools: Fix renaming of the state field of task_struct
Browse files Browse the repository at this point in the history
Kernel commit 2f064a59a1 ("sched: Change task_struct::state") changes
the name of task_struct::state to task_struct::__state, which breaks
several bcc tools. Fix this issue by checking field existence in vmlinux
BTF. Since this change was intruduce in kernel v5.14, we should have
BTF support. Closes iovisor#3658 .

Signed-off-by: Hengqi Chen <[email protected]>
  • Loading branch information
chenhengqi authored and yonghong-song committed Nov 1, 2021
1 parent 8270cf2 commit 08765a9
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 16 deletions.
12 changes: 8 additions & 4 deletions tools/offcputime.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ def signal_ignore(signal, frame):
#define MAXBLOCK_US MAXBLOCK_US_VALUEULL
struct key_t {
u32 pid;
u32 tgid;
u64 pid;
u64 tgid;
int user_stack_id;
int kernel_stack_id;
char name[TASK_COMM_LEN];
Expand Down Expand Up @@ -205,14 +205,18 @@ def signal_ignore(signal, frame):
thread_context = "all threads"
thread_filter = '1'
if args.state == 0:
state_filter = 'prev->state == 0'
state_filter = 'prev->STATE_FIELD == 0'
elif args.state:
# these states are sometimes bitmask checked
state_filter = 'prev->state & %d' % args.state
state_filter = 'prev->STATE_FIELD & %d' % args.state
else:
state_filter = '1'
bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter)
bpf_text = bpf_text.replace('STATE_FILTER', state_filter)
if BPF.kernel_struct_has_field(b'task_struct', b'__state') == 1:
bpf_text = bpf_text.replace('STATE_FIELD', '__state')
else:
bpf_text = bpf_text.replace('STATE_FIELD', 'state')

# set stack storage size
bpf_text = bpf_text.replace('STACK_STORAGE_SIZE', str(args.stack_storage_size))
Expand Down
20 changes: 12 additions & 8 deletions tools/offwaketime.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ def signal_ignore(signal, frame):
struct key_t {
char waker[TASK_COMM_LEN];
char target[TASK_COMM_LEN];
int w_k_stack_id;
int w_u_stack_id;
int t_k_stack_id;
int t_u_stack_id;
u32 t_pid;
u32 t_tgid;
s64 w_k_stack_id;
s64 w_u_stack_id;
s64 t_k_stack_id;
s64 t_u_stack_id;
u64 t_pid;
u64 t_tgid;
u32 w_pid;
u32 w_tgid;
};
Expand Down Expand Up @@ -254,14 +254,18 @@ def signal_ignore(signal, frame):
else:
thread_filter = '1'
if args.state == 0:
state_filter = 'p->state == 0'
state_filter = 'p->STATE_FIELD == 0'
elif args.state:
# these states are sometimes bitmask checked
state_filter = 'p->state & %d' % args.state
state_filter = 'p->STATE_FIELD & %d' % args.state
else:
state_filter = '1'
bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter)
bpf_text = bpf_text.replace('STATE_FILTER', state_filter)
if BPF.kernel_struct_has_field(b'task_struct', b'__state') == 1:
bpf_text = bpf_text.replace('STATE_FIELD', '__state')
else:
bpf_text = bpf_text.replace('STATE_FIELD', 'state')

# set stack storage size
bpf_text = bpf_text.replace('STACK_STORAGE_SIZE', str(args.stack_storage_size))
Expand Down
8 changes: 6 additions & 2 deletions tools/runqlat.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
u32 pid, tgid;
// ivcsw: treat like an enqueue event and store timestamp
if (prev->state == TASK_RUNNING) {
if (prev->STATE_FIELD == TASK_RUNNING) {
tgid = prev->tgid;
pid = prev->pid;
if (!(FILTER || pid == 0)) {
Expand Down Expand Up @@ -210,7 +210,7 @@
u32 pid, tgid;
// ivcsw: treat like an enqueue event and store timestamp
if (prev->state == TASK_RUNNING) {
if (prev->STATE_FIELD == TASK_RUNNING) {
tgid = prev->tgid;
pid = prev->pid;
if (!(FILTER || pid == 0)) {
Expand Down Expand Up @@ -248,6 +248,10 @@
bpf_text += bpf_text_kprobe

# code substitutions
if BPF.kernel_struct_has_field(b'task_struct', b'__state') == 1:
bpf_text = bpf_text.replace('STATE_FIELD', '__state')
else:
bpf_text = bpf_text.replace('STATE_FIELD', 'state')
if args.pid:
# pid from userspace point of view is thread group from kernel pov
bpf_text = bpf_text.replace('FILTER', 'tgid != %s' % args.pid)
Expand Down
8 changes: 6 additions & 2 deletions tools/runqslower.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
// ivcsw: treat like an enqueue event and store timestamp
prev_pid = prev->pid;
if (prev->state == TASK_RUNNING) {
if (prev->STATE_FIELD == TASK_RUNNING) {
tgid = prev->tgid;
u64 ts = bpf_ktime_get_ns();
if (prev_pid != 0) {
Expand Down Expand Up @@ -185,7 +185,7 @@
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_FIELD);
bpf_probe_read_kernel(&prev_pid, sizeof(prev->pid), &prev->pid);
if (state == TASK_RUNNING) {
bpf_probe_read_kernel(&tgid, sizeof(prev->tgid), &prev->tgid);
Expand Down Expand Up @@ -234,6 +234,10 @@
bpf_text += bpf_text_kprobe

# code substitutions
if BPF.kernel_struct_has_field(b'task_struct', b'__state') == 1:
bpf_text = bpf_text.replace('STATE_FIELD', '__state')
else:
bpf_text = bpf_text.replace('STATE_FIELD', 'state')
if min_us == 0:
bpf_text = bpf_text.replace('FILTER_US', '0')
else:
Expand Down

0 comments on commit 08765a9

Please sign in to comment.