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

samples/bpf: simplify spintest with kprobe.multi

With the introduction of kprobe.multi, it is now possible to attach
multiple kprobes to a single BPF program without the need for multiple
definitions. Additionally, this method supports wildcard-based
matching, allowing for further simplification of BPF programs. In here,
an asterisk (*) wildcard is used to map to all symbols relevant to
spin_{lock|unlock}.

Furthermore, since kprobe.multi handles symbol matching, this commit
eliminates the need for the previous logic of reading the ksym table to
verify the existence of symbols.

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

authored by

Daniel T. Lee and committed by
Alexei Starovoitov
456d5355 8dc80551

+10 -29
+3 -14
samples/bpf/spintest.bpf.c
··· 47 47 } 48 48 49 49 /* add kprobes to all possible *spin* functions */ 50 - SEC("kprobe/spin_unlock")PROG(p1) 51 - SEC("kprobe/spin_lock")PROG(p2) 52 - SEC("kprobe/mutex_spin_on_owner")PROG(p3) 53 - SEC("kprobe/rwsem_spin_on_owner")PROG(p4) 54 - SEC("kprobe/spin_unlock_irqrestore")PROG(p5) 55 - SEC("kprobe/_raw_spin_unlock_irqrestore")PROG(p6) 56 - SEC("kprobe/_raw_spin_unlock_bh")PROG(p7) 57 - SEC("kprobe/_raw_spin_unlock")PROG(p8) 58 - SEC("kprobe/_raw_spin_lock_irqsave")PROG(p9) 59 - SEC("kprobe/_raw_spin_trylock_bh")PROG(p10) 60 - SEC("kprobe/_raw_spin_lock_irq")PROG(p11) 61 - SEC("kprobe/_raw_spin_trylock")PROG(p12) 62 - SEC("kprobe/_raw_spin_lock")PROG(p13) 63 - SEC("kprobe/_raw_spin_lock_bh")PROG(p14) 50 + SEC("kprobe.multi/spin_*lock*")PROG(spin_lock) 51 + SEC("kprobe.multi/*_spin_on_owner")PROG(spin_on_owner) 52 + SEC("kprobe.multi/_raw_spin_*lock*")PROG(raw_spin_lock) 64 53 65 54 /* and to inner bpf helpers */ 66 55 SEC("kprobe/htab_map_update_elem")PROG(p15)
+7 -15
samples/bpf/spintest_user.c
··· 9 9 10 10 int main(int ac, char **argv) 11 11 { 12 - char filename[256], symbol[256]; 13 12 struct bpf_object *obj = NULL; 14 13 struct bpf_link *links[20]; 15 14 long key, next_key, value; 16 15 struct bpf_program *prog; 17 16 int map_fd, i, j = 0; 18 - const char *section; 17 + char filename[256]; 19 18 struct ksym *sym; 20 19 21 20 if (load_kallsyms()) { ··· 43 44 } 44 45 45 46 bpf_object__for_each_program(prog, obj) { 46 - section = bpf_program__section_name(prog); 47 - if (sscanf(section, "kprobe/%s", symbol) != 1) 48 - continue; 49 - 50 - /* Attach prog only when symbol exists */ 51 - if (ksym_get_addr(symbol)) { 52 - links[j] = bpf_program__attach(prog); 53 - if (libbpf_get_error(links[j])) { 54 - fprintf(stderr, "bpf_program__attach failed\n"); 55 - links[j] = NULL; 56 - goto cleanup; 57 - } 58 - j++; 47 + links[j] = bpf_program__attach(prog); 48 + if (libbpf_get_error(links[j])) { 49 + fprintf(stderr, "bpf_program__attach failed\n"); 50 + links[j] = NULL; 51 + goto cleanup; 59 52 } 53 + j++; 60 54 } 61 55 62 56 for (i = 0; i < 5; i++) {