Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

samples/bpf: make tracing programs to be more CO-RE centric

The existing tracing programs have been developed for a considerable
period of time and, as a result, do not properly incorporate the
features of the current libbpf, such as CO-RE. This is evident in
frequent usage of functions like PT_REGS* and the persistence of "hack"
methods using underscore-style bpf_probe_read_kernel from the past.

These programs are far behind the current level of libbpf and can
potentially confuse users. Therefore, this commit aims to convert the
outdated BPF programs to be more CO-RE centric.

Signed-off-by: Daniel T. Lee <danieltimlee@gmail.com>
Link: https://lore.kernel.org/r/20230818090119.477441-6-danieltimlee@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Daniel T. Lee and committed by
Alexei Starovoitov
11430421 02dabc24

+20 -40
+5 -13
samples/bpf/offwaketime.bpf.c
··· 8 8 #include <linux/version.h> 9 9 #include <bpf/bpf_helpers.h> 10 10 #include <bpf/bpf_tracing.h> 11 + #include <bpf/bpf_core_read.h> 11 12 12 13 #ifndef PERF_MAX_STACK_DEPTH 13 14 #define PERF_MAX_STACK_DEPTH 127 14 15 #endif 15 - 16 - #define _(P) \ 17 - ({ \ 18 - typeof(P) val; \ 19 - bpf_probe_read_kernel(&val, sizeof(val), &(P)); \ 20 - val; \ 21 - }) 22 16 23 17 #define MINBLOCK_US 1 24 18 #define MAX_ENTRIES 10000 ··· 62 68 SEC("kprobe/try_to_wake_up") 63 69 int waker(struct pt_regs *ctx) 64 70 { 65 - struct task_struct *p = (void *) PT_REGS_PARM1(ctx); 71 + struct task_struct *p = (void *)PT_REGS_PARM1_CORE(ctx); 72 + u32 pid = BPF_CORE_READ(p, pid); 66 73 struct wokeby_t woke; 67 - u32 pid; 68 - 69 - pid = _(p->pid); 70 74 71 75 bpf_get_current_comm(&woke.name, sizeof(woke.name)); 72 76 woke.ret = bpf_get_stackid(ctx, &stackmap, STACKID_FLAGS); ··· 113 121 SEC("kprobe.multi/finish_task_switch*") 114 122 int oncpu(struct pt_regs *ctx) 115 123 { 116 - struct task_struct *p = (void *) PT_REGS_PARM1(ctx); 124 + struct task_struct *p = (void *)PT_REGS_PARM1_CORE(ctx); 117 125 /* record previous thread sleep time */ 118 - u32 pid = _(p->pid); 126 + u32 pid = BPF_CORE_READ(p, pid); 119 127 #endif 120 128 u64 delta, ts, *tsp; 121 129
+7 -13
samples/bpf/test_overhead_kprobe.bpf.c
··· 8 8 #include <linux/version.h> 9 9 #include <bpf/bpf_helpers.h> 10 10 #include <bpf/bpf_tracing.h> 11 - 12 - #define _(P) \ 13 - ({ \ 14 - typeof(P) val = 0; \ 15 - bpf_probe_read_kernel(&val, sizeof(val), &(P)); \ 16 - val; \ 17 - }) 11 + #include <bpf/bpf_core_read.h> 18 12 19 13 SEC("kprobe/__set_task_comm") 20 14 int prog(struct pt_regs *ctx) ··· 20 26 u16 oom_score_adj; 21 27 u32 pid; 22 28 23 - tsk = (void *)PT_REGS_PARM1(ctx); 29 + tsk = (void *)PT_REGS_PARM1_CORE(ctx); 24 30 25 - pid = _(tsk->pid); 26 - bpf_probe_read_kernel_str(oldcomm, sizeof(oldcomm), &tsk->comm); 27 - bpf_probe_read_kernel_str(newcomm, sizeof(newcomm), 31 + pid = BPF_CORE_READ(tsk, pid); 32 + bpf_core_read_str(oldcomm, sizeof(oldcomm), &tsk->comm); 33 + bpf_core_read_str(newcomm, sizeof(newcomm), 28 34 (void *)PT_REGS_PARM2(ctx)); 29 - signal = _(tsk->signal); 30 - oom_score_adj = _(signal->oom_score_adj); 35 + signal = BPF_CORE_READ(tsk, signal); 36 + oom_score_adj = BPF_CORE_READ(signal, oom_score_adj); 31 37 return 0; 32 38 } 33 39
+5 -12
samples/bpf/tracex1.bpf.c
··· 8 8 #include "net_shared.h" 9 9 #include <linux/version.h> 10 10 #include <bpf/bpf_helpers.h> 11 + #include <bpf/bpf_core_read.h> 11 12 #include <bpf/bpf_tracing.h> 12 - 13 - #define _(P) \ 14 - ({ \ 15 - typeof(P) val = 0; \ 16 - bpf_probe_read_kernel(&val, sizeof(val), &(P)); \ 17 - val; \ 18 - }) 19 13 20 14 /* kprobe is NOT a stable ABI 21 15 * kernel functions can be removed, renamed or completely change semantics. ··· 28 34 struct sk_buff *skb; 29 35 int len; 30 36 31 - /* non-portable! works for the given kernel only */ 32 - bpf_probe_read_kernel(&skb, sizeof(skb), (void *)PT_REGS_PARM1(ctx)); 33 - dev = _(skb->dev); 34 - len = _(skb->len); 37 + bpf_core_read(&skb, sizeof(skb), (void *)PT_REGS_PARM1(ctx)); 38 + dev = BPF_CORE_READ(skb, dev); 39 + len = BPF_CORE_READ(skb, len); 35 40 36 - bpf_probe_read_kernel(devname, sizeof(devname), dev->name); 41 + BPF_CORE_READ_STR_INTO(&devname, dev, name); 37 42 38 43 if (devname[0] == 'l' && devname[1] == 'o') { 39 44 char fmt[] = "skb %p len %d\n";
+3 -2
samples/bpf/tracex5.bpf.c
··· 10 10 #include <uapi/linux/unistd.h> 11 11 #include <bpf/bpf_helpers.h> 12 12 #include <bpf/bpf_tracing.h> 13 + #include <bpf/bpf_core_read.h> 13 14 14 15 #define __stringify(x) #x 15 16 #define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F ··· 47 46 { 48 47 struct seccomp_data sd; 49 48 50 - bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx)); 49 + bpf_core_read(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx)); 51 50 if (sd.args[2] == 512) { 52 51 char fmt[] = "write(fd=%d, buf=%p, size=%d)\n"; 53 52 bpf_trace_printk(fmt, sizeof(fmt), ··· 60 59 { 61 60 struct seccomp_data sd; 62 61 63 - bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx)); 62 + bpf_core_read(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx)); 64 63 if (sd.args[2] > 128 && sd.args[2] <= 1024) { 65 64 char fmt[] = "read(fd=%d, buf=%p, size=%d)\n"; 66 65 bpf_trace_printk(fmt, sizeof(fmt),