Skip to content

Commit 0236fec

Browse files
olsajiriAlexei Starovoitov
authored andcommitted
bpf: Resolve symbols with ftrace_lookup_symbols for kprobe multi link
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% ) Acked-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20220510122616.2652285-5-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 8be9253 commit 0236fec

File tree

1 file changed

+66
-46
lines changed

1 file changed

+66
-46
lines changed

kernel/trace/bpf_trace.c

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,59 @@ struct bpf_kprobe_multi_run_ctx {
22292229
unsigned long entry_ip;
22302230
};
22312231

2232+
struct user_syms {
2233+
const char **syms;
2234+
char *buf;
2235+
};
2236+
2237+
static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32 cnt)
2238+
{
2239+
unsigned long __user usymbol;
2240+
const char **syms = NULL;
2241+
char *buf = NULL, *p;
2242+
int err = -ENOMEM;
2243+
unsigned int i;
2244+
2245+
syms = kvmalloc(cnt * sizeof(*syms), GFP_KERNEL);
2246+
if (!syms)
2247+
goto error;
2248+
2249+
buf = kvmalloc(cnt * KSYM_NAME_LEN, GFP_KERNEL);
2250+
if (!buf)
2251+
goto error;
2252+
2253+
for (p = buf, i = 0; i < cnt; i++) {
2254+
if (__get_user(usymbol, usyms + i)) {
2255+
err = -EFAULT;
2256+
goto error;
2257+
}
2258+
err = strncpy_from_user(p, (const char __user *) usymbol, KSYM_NAME_LEN);
2259+
if (err == KSYM_NAME_LEN)
2260+
err = -E2BIG;
2261+
if (err < 0)
2262+
goto error;
2263+
syms[i] = p;
2264+
p += err + 1;
2265+
}
2266+
2267+
us->syms = syms;
2268+
us->buf = buf;
2269+
return 0;
2270+
2271+
error:
2272+
if (err) {
2273+
kvfree(syms);
2274+
kvfree(buf);
2275+
}
2276+
return err;
2277+
}
2278+
2279+
static void free_user_syms(struct user_syms *us)
2280+
{
2281+
kvfree(us->syms);
2282+
kvfree(us->buf);
2283+
}
2284+
22322285
static void bpf_kprobe_multi_link_release(struct bpf_link *link)
22332286
{
22342287
struct bpf_kprobe_multi_link *kmulti_link;
@@ -2349,53 +2402,12 @@ kprobe_multi_link_handler(struct fprobe *fp, unsigned long entry_ip,
23492402
kprobe_multi_link_prog_run(link, entry_ip, regs);
23502403
}
23512404

2352-
static int
2353-
kprobe_multi_resolve_syms(const void __user *usyms, u32 cnt,
2354-
unsigned long *addrs)
2405+
static int symbols_cmp(const void *a, const void *b)
23552406
{
2356-
unsigned long addr, size;
2357-
const char __user **syms;
2358-
int err = -ENOMEM;
2359-
unsigned int i;
2360-
char *func;
2361-
2362-
size = cnt * sizeof(*syms);
2363-
syms = kvzalloc(size, GFP_KERNEL);
2364-
if (!syms)
2365-
return -ENOMEM;
2407+
const char **str_a = (const char **) a;
2408+
const char **str_b = (const char **) b;
23662409

2367-
func = kmalloc(KSYM_NAME_LEN, GFP_KERNEL);
2368-
if (!func)
2369-
goto error;
2370-
2371-
if (copy_from_user(syms, usyms, size)) {
2372-
err = -EFAULT;
2373-
goto error;
2374-
}
2375-
2376-
for (i = 0; i < cnt; i++) {
2377-
err = strncpy_from_user(func, syms[i], KSYM_NAME_LEN);
2378-
if (err == KSYM_NAME_LEN)
2379-
err = -E2BIG;
2380-
if (err < 0)
2381-
goto error;
2382-
err = -EINVAL;
2383-
addr = kallsyms_lookup_name(func);
2384-
if (!addr)
2385-
goto error;
2386-
if (!kallsyms_lookup_size_offset(addr, &size, NULL))
2387-
goto error;
2388-
addr = ftrace_location_range(addr, addr + size - 1);
2389-
if (!addr)
2390-
goto error;
2391-
addrs[i] = addr;
2392-
}
2393-
2394-
err = 0;
2395-
error:
2396-
kvfree(syms);
2397-
kfree(func);
2398-
return err;
2410+
return strcmp(*str_a, *str_b);
23992411
}
24002412

24012413
int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
@@ -2441,7 +2453,15 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
24412453
goto error;
24422454
}
24432455
} else {
2444-
err = kprobe_multi_resolve_syms(usyms, cnt, addrs);
2456+
struct user_syms us;
2457+
2458+
err = copy_user_syms(&us, usyms, cnt);
2459+
if (err)
2460+
goto error;
2461+
2462+
sort(us.syms, cnt, sizeof(*us.syms), symbols_cmp, NULL);
2463+
err = ftrace_lookup_symbols(us.syms, cnt, addrs);
2464+
free_user_syms(&us);
24452465
if (err)
24462466
goto error;
24472467
}

0 commit comments

Comments
 (0)