On Mon, Apr 18, 2022 at 5:49 AM Jiri Olsa <jolsa@xxxxxxxxxx> wrote: > > Using kallsyms_lookup_names function to speed up symbols lookup in > kprobe multi link attachment and replacing with it the current > kprobe_multi_resolve_syms function. > > This speeds up bpftrace kprobe attachment: > > # perf stat -r 5 -e cycles ./src/bpftrace -e 'kprobe:x* { } i:ms:1 { exit(); }' > ... > 6.5681 +- 0.0225 seconds time elapsed ( +- 0.34% ) > > After: > > # perf stat -r 5 -e cycles ./src/bpftrace -e 'kprobe:x* { } i:ms:1 { exit(); }' > ... > 0.5661 +- 0.0275 seconds time elapsed ( +- 4.85% ) > > Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx> > --- LGTM. Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > kernel/trace/bpf_trace.c | 113 +++++++++++++++++++++++---------------- > 1 file changed, 67 insertions(+), 46 deletions(-) > > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > index b26f3da943de..f49cdc46a21f 100644 > --- a/kernel/trace/bpf_trace.c > +++ b/kernel/trace/bpf_trace.c > @@ -2226,6 +2226,60 @@ struct bpf_kprobe_multi_run_ctx { > unsigned long entry_ip; > }; > > +struct user_syms { > + const char **syms; > + char *buf; > +}; > + > +static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32 cnt) > +{ > + unsigned long __user usymbol; > + const char **syms = NULL; > + char *buf = NULL, *p; > + int err = -EFAULT; > + unsigned int i; > + > + err = -ENOMEM; > + syms = kvmalloc(cnt * sizeof(*syms), GFP_KERNEL); > + if (!syms) > + goto error; > + > + buf = kvmalloc(cnt * KSYM_NAME_LEN, GFP_KERNEL); > + if (!buf) > + goto error; > + > + for (p = buf, i = 0; i < cnt; i++) { > + if (__get_user(usymbol, usyms + i)) { > + err = -EFAULT; > + goto error; > + } > + err = strncpy_from_user(p, (const char __user *) usymbol, KSYM_NAME_LEN); > + if (err == KSYM_NAME_LEN) > + err = -E2BIG; > + if (err < 0) > + goto error; > + syms[i] = p; > + p += err + 1; > + } > + > + err = 0; > + us->syms = syms; > + us->buf = buf; return 0 here instead of falling through into error: block? > + > +error: > + if (err) { > + kvfree(syms); > + kvfree(buf); > + } > + return err; > +} > + > +static void free_user_syms(struct user_syms *us) > +{ > + kvfree(us->syms); > + kvfree(us->buf); > +} > + > static void bpf_kprobe_multi_link_release(struct bpf_link *link) > { > struct bpf_kprobe_multi_link *kmulti_link; [...]