perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk

  [root@five ~]# perf bench uprobe all
  # Running uprobe/baseline benchmark...
  # Executed 1,000 usleep(1000) calls
       Total time: 1,053,963 usecs

   1,053.963 usecs/op

  # Running uprobe/empty benchmark...
  # Executed 1,000 usleep(1000) calls
       Total time: 1,056,293 usecs +2,330 to baseline

   1,056.293 usecs/op 2.330 usecs/op to baseline

  # Running uprobe/trace_printk benchmark...
  # Executed 1,000 usleep(1000) calls
       Total time: 1,056,977 usecs +3,014 to baseline +684 to previous

   1,056.977 usecs/op 3.014 usecs/op to baseline 0.684 usecs/op to previous

  [root@five ~]#
Acked-by: default avatarIan Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andre Fredette <anfredet@redhat.com>
Cc: Clark Williams <williams@redhat.com>
Cc: Dave Tucker <datucker@redhat.com>
Cc: Derek Barbosa <debarbos@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/lkml/20230719204910.539044-6-acme@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 6af5e4cf
...@@ -44,6 +44,7 @@ int bench_breakpoint_thread(int argc, const char **argv); ...@@ -44,6 +44,7 @@ int bench_breakpoint_thread(int argc, const char **argv);
int bench_breakpoint_enable(int argc, const char **argv); int bench_breakpoint_enable(int argc, const char **argv);
int bench_uprobe_baseline(int argc, const char **argv); int bench_uprobe_baseline(int argc, const char **argv);
int bench_uprobe_empty(int argc, const char **argv); int bench_uprobe_empty(int argc, const char **argv);
int bench_uprobe_trace_printk(int argc, const char **argv);
int bench_pmu_scan(int argc, const char **argv); int bench_pmu_scan(int argc, const char **argv);
#define BENCH_FORMAT_DEFAULT_STR "default" #define BENCH_FORMAT_DEFAULT_STR "default"
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <subcmd/parse-options.h> #include <subcmd/parse-options.h>
#include "../builtin.h" #include "../builtin.h"
#include "bench.h" #include "bench.h"
#include <linux/compiler.h>
#include <linux/time64.h> #include <linux/time64.h>
#include <inttypes.h> #include <inttypes.h>
...@@ -27,6 +28,7 @@ static int loops = LOOPS_DEFAULT; ...@@ -27,6 +28,7 @@ static int loops = LOOPS_DEFAULT;
enum bench_uprobe { enum bench_uprobe {
BENCH_UPROBE__BASELINE, BENCH_UPROBE__BASELINE,
BENCH_UPROBE__EMPTY, BENCH_UPROBE__EMPTY,
BENCH_UPROBE__TRACE_PRINTK,
}; };
static const struct option options[] = { static const struct option options[] = {
...@@ -42,9 +44,21 @@ static const char * const bench_uprobe_usage[] = { ...@@ -42,9 +44,21 @@ static const char * const bench_uprobe_usage[] = {
#ifdef HAVE_BPF_SKEL #ifdef HAVE_BPF_SKEL
#include "bpf_skel/bench_uprobe.skel.h" #include "bpf_skel/bench_uprobe.skel.h"
#define bench_uprobe__attach_uprobe(prog) \
skel->links.prog = bpf_program__attach_uprobe_opts(/*prog=*/skel->progs.prog, \
/*pid=*/-1, \
/*binary_path=*/"/lib64/libc.so.6", \
/*func_offset=*/0, \
/*opts=*/&uprobe_opts); \
if (!skel->links.prog) { \
err = -errno; \
fprintf(stderr, "Failed to attach bench uprobe \"%s\": %s\n", #prog, strerror(errno)); \
goto cleanup; \
}
struct bench_uprobe_bpf *skel; struct bench_uprobe_bpf *skel;
static int bench_uprobe__setup_bpf_skel(void) static int bench_uprobe__setup_bpf_skel(enum bench_uprobe bench)
{ {
DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts);
int err; int err;
...@@ -63,14 +77,12 @@ static int bench_uprobe__setup_bpf_skel(void) ...@@ -63,14 +77,12 @@ static int bench_uprobe__setup_bpf_skel(void)
} }
uprobe_opts.func_name = "usleep"; uprobe_opts.func_name = "usleep";
skel->links.empty = bpf_program__attach_uprobe_opts(/*prog=*/skel->progs.empty, switch (bench) {
/*pid=*/-1, case BENCH_UPROBE__BASELINE: break;
/*binary_path=*/"/lib64/libc.so.6", case BENCH_UPROBE__EMPTY: bench_uprobe__attach_uprobe(empty); break;
/*func_offset=*/0, case BENCH_UPROBE__TRACE_PRINTK: bench_uprobe__attach_uprobe(trace_printk); break;
/*opts=*/&uprobe_opts); default:
if (!skel->links.empty) { fprintf(stderr, "Invalid bench: %d\n", bench);
err = -errno;
fprintf(stderr, "Failed to attach bench uprobe: %s\n", strerror(errno));
goto cleanup; goto cleanup;
} }
...@@ -88,7 +100,7 @@ static void bench_uprobe__teardown_bpf_skel(void) ...@@ -88,7 +100,7 @@ static void bench_uprobe__teardown_bpf_skel(void)
} }
} }
#else #else
static int bench_uprobe__setup_bpf_skel(void) { return 0; } static int bench_uprobe__setup_bpf_skel(enum bench_uprobe bench __maybe_unused) { return 0; }
static void bench_uprobe__teardown_bpf_skel(void) {}; static void bench_uprobe__teardown_bpf_skel(void) {};
#endif #endif
...@@ -135,7 +147,7 @@ static int bench_uprobe(int argc, const char **argv, enum bench_uprobe bench) ...@@ -135,7 +147,7 @@ static int bench_uprobe(int argc, const char **argv, enum bench_uprobe bench)
argc = parse_options(argc, argv, options, bench_uprobe_usage, 0); argc = parse_options(argc, argv, options, bench_uprobe_usage, 0);
if (bench != BENCH_UPROBE__BASELINE && bench_uprobe__setup_bpf_skel() < 0) if (bench != BENCH_UPROBE__BASELINE && bench_uprobe__setup_bpf_skel(bench) < 0)
return 0; return 0;
clock_gettime(CLOCK_REALTIME, &start); clock_gettime(CLOCK_REALTIME, &start);
...@@ -179,3 +191,8 @@ int bench_uprobe_empty(int argc, const char **argv) ...@@ -179,3 +191,8 @@ int bench_uprobe_empty(int argc, const char **argv)
{ {
return bench_uprobe(argc, argv, BENCH_UPROBE__EMPTY); return bench_uprobe(argc, argv, BENCH_UPROBE__EMPTY);
} }
int bench_uprobe_trace_printk(int argc, const char **argv)
{
return bench_uprobe(argc, argv, BENCH_UPROBE__TRACE_PRINTK);
}
...@@ -107,6 +107,7 @@ static struct bench breakpoint_benchmarks[] = { ...@@ -107,6 +107,7 @@ static struct bench breakpoint_benchmarks[] = {
static struct bench uprobe_benchmarks[] = { static struct bench uprobe_benchmarks[] = {
{ "baseline", "Baseline libc usleep(1000) call", bench_uprobe_baseline, }, { "baseline", "Baseline libc usleep(1000) call", bench_uprobe_baseline, },
{ "empty", "Attach empty BPF prog to uprobe on usleep, system wide", bench_uprobe_empty, }, { "empty", "Attach empty BPF prog to uprobe on usleep, system wide", bench_uprobe_empty, },
{ "trace_printk", "Attach trace_printk BPF prog to uprobe on usleep syswide", bench_uprobe_trace_printk, },
{ NULL, NULL, NULL }, { NULL, NULL, NULL },
}; };
......
...@@ -3,10 +3,21 @@ ...@@ -3,10 +3,21 @@
#include "vmlinux.h" #include "vmlinux.h"
#include <bpf/bpf_tracing.h> #include <bpf/bpf_tracing.h>
unsigned int nr_uprobes;
SEC("uprobe") SEC("uprobe")
int BPF_UPROBE(empty) int BPF_UPROBE(empty)
{ {
return 0; return 0;
} }
SEC("uprobe")
int BPF_UPROBE(trace_printk)
{
char fmt[] = "perf bench uprobe %u";
bpf_trace_printk(fmt, sizeof(fmt), ++nr_uprobes);
return 0;
}
char LICENSE[] SEC("license") = "Dual BSD/GPL"; char LICENSE[] SEC("license") = "Dual BSD/GPL";
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment