Skip to content

Commit f727b13

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
selftests/bpf: add multi-uprobe benchmarks
Add multi-uprobe and multi-uretprobe benchmarks to bench tool. Multi- and classic uprobes/uretprobes have different low-level triggering code paths, so it's sometimes important to be able to benchmark both flavors of uprobes/uretprobes. Sample examples from my dev machine below. Single-threaded peformance almost doesn't differ, but with more parallel CPUs triggering the same uprobe/uretprobe the difference grows. This might be due to [0], but given the code is slightly different, there could be other sources of slowdown. Note, all these numbers will change due to ongoing work to improve uprobe/uretprobe scalability (e.g., [1]), but having benchmark like this is useful for measurements and debugging nevertheless. \#!/bin/bash set -eufo pipefail for p in 1 8 16 32; do for i in uprobe-nop uretprobe-nop uprobe-multi-nop uretprobe-multi-nop; do summary=$(sudo ./bench -w1 -d3 -p$p -a trig-$i | tail -n1) total=$(echo "$summary" | cut -d'(' -f1 | cut -d' ' -f3-) percpu=$(echo "$summary" | cut -d'(' -f2 | cut -d')' -f1 | cut -d'/' -f1) printf "%-21s (%2d cpus): %s (%s/s/cpu)\n" $i $p "$total" "$percpu" done echo done uprobe-nop ( 1 cpus): 1.020 ± 0.005M/s ( 1.020M/s/cpu) uretprobe-nop ( 1 cpus): 0.515 ± 0.009M/s ( 0.515M/s/cpu) uprobe-multi-nop ( 1 cpus): 1.036 ± 0.004M/s ( 1.036M/s/cpu) uretprobe-multi-nop ( 1 cpus): 0.512 ± 0.005M/s ( 0.512M/s/cpu) uprobe-nop ( 8 cpus): 3.481 ± 0.030M/s ( 0.435M/s/cpu) uretprobe-nop ( 8 cpus): 2.222 ± 0.008M/s ( 0.278M/s/cpu) uprobe-multi-nop ( 8 cpus): 3.769 ± 0.094M/s ( 0.471M/s/cpu) uretprobe-multi-nop ( 8 cpus): 2.482 ± 0.007M/s ( 0.310M/s/cpu) uprobe-nop (16 cpus): 2.968 ± 0.011M/s ( 0.185M/s/cpu) uretprobe-nop (16 cpus): 1.870 ± 0.002M/s ( 0.117M/s/cpu) uprobe-multi-nop (16 cpus): 3.541 ± 0.037M/s ( 0.221M/s/cpu) uretprobe-multi-nop (16 cpus): 2.123 ± 0.026M/s ( 0.133M/s/cpu) uprobe-nop (32 cpus): 2.524 ± 0.026M/s ( 0.079M/s/cpu) uretprobe-nop (32 cpus): 1.572 ± 0.003M/s ( 0.049M/s/cpu) uprobe-multi-nop (32 cpus): 2.717 ± 0.003M/s ( 0.085M/s/cpu) uretprobe-multi-nop (32 cpus): 1.687 ± 0.007M/s ( 0.053M/s/cpu) [0] https://lore.kernel.org/linux-trace-kernel/[email protected]/ [1] https://lore.kernel.org/linux-trace-kernel/[email protected]/ Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: Jiri Olsa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 4e9e076 commit f727b13

File tree

3 files changed

+85
-15
lines changed

3 files changed

+85
-15
lines changed

tools/testing/selftests/bpf/bench.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,12 @@ extern const struct bench bench_trig_uprobe_push;
520520
extern const struct bench bench_trig_uretprobe_push;
521521
extern const struct bench bench_trig_uprobe_ret;
522522
extern const struct bench bench_trig_uretprobe_ret;
523+
extern const struct bench bench_trig_uprobe_multi_nop;
524+
extern const struct bench bench_trig_uretprobe_multi_nop;
525+
extern const struct bench bench_trig_uprobe_multi_push;
526+
extern const struct bench bench_trig_uretprobe_multi_push;
527+
extern const struct bench bench_trig_uprobe_multi_ret;
528+
extern const struct bench bench_trig_uretprobe_multi_ret;
523529

524530
extern const struct bench bench_rb_libbpf;
525531
extern const struct bench bench_rb_custom;
@@ -574,6 +580,12 @@ static const struct bench *benchs[] = {
574580
&bench_trig_uretprobe_push,
575581
&bench_trig_uprobe_ret,
576582
&bench_trig_uretprobe_ret,
583+
&bench_trig_uprobe_multi_nop,
584+
&bench_trig_uretprobe_multi_nop,
585+
&bench_trig_uprobe_multi_push,
586+
&bench_trig_uretprobe_multi_push,
587+
&bench_trig_uprobe_multi_ret,
588+
&bench_trig_uretprobe_multi_ret,
577589
/* ringbuf/perfbuf benchmarks */
578590
&bench_rb_libbpf,
579591
&bench_rb_custom,

tools/testing/selftests/bpf/benchs/bench_trigger.c

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ static void *uprobe_producer_ret(void *input)
332332
return NULL;
333333
}
334334

335-
static void usetup(bool use_retprobe, void *target_addr)
335+
static void usetup(bool use_retprobe, bool use_multi, void *target_addr)
336336
{
337337
size_t uprobe_offset;
338338
struct bpf_link *link;
@@ -346,7 +346,10 @@ static void usetup(bool use_retprobe, void *target_addr)
346346
exit(1);
347347
}
348348

349-
bpf_program__set_autoload(ctx.skel->progs.bench_trigger_uprobe, true);
349+
if (use_multi)
350+
bpf_program__set_autoload(ctx.skel->progs.bench_trigger_uprobe_multi, true);
351+
else
352+
bpf_program__set_autoload(ctx.skel->progs.bench_trigger_uprobe, true);
350353

351354
err = trigger_bench__load(ctx.skel);
352355
if (err) {
@@ -355,16 +358,28 @@ static void usetup(bool use_retprobe, void *target_addr)
355358
}
356359

357360
uprobe_offset = get_uprobe_offset(target_addr);
358-
link = bpf_program__attach_uprobe(ctx.skel->progs.bench_trigger_uprobe,
359-
use_retprobe,
360-
-1 /* all PIDs */,
361-
"/proc/self/exe",
362-
uprobe_offset);
361+
if (use_multi) {
362+
LIBBPF_OPTS(bpf_uprobe_multi_opts, opts,
363+
.retprobe = use_retprobe,
364+
.cnt = 1,
365+
.offsets = &uprobe_offset,
366+
);
367+
link = bpf_program__attach_uprobe_multi(
368+
ctx.skel->progs.bench_trigger_uprobe_multi,
369+
-1 /* all PIDs */, "/proc/self/exe", NULL, &opts);
370+
ctx.skel->links.bench_trigger_uprobe_multi = link;
371+
} else {
372+
link = bpf_program__attach_uprobe(ctx.skel->progs.bench_trigger_uprobe,
373+
use_retprobe,
374+
-1 /* all PIDs */,
375+
"/proc/self/exe",
376+
uprobe_offset);
377+
ctx.skel->links.bench_trigger_uprobe = link;
378+
}
363379
if (!link) {
364-
fprintf(stderr, "failed to attach uprobe!\n");
380+
fprintf(stderr, "failed to attach %s!\n", use_multi ? "multi-uprobe" : "uprobe");
365381
exit(1);
366382
}
367-
ctx.skel->links.bench_trigger_uprobe = link;
368383
}
369384

370385
static void usermode_count_setup(void)
@@ -374,32 +389,62 @@ static void usermode_count_setup(void)
374389

375390
static void uprobe_nop_setup(void)
376391
{
377-
usetup(false, &uprobe_target_nop);
392+
usetup(false, false /* !use_multi */, &uprobe_target_nop);
378393
}
379394

380395
static void uretprobe_nop_setup(void)
381396
{
382-
usetup(true, &uprobe_target_nop);
397+
usetup(true, false /* !use_multi */, &uprobe_target_nop);
383398
}
384399

385400
static void uprobe_push_setup(void)
386401
{
387-
usetup(false, &uprobe_target_push);
402+
usetup(false, false /* !use_multi */, &uprobe_target_push);
388403
}
389404

390405
static void uretprobe_push_setup(void)
391406
{
392-
usetup(true, &uprobe_target_push);
407+
usetup(true, false /* !use_multi */, &uprobe_target_push);
393408
}
394409

395410
static void uprobe_ret_setup(void)
396411
{
397-
usetup(false, &uprobe_target_ret);
412+
usetup(false, false /* !use_multi */, &uprobe_target_ret);
398413
}
399414

400415
static void uretprobe_ret_setup(void)
401416
{
402-
usetup(true, &uprobe_target_ret);
417+
usetup(true, false /* !use_multi */, &uprobe_target_ret);
418+
}
419+
420+
static void uprobe_multi_nop_setup(void)
421+
{
422+
usetup(false, true /* use_multi */, &uprobe_target_nop);
423+
}
424+
425+
static void uretprobe_multi_nop_setup(void)
426+
{
427+
usetup(true, true /* use_multi */, &uprobe_target_nop);
428+
}
429+
430+
static void uprobe_multi_push_setup(void)
431+
{
432+
usetup(false, true /* use_multi */, &uprobe_target_push);
433+
}
434+
435+
static void uretprobe_multi_push_setup(void)
436+
{
437+
usetup(true, true /* use_multi */, &uprobe_target_push);
438+
}
439+
440+
static void uprobe_multi_ret_setup(void)
441+
{
442+
usetup(false, true /* use_multi */, &uprobe_target_ret);
443+
}
444+
445+
static void uretprobe_multi_ret_setup(void)
446+
{
447+
usetup(true, true /* use_multi */, &uprobe_target_ret);
403448
}
404449

405450
const struct bench bench_trig_syscall_count = {
@@ -454,3 +499,9 @@ BENCH_TRIG_USERMODE(uprobe_ret, ret, "uprobe-ret");
454499
BENCH_TRIG_USERMODE(uretprobe_nop, nop, "uretprobe-nop");
455500
BENCH_TRIG_USERMODE(uretprobe_push, push, "uretprobe-push");
456501
BENCH_TRIG_USERMODE(uretprobe_ret, ret, "uretprobe-ret");
502+
BENCH_TRIG_USERMODE(uprobe_multi_nop, nop, "uprobe-multi-nop");
503+
BENCH_TRIG_USERMODE(uprobe_multi_push, push, "uprobe-multi-push");
504+
BENCH_TRIG_USERMODE(uprobe_multi_ret, ret, "uprobe-multi-ret");
505+
BENCH_TRIG_USERMODE(uretprobe_multi_nop, nop, "uretprobe-multi-nop");
506+
BENCH_TRIG_USERMODE(uretprobe_multi_push, push, "uretprobe-multi-push");
507+
BENCH_TRIG_USERMODE(uretprobe_multi_ret, ret, "uretprobe-multi-ret");

tools/testing/selftests/bpf/progs/trigger_bench.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ int bench_trigger_uprobe(void *ctx)
3232
return 0;
3333
}
3434

35+
SEC("?uprobe.multi")
36+
int bench_trigger_uprobe_multi(void *ctx)
37+
{
38+
inc_counter();
39+
return 0;
40+
}
41+
3542
const volatile int batch_iters = 0;
3643

3744
SEC("?raw_tp")

0 commit comments

Comments
 (0)