* [PATCHES/RFC 1/5] perf bench uprobe + BPF skel
@ 2023-07-19 20:49 Arnaldo Carvalho de Melo
2023-07-19 20:49 ` [PATCH 1/5] perf bench uprobe: Add benchmark to test uprobe overhead Arnaldo Carvalho de Melo
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-07-19 20:49 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Masami Hiramatsu
Hi,
This adds a 'perf bench' to test the overhead of uprobes + BPF
programs, for now just a few simple tests, but I plan to make it
possible to specify the functions to attach the uprobe + BPF, other BPF
operations dealing with maps, etc.
This is how it looks like now:
[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 ~]
I put it here:
https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/commit/?h=perf-bench-uprobe
git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git perf-bench-uprobe
Further ideas, problems?
- Arnaldo
Arnaldo Carvalho de Melo (5):
perf bench uprobe: Add benchmark to test uprobe overhead
perf bench uprobe: Print diff to baseline
perf bench uprobe: Show diff to previous
perf bench uprobe empty: Add entry attaching an empty BPF program
perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk
tools/perf/Documentation/perf-bench.txt | 3 +
tools/perf/Makefile.perf | 1 +
tools/perf/bench/Build | 1 +
tools/perf/bench/bench.h | 3 +
tools/perf/bench/uprobe.c | 198 ++++++++++++++++++++
tools/perf/builtin-bench.c | 8 +
tools/perf/util/bpf_skel/bench_uprobe.bpf.c | 23 +++
7 files changed, 237 insertions(+)
create mode 100644 tools/perf/bench/uprobe.c
create mode 100644 tools/perf/util/bpf_skel/bench_uprobe.bpf.c
--
2.41.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/5] perf bench uprobe: Add benchmark to test uprobe overhead
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
@ 2023-07-19 20:49 ` Arnaldo Carvalho de Melo
2023-07-21 14:45 ` Masami Hiramatsu
2023-07-19 20:49 ` [PATCH 2/5] perf bench uprobe: Print diff to baseline Arnaldo Carvalho de Melo
` (5 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-07-19 20:49 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
From: Arnaldo Carvalho de Melo <acme@redhat.com>
This just adds the initial "workload", a call to libc's usleep(1000us)
function:
$ perf stat --null perf bench uprobe all
# Running uprobe/baseline benchmark...
# Executed 1000 usleep(1000) calls
Total time: 1053533 usecs
1053.533 usecs/op
Performance counter stats for 'perf bench uprobe all':
1.061042896 seconds time elapsed
0.001079000 seconds user
0.006499000 seconds sys
$
More entries will be added using a BPF skel to add various uprobes to
the usleep() function.
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: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/Documentation/perf-bench.txt | 3 +
tools/perf/bench/Build | 1 +
tools/perf/bench/bench.h | 1 +
tools/perf/bench/uprobe.c | 80 +++++++++++++++++++++++++
tools/perf/builtin-bench.c | 6 ++
5 files changed, 91 insertions(+)
create mode 100644 tools/perf/bench/uprobe.c
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index f04f0eaded985fc8..ca5789625cd2b8e5 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -67,6 +67,9 @@ SUBSYSTEM
'internals'::
Benchmark internal perf functionality.
+'uprobe'::
+ Benchmark overhead of uprobe + BPF.
+
'all'::
All benchmark subsystems.
diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
index 0f158dc8139bbd0d..47412d47dccfeff2 100644
--- a/tools/perf/bench/Build
+++ b/tools/perf/bench/Build
@@ -16,6 +16,7 @@ perf-y += inject-buildid.o
perf-y += evlist-open-close.o
perf-y += breakpoint.o
perf-y += pmu-scan.o
+perf-y += uprobe.o
perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-asm.o
perf-$(CONFIG_X86_64) += mem-memset-x86-64-asm.o
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
index 0d2b65976212333a..201311f75c964df2 100644
--- a/tools/perf/bench/bench.h
+++ b/tools/perf/bench/bench.h
@@ -42,6 +42,7 @@ int bench_inject_build_id(int argc, const char **argv);
int bench_evlist_open_close(int argc, const char **argv);
int bench_breakpoint_thread(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_pmu_scan(int argc, const char **argv);
#define BENCH_FORMAT_DEFAULT_STR "default"
diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
new file mode 100644
index 0000000000000000..707174220a76701f
--- /dev/null
+++ b/tools/perf/bench/uprobe.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * uprobe.c
+ *
+ * uprobe benchmarks
+ *
+ * Copyright (C) 2023, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
+ */
+#include "../perf.h"
+#include "../util/util.h"
+#include <subcmd/parse-options.h>
+#include "../builtin.h"
+#include "bench.h"
+#include <linux/time64.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define LOOPS_DEFAULT 1000
+static int loops = LOOPS_DEFAULT;
+
+static const struct option options[] = {
+ OPT_INTEGER('l', "loop", &loops, "Specify number of loops"),
+ OPT_END()
+};
+
+static const char * const bench_uprobe_usage[] = {
+ "perf bench uprobe <options>",
+ NULL
+};
+
+static int bench_uprobe(int argc, const char **argv)
+{
+ const char *name = "usleep(1000)", *unit = "usec";
+ struct timespec start, end;
+ u64 diff;
+ int i;
+
+ argc = parse_options(argc, argv, options, bench_uprobe_usage, 0);
+
+ clock_gettime(CLOCK_REALTIME, &start);
+
+ for (i = 0; i < loops; i++) {
+ usleep(USEC_PER_MSEC);
+ }
+
+ clock_gettime(CLOCK_REALTIME, &end);
+
+ diff = end.tv_sec * NSEC_PER_SEC + end.tv_nsec - (start.tv_sec * NSEC_PER_SEC + start.tv_nsec);
+ diff /= NSEC_PER_USEC;
+
+ switch (bench_format) {
+ case BENCH_FORMAT_DEFAULT:
+ printf("# Executed %'d %s calls\n", loops, name);
+ printf(" %14s: %'" PRIu64 " %ss\n\n", "Total time", diff, unit);
+ printf(" %'.3f %ss/op\n", (double)diff / (double)loops, unit);
+ break;
+
+ case BENCH_FORMAT_SIMPLE:
+ printf("%" PRIu64 "\n", diff);
+ break;
+
+ default:
+ /* reaching here is something of a disaster */
+ fprintf(stderr, "Unknown format:%d\n", bench_format);
+ exit(1);
+ }
+
+ return 0;
+}
+
+int bench_uprobe_baseline(int argc, const char **argv)
+{
+ return bench_uprobe(argc, argv);
+}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index db435b791a09b69b..09637aee83413e63 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -104,6 +104,11 @@ static struct bench breakpoint_benchmarks[] = {
{ NULL, NULL, NULL },
};
+static struct bench uprobe_benchmarks[] = {
+ { "baseline", "Baseline libc usleep(1000) call", bench_uprobe_baseline, },
+ { NULL, NULL, NULL },
+};
+
struct collection {
const char *name;
const char *summary;
@@ -123,6 +128,7 @@ static struct collection collections[] = {
#endif
{ "internals", "Perf-internals benchmarks", internals_benchmarks },
{ "breakpoint", "Breakpoint benchmarks", breakpoint_benchmarks },
+ { "uprobe", "uprobe benchmarks", uprobe_benchmarks },
{ "all", "All benchmarks", NULL },
{ NULL, NULL, NULL }
};
--
2.41.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/5] perf bench uprobe: Print diff to baseline
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
2023-07-19 20:49 ` [PATCH 1/5] perf bench uprobe: Add benchmark to test uprobe overhead Arnaldo Carvalho de Melo
@ 2023-07-19 20:49 ` Arnaldo Carvalho de Melo
2023-07-21 14:43 ` Masami Hiramatsu
2023-07-19 20:49 ` [PATCH 3/5] perf bench uprobe: Show diff to previous Arnaldo Carvalho de Melo
` (4 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-07-19 20:49 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
From: Arnaldo Carvalho de Melo <acme@redhat.com>
This is just prep work to show the diff to the unmodified workload.
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: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/bench/uprobe.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
index 707174220a76701f..60e7c43298d8cf56 100644
--- a/tools/perf/bench/uprobe.c
+++ b/tools/perf/bench/uprobe.c
@@ -34,6 +34,29 @@ static const char * const bench_uprobe_usage[] = {
NULL
};
+static int bench_uprobe_format__default_fprintf(const char *name, const char *unit, u64 diff, FILE *fp)
+{
+ static u64 baseline;
+ s64 diff_to_baseline = diff - baseline;
+ int printed = fprintf(fp, "# Executed %'d %s calls\n", loops, name);
+
+ printed += fprintf(fp, " %14s: %'" PRIu64 " %ss", "Total time", diff, unit);
+
+ if (baseline)
+ printed += fprintf(fp, " %s%'" PRId64 " to baseline", diff_to_baseline > 0 ? "+" : "", diff_to_baseline);
+
+ printed += fprintf(fp, "\n\n %'.3f %ss/op", (double)diff / (double)loops, unit);
+
+ if (baseline)
+ printed += fprintf(fp, " %'.3f %ss/op to baseline", (double)diff_to_baseline / (double)loops, unit);
+ else
+ baseline = diff;
+
+ fputc('\n', fp);
+
+ return printed + 1;
+}
+
static int bench_uprobe(int argc, const char **argv)
{
const char *name = "usleep(1000)", *unit = "usec";
@@ -56,9 +79,7 @@ static int bench_uprobe(int argc, const char **argv)
switch (bench_format) {
case BENCH_FORMAT_DEFAULT:
- printf("# Executed %'d %s calls\n", loops, name);
- printf(" %14s: %'" PRIu64 " %ss\n\n", "Total time", diff, unit);
- printf(" %'.3f %ss/op\n", (double)diff / (double)loops, unit);
+ bench_uprobe_format__default_fprintf(name, unit, diff, stdout);
break;
case BENCH_FORMAT_SIMPLE:
--
2.41.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/5] perf bench uprobe: Show diff to previous
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
2023-07-19 20:49 ` [PATCH 1/5] perf bench uprobe: Add benchmark to test uprobe overhead Arnaldo Carvalho de Melo
2023-07-19 20:49 ` [PATCH 2/5] perf bench uprobe: Print diff to baseline Arnaldo Carvalho de Melo
@ 2023-07-19 20:49 ` Arnaldo Carvalho de Melo
2023-07-21 14:48 ` Masami Hiramatsu
2023-07-19 20:49 ` [PATCH 4/5] perf bench uprobe empty: Add entry attaching an empty BPF program Arnaldo Carvalho de Melo
` (3 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-07-19 20:49 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Will be useful to show the incremental overhead as we do more stuff in
the BPF program attached to the uprobes.
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: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/bench/uprobe.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
index 60e7c43298d8cf56..a90e09f791c540a9 100644
--- a/tools/perf/bench/uprobe.c
+++ b/tools/perf/bench/uprobe.c
@@ -36,24 +36,35 @@ static const char * const bench_uprobe_usage[] = {
static int bench_uprobe_format__default_fprintf(const char *name, const char *unit, u64 diff, FILE *fp)
{
- static u64 baseline;
- s64 diff_to_baseline = diff - baseline;
+ static u64 baseline, previous;
+ s64 diff_to_baseline = diff - baseline,
+ diff_to_previous = diff - previous;
int printed = fprintf(fp, "# Executed %'d %s calls\n", loops, name);
printed += fprintf(fp, " %14s: %'" PRIu64 " %ss", "Total time", diff, unit);
- if (baseline)
+ if (baseline) {
printed += fprintf(fp, " %s%'" PRId64 " to baseline", diff_to_baseline > 0 ? "+" : "", diff_to_baseline);
+ if (previous != baseline)
+ fprintf(stdout, " %s%'" PRId64 " to previous", diff_to_previous > 0 ? "+" : "", diff_to_previous);
+ }
+
printed += fprintf(fp, "\n\n %'.3f %ss/op", (double)diff / (double)loops, unit);
- if (baseline)
+ if (baseline) {
printed += fprintf(fp, " %'.3f %ss/op to baseline", (double)diff_to_baseline / (double)loops, unit);
- else
+
+ if (previous != baseline)
+ printed += fprintf(fp, " %'.3f %ss/op to previous", (double)diff_to_previous / (double)loops, unit);
+ } else {
baseline = diff;
+ }
fputc('\n', fp);
+ previous = diff;
+
return printed + 1;
}
--
2.41.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] perf bench uprobe empty: Add entry attaching an empty BPF program
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
` (2 preceding siblings ...)
2023-07-19 20:49 ` [PATCH 3/5] perf bench uprobe: Show diff to previous Arnaldo Carvalho de Melo
@ 2023-07-19 20:49 ` Arnaldo Carvalho de Melo
2023-07-19 20:49 ` [PATCH 5/5] perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk Arnaldo Carvalho de Melo
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-07-19 20:49 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Using libbpf and a BPF skel:
# perf bench uprobe all
# Running uprobe/baseline benchmark...
# Executed 1,000 usleep(1000) calls
Total time: 1,055,618 usecs
1,055.618 usecs/op
# Running uprobe/empty benchmark...
# Executed 1,000 usleep(1000) calls
Total time: 1,057,146 usecs +1,528 to baseline
1,057.146 usecs/op
#
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: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/Makefile.perf | 1 +
tools/perf/bench/bench.h | 1 +
tools/perf/bench/uprobe.c | 75 ++++++++++++++++++++-
tools/perf/builtin-bench.c | 3 +-
tools/perf/util/bpf_skel/bench_uprobe.bpf.c | 12 ++++
5 files changed, 88 insertions(+), 4 deletions(-)
create mode 100644 tools/perf/util/bpf_skel/bench_uprobe.bpf.c
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 097316ef38e6a80f..a44d16ec11ee5490 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -1057,6 +1057,7 @@ SKELETONS += $(SKEL_OUT)/bperf_leader.skel.h $(SKEL_OUT)/bperf_follower.skel.h
SKELETONS += $(SKEL_OUT)/bperf_cgroup.skel.h $(SKEL_OUT)/func_latency.skel.h
SKELETONS += $(SKEL_OUT)/off_cpu.skel.h $(SKEL_OUT)/lock_contention.skel.h
SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h $(SKEL_OUT)/sample_filter.skel.h
+SKELETONS += $(SKEL_OUT)/bench_uprobe.skel.h
$(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT):
$(Q)$(MKDIR) -p $@
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
index 201311f75c964df2..daf4850b441cf91c 100644
--- a/tools/perf/bench/bench.h
+++ b/tools/perf/bench/bench.h
@@ -43,6 +43,7 @@ int bench_evlist_open_close(int argc, const char **argv);
int bench_breakpoint_thread(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_empty(int argc, const char **argv);
int bench_pmu_scan(int argc, const char **argv);
#define BENCH_FORMAT_DEFAULT_STR "default"
diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
index a90e09f791c540a9..dfb90038a4f7a06a 100644
--- a/tools/perf/bench/uprobe.c
+++ b/tools/perf/bench/uprobe.c
@@ -24,6 +24,11 @@
#define LOOPS_DEFAULT 1000
static int loops = LOOPS_DEFAULT;
+enum bench_uprobe {
+ BENCH_UPROBE__BASELINE,
+ BENCH_UPROBE__EMPTY,
+};
+
static const struct option options[] = {
OPT_INTEGER('l', "loop", &loops, "Specify number of loops"),
OPT_END()
@@ -34,6 +39,59 @@ static const char * const bench_uprobe_usage[] = {
NULL
};
+#ifdef HAVE_BPF_SKEL
+#include "bpf_skel/bench_uprobe.skel.h"
+
+struct bench_uprobe_bpf *skel;
+
+static int bench_uprobe__setup_bpf_skel(void)
+{
+ DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts);
+ int err;
+
+ /* Load and verify BPF application */
+ skel = bench_uprobe_bpf__open();
+ if (!skel) {
+ fprintf(stderr, "Failed to open and load uprobes bench BPF skeleton\n");
+ return -1;
+ }
+
+ err = bench_uprobe_bpf__load(skel);
+ if (err) {
+ fprintf(stderr, "Failed to load and verify BPF skeleton\n");
+ goto cleanup;
+ }
+
+ uprobe_opts.func_name = "usleep";
+ skel->links.empty = bpf_program__attach_uprobe_opts(/*prog=*/skel->progs.empty,
+ /*pid=*/-1,
+ /*binary_path=*/"/lib64/libc.so.6",
+ /*func_offset=*/0,
+ /*opts=*/&uprobe_opts);
+ if (!skel->links.empty) {
+ err = -errno;
+ fprintf(stderr, "Failed to attach bench uprobe: %s\n", strerror(errno));
+ goto cleanup;
+ }
+
+ return err;
+cleanup:
+ bench_uprobe_bpf__destroy(skel);
+ return err;
+}
+
+static void bench_uprobe__teardown_bpf_skel(void)
+{
+ if (skel) {
+ bench_uprobe_bpf__destroy(skel);
+ skel = NULL;
+ }
+}
+#else
+static int bench_uprobe__setup_bpf_skel(void) { return 0; }
+static void bench_uprobe__teardown_bpf_skel(void) {};
+#endif
+
static int bench_uprobe_format__default_fprintf(const char *name, const char *unit, u64 diff, FILE *fp)
{
static u64 baseline, previous;
@@ -68,7 +126,7 @@ static int bench_uprobe_format__default_fprintf(const char *name, const char *un
return printed + 1;
}
-static int bench_uprobe(int argc, const char **argv)
+static int bench_uprobe(int argc, const char **argv, enum bench_uprobe bench)
{
const char *name = "usleep(1000)", *unit = "usec";
struct timespec start, end;
@@ -77,7 +135,10 @@ static int bench_uprobe(int argc, const char **argv)
argc = parse_options(argc, argv, options, bench_uprobe_usage, 0);
- clock_gettime(CLOCK_REALTIME, &start);
+ if (bench != BENCH_UPROBE__BASELINE && bench_uprobe__setup_bpf_skel() < 0)
+ return 0;
+
+ clock_gettime(CLOCK_REALTIME, &start);
for (i = 0; i < loops; i++) {
usleep(USEC_PER_MSEC);
@@ -103,10 +164,18 @@ static int bench_uprobe(int argc, const char **argv)
exit(1);
}
+ if (bench != BENCH_UPROBE__BASELINE)
+ bench_uprobe__teardown_bpf_skel();
+
return 0;
}
int bench_uprobe_baseline(int argc, const char **argv)
{
- return bench_uprobe(argc, argv);
+ return bench_uprobe(argc, argv, BENCH_UPROBE__BASELINE);
+}
+
+int bench_uprobe_empty(int argc, const char **argv)
+{
+ return bench_uprobe(argc, argv, BENCH_UPROBE__EMPTY);
}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index 09637aee83413e63..1021680bbc6d4298 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -105,7 +105,8 @@ static struct bench breakpoint_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, },
{ NULL, NULL, NULL },
};
diff --git a/tools/perf/util/bpf_skel/bench_uprobe.bpf.c b/tools/perf/util/bpf_skel/bench_uprobe.bpf.c
new file mode 100644
index 0000000000000000..1365dcc5dddff546
--- /dev/null
+++ b/tools/perf/util/bpf_skel/bench_uprobe.bpf.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+// Copyright (c) 2023 Red Hat
+#include "vmlinux.h"
+#include <bpf/bpf_tracing.h>
+
+SEC("uprobe")
+int BPF_UPROBE(empty)
+{
+ return 0;
+}
+
+char LICENSE[] SEC("license") = "Dual BSD/GPL";
--
2.41.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/5] perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
` (3 preceding siblings ...)
2023-07-19 20:49 ` [PATCH 4/5] perf bench uprobe empty: Add entry attaching an empty BPF program Arnaldo Carvalho de Melo
@ 2023-07-19 20:49 ` Arnaldo Carvalho de Melo
2023-07-19 22:41 ` [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Ian Rogers
2023-07-21 14:32 ` Masami Hiramatsu
6 siblings, 0 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-07-19 20:49 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
From: Arnaldo Carvalho de Melo <acme@redhat.com>
[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 ~]#
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: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/bench/bench.h | 1 +
tools/perf/bench/uprobe.c | 39 +++++++++++++++------
tools/perf/builtin-bench.c | 1 +
tools/perf/util/bpf_skel/bench_uprobe.bpf.c | 11 ++++++
4 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
index daf4850b441cf91c..50de4773651f9914 100644
--- a/tools/perf/bench/bench.h
+++ b/tools/perf/bench/bench.h
@@ -44,6 +44,7 @@ int bench_breakpoint_thread(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_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);
#define BENCH_FORMAT_DEFAULT_STR "default"
diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
index dfb90038a4f7a06a..914c0817fe8ad31b 100644
--- a/tools/perf/bench/uprobe.c
+++ b/tools/perf/bench/uprobe.c
@@ -11,6 +11,7 @@
#include <subcmd/parse-options.h>
#include "../builtin.h"
#include "bench.h"
+#include <linux/compiler.h>
#include <linux/time64.h>
#include <inttypes.h>
@@ -27,6 +28,7 @@ static int loops = LOOPS_DEFAULT;
enum bench_uprobe {
BENCH_UPROBE__BASELINE,
BENCH_UPROBE__EMPTY,
+ BENCH_UPROBE__TRACE_PRINTK,
};
static const struct option options[] = {
@@ -42,9 +44,21 @@ static const char * const bench_uprobe_usage[] = {
#ifdef HAVE_BPF_SKEL
#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;
-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);
int err;
@@ -63,14 +77,12 @@ static int bench_uprobe__setup_bpf_skel(void)
}
uprobe_opts.func_name = "usleep";
- skel->links.empty = bpf_program__attach_uprobe_opts(/*prog=*/skel->progs.empty,
- /*pid=*/-1,
- /*binary_path=*/"/lib64/libc.so.6",
- /*func_offset=*/0,
- /*opts=*/&uprobe_opts);
- if (!skel->links.empty) {
- err = -errno;
- fprintf(stderr, "Failed to attach bench uprobe: %s\n", strerror(errno));
+ switch (bench) {
+ case BENCH_UPROBE__BASELINE: break;
+ case BENCH_UPROBE__EMPTY: bench_uprobe__attach_uprobe(empty); break;
+ case BENCH_UPROBE__TRACE_PRINTK: bench_uprobe__attach_uprobe(trace_printk); break;
+ default:
+ fprintf(stderr, "Invalid bench: %d\n", bench);
goto cleanup;
}
@@ -88,7 +100,7 @@ static void bench_uprobe__teardown_bpf_skel(void)
}
}
#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) {};
#endif
@@ -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);
- 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;
clock_gettime(CLOCK_REALTIME, &start);
@@ -179,3 +191,8 @@ int bench_uprobe_empty(int argc, const char **argv)
{
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);
+}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index 1021680bbc6d4298..f60ccafccac25602 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -107,6 +107,7 @@ static struct bench breakpoint_benchmarks[] = {
static struct bench uprobe_benchmarks[] = {
{ "baseline", "Baseline libc usleep(1000) call", bench_uprobe_baseline, },
{ "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 },
};
diff --git a/tools/perf/util/bpf_skel/bench_uprobe.bpf.c b/tools/perf/util/bpf_skel/bench_uprobe.bpf.c
index 1365dcc5dddff546..7046bea5da871627 100644
--- a/tools/perf/util/bpf_skel/bench_uprobe.bpf.c
+++ b/tools/perf/util/bpf_skel/bench_uprobe.bpf.c
@@ -3,10 +3,21 @@
#include "vmlinux.h"
#include <bpf/bpf_tracing.h>
+unsigned int nr_uprobes;
+
SEC("uprobe")
int BPF_UPROBE(empty)
{
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";
--
2.41.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCHES/RFC 1/5] perf bench uprobe + BPF skel
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
` (4 preceding siblings ...)
2023-07-19 20:49 ` [PATCH 5/5] perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk Arnaldo Carvalho de Melo
@ 2023-07-19 22:41 ` Ian Rogers
2023-07-20 13:56 ` Arnaldo Carvalho de Melo
2023-07-21 14:32 ` Masami Hiramatsu
6 siblings, 1 reply; 12+ messages in thread
From: Ian Rogers @ 2023-07-19 22:41 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, Jiri Olsa,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Masami Hiramatsu
On Wed, Jul 19, 2023 at 1:49 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> Hi,
>
> This adds a 'perf bench' to test the overhead of uprobes + BPF
> programs, for now just a few simple tests, but I plan to make it
> possible to specify the functions to attach the uprobe + BPF, other BPF
> operations dealing with maps, etc.
>
> This is how it looks like now:
>
> [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 ~]
>
> I put it here:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/commit/?h=perf-bench-uprobe
>
> git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git perf-bench-uprobe
>
> Further ideas, problems?
No problems. Perhaps it would be interesting to measure the uprobe
overhead compared to say the overhead attaching to the nanosleep
syscall?
Thanks,
Ian
> - Arnaldo
>
>
>
> Arnaldo Carvalho de Melo (5):
> perf bench uprobe: Add benchmark to test uprobe overhead
> perf bench uprobe: Print diff to baseline
> perf bench uprobe: Show diff to previous
> perf bench uprobe empty: Add entry attaching an empty BPF program
> perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk
>
> tools/perf/Documentation/perf-bench.txt | 3 +
> tools/perf/Makefile.perf | 1 +
> tools/perf/bench/Build | 1 +
> tools/perf/bench/bench.h | 3 +
> tools/perf/bench/uprobe.c | 198 ++++++++++++++++++++
> tools/perf/builtin-bench.c | 8 +
> tools/perf/util/bpf_skel/bench_uprobe.bpf.c | 23 +++
> 7 files changed, 237 insertions(+)
> create mode 100644 tools/perf/bench/uprobe.c
> create mode 100644 tools/perf/util/bpf_skel/bench_uprobe.bpf.c
>
> --
> 2.41.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCHES/RFC 1/5] perf bench uprobe + BPF skel
2023-07-19 22:41 ` [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Ian Rogers
@ 2023-07-20 13:56 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 12+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-07-20 13:56 UTC (permalink / raw)
To: Ian Rogers
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, Jiri Olsa,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Masami Hiramatsu
Em Wed, Jul 19, 2023 at 03:41:54PM -0700, Ian Rogers escreveu:
> On Wed, Jul 19, 2023 at 1:49 PM Arnaldo Carvalho de Melo
> <acme@kernel.org> wrote:
> >
> > Hi,
> >
> > This adds a 'perf bench' to test the overhead of uprobes + BPF
> > programs, for now just a few simple tests, but I plan to make it
> > possible to specify the functions to attach the uprobe + BPF, other BPF
> > operations dealing with maps, etc.
> >
> > This is how it looks like now:
> >
> > [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 ~]
> >
> > I put it here:
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/commit/?h=perf-bench-uprobe
> >
> > git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git perf-bench-uprobe
> >
> > Further ideas, problems?
>
> No problems. Perhaps it would be interesting to measure the uprobe
> overhead compared to say the overhead attaching to the nanosleep
> syscall?
Can you rephrase your question?
The test is comparing the overhead attaching to the clock_nanosleep
syscall:
[root@five ~]# strace -c ~/bin/perf bench uprobe baseline
# Running 'uprobe/baseline' benchmark:
# Executed 1,000 usleep(1000) calls
Total time: 1,077,139 usecs
1,077.139 usecs/op
==7056==LeakSanitizer has encountered a fatal error.
==7056==HINT: For debugging, try setting environment variable LSAN_OPTIONS=verbosity=1:log_threads=1
==7056==HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ------------------
52.87 0.002973 2 1000 clock_nanosleep
22.55 0.001268 3 370 mmap
8.87 0.000499 4 106 read
5.42 0.000305 4 62 munmap
2.42 0.000136 3 38 openat
1.69 0.000095 1 48 mprotect
1.28 0.000072 1 57 close
1.19 0.000067 3 18 open
0.98 0.000055 1 40 1 newfstatat
0.44 0.000025 0 30 pread64
0.44 0.000025 6 4 getdents64
0.32 0.000018 18 1 readlink
0.28 0.000016 2 8 write
0.23 0.000013 1 9 4 prctl
0.21 0.000012 6 2 2 access
0.12 0.000007 0 8 madvise
0.11 0.000006 1 4 clock_gettime
0.11 0.000006 1 4 prlimit64
0.07 0.000004 1 3 rt_sigaction
0.07 0.000004 1 4 sigaltstack
0.07 0.000004 4 1 sched_getaffinity
0.05 0.000003 0 6 getpid
0.04 0.000002 0 3 rt_sigprocmask
0.04 0.000002 1 2 1 arch_prctl
0.04 0.000002 1 2 futex
0.04 0.000002 2 1 set_robust_list
0.02 0.000001 1 1 set_tid_address
0.02 0.000001 1 1 rseq
0.00 0.000000 0 1 brk
0.00 0.000000 0 14 sched_yield
0.00 0.000000 0 1 clone
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 wait4
0.00 0.000000 0 1 gettid
------ ----------- ----------- --------- --------- ------------------
100.00 0.005623 3 1852 8 total
[root@five ~]#
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCHES/RFC 1/5] perf bench uprobe + BPF skel
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
` (5 preceding siblings ...)
2023-07-19 22:41 ` [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Ian Rogers
@ 2023-07-21 14:32 ` Masami Hiramatsu
6 siblings, 0 replies; 12+ messages in thread
From: Masami Hiramatsu @ 2023-07-21 14:32 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Masami Hiramatsu
On Wed, 19 Jul 2023 17:49:05 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> Hi,
>
> This adds a 'perf bench' to test the overhead of uprobes + BPF
> programs, for now just a few simple tests, but I plan to make it
> possible to specify the functions to attach the uprobe + BPF, other BPF
> operations dealing with maps, etc.
>
> This is how it looks like now:
>
> [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 ~]
Looks great! maybe we can also make kprobes benchmark too (but it depends
on optimization and ftrace-based...)
Thank you,
>
> I put it here:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/commit/?h=perf-bench-uprobe
>
> git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git perf-bench-uprobe
>
> Further ideas, problems?
>
> - Arnaldo
>
>
>
> Arnaldo Carvalho de Melo (5):
> perf bench uprobe: Add benchmark to test uprobe overhead
> perf bench uprobe: Print diff to baseline
> perf bench uprobe: Show diff to previous
> perf bench uprobe empty: Add entry attaching an empty BPF program
> perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk
>
> tools/perf/Documentation/perf-bench.txt | 3 +
> tools/perf/Makefile.perf | 1 +
> tools/perf/bench/Build | 1 +
> tools/perf/bench/bench.h | 3 +
> tools/perf/bench/uprobe.c | 198 ++++++++++++++++++++
> tools/perf/builtin-bench.c | 8 +
> tools/perf/util/bpf_skel/bench_uprobe.bpf.c | 23 +++
> 7 files changed, 237 insertions(+)
> create mode 100644 tools/perf/bench/uprobe.c
> create mode 100644 tools/perf/util/bpf_skel/bench_uprobe.bpf.c
>
> --
> 2.41.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/5] perf bench uprobe: Print diff to baseline
2023-07-19 20:49 ` [PATCH 2/5] perf bench uprobe: Print diff to baseline Arnaldo Carvalho de Melo
@ 2023-07-21 14:43 ` Masami Hiramatsu
0 siblings, 0 replies; 12+ messages in thread
From: Masami Hiramatsu @ 2023-07-21 14:43 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
On Wed, 19 Jul 2023 17:49:07 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> This is just prep work to show the diff to the unmodified workload.
Looks good to me, just one comment below.
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
> 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: Ian Rogers <irogers@google.com>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> tools/perf/bench/uprobe.c | 27 ++++++++++++++++++++++++---
> 1 file changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
> index 707174220a76701f..60e7c43298d8cf56 100644
> --- a/tools/perf/bench/uprobe.c
> +++ b/tools/perf/bench/uprobe.c
> @@ -34,6 +34,29 @@ static const char * const bench_uprobe_usage[] = {
> NULL
> };
>
> +static int bench_uprobe_format__default_fprintf(const char *name, const char *unit, u64 diff, FILE *fp)
> +{
> + static u64 baseline;
> + s64 diff_to_baseline = diff - baseline;
> + int printed = fprintf(fp, "# Executed %'d %s calls\n", loops, name);
> +
> + printed += fprintf(fp, " %14s: %'" PRIu64 " %ss", "Total time", diff, unit);
> +
> + if (baseline)
> + printed += fprintf(fp, " %s%'" PRId64 " to baseline", diff_to_baseline > 0 ? "+" : "", diff_to_baseline);
> +
> + printed += fprintf(fp, "\n\n %'.3f %ss/op", (double)diff / (double)loops, unit);
Just a nit, do we need to repeat (double) cast on the denominator side too?
> +
> + if (baseline)
> + printed += fprintf(fp, " %'.3f %ss/op to baseline", (double)diff_to_baseline / (double)loops, unit);
> + else
> + baseline = diff;
> +
> + fputc('\n', fp);
> +
> + return printed + 1;
> +}
> +
> static int bench_uprobe(int argc, const char **argv)
> {
> const char *name = "usleep(1000)", *unit = "usec";
> @@ -56,9 +79,7 @@ static int bench_uprobe(int argc, const char **argv)
>
> switch (bench_format) {
> case BENCH_FORMAT_DEFAULT:
> - printf("# Executed %'d %s calls\n", loops, name);
> - printf(" %14s: %'" PRIu64 " %ss\n\n", "Total time", diff, unit);
> - printf(" %'.3f %ss/op\n", (double)diff / (double)loops, unit);
> + bench_uprobe_format__default_fprintf(name, unit, diff, stdout);
> break;
>
> case BENCH_FORMAT_SIMPLE:
> --
> 2.41.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/5] perf bench uprobe: Add benchmark to test uprobe overhead
2023-07-19 20:49 ` [PATCH 1/5] perf bench uprobe: Add benchmark to test uprobe overhead Arnaldo Carvalho de Melo
@ 2023-07-21 14:45 ` Masami Hiramatsu
0 siblings, 0 replies; 12+ messages in thread
From: Masami Hiramatsu @ 2023-07-21 14:45 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
On Wed, 19 Jul 2023 17:49:06 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> This just adds the initial "workload", a call to libc's usleep(1000us)
> function:
>
> $ perf stat --null perf bench uprobe all
> # Running uprobe/baseline benchmark...
> # Executed 1000 usleep(1000) calls
> Total time: 1053533 usecs
>
> 1053.533 usecs/op
>
> Performance counter stats for 'perf bench uprobe all':
>
> 1.061042896 seconds time elapsed
>
> 0.001079000 seconds user
> 0.006499000 seconds sys
>
> $
>
> More entries will be added using a BPF skel to add various uprobes to
> the usleep() function.
Looks good to me.
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Thanks,
>
> 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: Ian Rogers <irogers@google.com>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> tools/perf/Documentation/perf-bench.txt | 3 +
> tools/perf/bench/Build | 1 +
> tools/perf/bench/bench.h | 1 +
> tools/perf/bench/uprobe.c | 80 +++++++++++++++++++++++++
> tools/perf/builtin-bench.c | 6 ++
> 5 files changed, 91 insertions(+)
> create mode 100644 tools/perf/bench/uprobe.c
>
> diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
> index f04f0eaded985fc8..ca5789625cd2b8e5 100644
> --- a/tools/perf/Documentation/perf-bench.txt
> +++ b/tools/perf/Documentation/perf-bench.txt
> @@ -67,6 +67,9 @@ SUBSYSTEM
> 'internals'::
> Benchmark internal perf functionality.
>
> +'uprobe'::
> + Benchmark overhead of uprobe + BPF.
> +
> 'all'::
> All benchmark subsystems.
>
> diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
> index 0f158dc8139bbd0d..47412d47dccfeff2 100644
> --- a/tools/perf/bench/Build
> +++ b/tools/perf/bench/Build
> @@ -16,6 +16,7 @@ perf-y += inject-buildid.o
> perf-y += evlist-open-close.o
> perf-y += breakpoint.o
> perf-y += pmu-scan.o
> +perf-y += uprobe.o
>
> perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-asm.o
> perf-$(CONFIG_X86_64) += mem-memset-x86-64-asm.o
> diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
> index 0d2b65976212333a..201311f75c964df2 100644
> --- a/tools/perf/bench/bench.h
> +++ b/tools/perf/bench/bench.h
> @@ -42,6 +42,7 @@ int bench_inject_build_id(int argc, const char **argv);
> int bench_evlist_open_close(int argc, const char **argv);
> int bench_breakpoint_thread(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_pmu_scan(int argc, const char **argv);
>
> #define BENCH_FORMAT_DEFAULT_STR "default"
> diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
> new file mode 100644
> index 0000000000000000..707174220a76701f
> --- /dev/null
> +++ b/tools/perf/bench/uprobe.c
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * uprobe.c
> + *
> + * uprobe benchmarks
> + *
> + * Copyright (C) 2023, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
> + */
> +#include "../perf.h"
> +#include "../util/util.h"
> +#include <subcmd/parse-options.h>
> +#include "../builtin.h"
> +#include "bench.h"
> +#include <linux/time64.h>
> +
> +#include <inttypes.h>
> +#include <stdio.h>
> +#include <sys/time.h>
> +#include <sys/types.h>
> +#include <time.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +
> +#define LOOPS_DEFAULT 1000
> +static int loops = LOOPS_DEFAULT;
> +
> +static const struct option options[] = {
> + OPT_INTEGER('l', "loop", &loops, "Specify number of loops"),
> + OPT_END()
> +};
> +
> +static const char * const bench_uprobe_usage[] = {
> + "perf bench uprobe <options>",
> + NULL
> +};
> +
> +static int bench_uprobe(int argc, const char **argv)
> +{
> + const char *name = "usleep(1000)", *unit = "usec";
> + struct timespec start, end;
> + u64 diff;
> + int i;
> +
> + argc = parse_options(argc, argv, options, bench_uprobe_usage, 0);
> +
> + clock_gettime(CLOCK_REALTIME, &start);
> +
> + for (i = 0; i < loops; i++) {
> + usleep(USEC_PER_MSEC);
> + }
> +
> + clock_gettime(CLOCK_REALTIME, &end);
> +
> + diff = end.tv_sec * NSEC_PER_SEC + end.tv_nsec - (start.tv_sec * NSEC_PER_SEC + start.tv_nsec);
> + diff /= NSEC_PER_USEC;
> +
> + switch (bench_format) {
> + case BENCH_FORMAT_DEFAULT:
> + printf("# Executed %'d %s calls\n", loops, name);
> + printf(" %14s: %'" PRIu64 " %ss\n\n", "Total time", diff, unit);
> + printf(" %'.3f %ss/op\n", (double)diff / (double)loops, unit);
> + break;
> +
> + case BENCH_FORMAT_SIMPLE:
> + printf("%" PRIu64 "\n", diff);
> + break;
> +
> + default:
> + /* reaching here is something of a disaster */
> + fprintf(stderr, "Unknown format:%d\n", bench_format);
> + exit(1);
> + }
> +
> + return 0;
> +}
> +
> +int bench_uprobe_baseline(int argc, const char **argv)
> +{
> + return bench_uprobe(argc, argv);
> +}
> diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
> index db435b791a09b69b..09637aee83413e63 100644
> --- a/tools/perf/builtin-bench.c
> +++ b/tools/perf/builtin-bench.c
> @@ -104,6 +104,11 @@ static struct bench breakpoint_benchmarks[] = {
> { NULL, NULL, NULL },
> };
>
> +static struct bench uprobe_benchmarks[] = {
> + { "baseline", "Baseline libc usleep(1000) call", bench_uprobe_baseline, },
> + { NULL, NULL, NULL },
> +};
> +
> struct collection {
> const char *name;
> const char *summary;
> @@ -123,6 +128,7 @@ static struct collection collections[] = {
> #endif
> { "internals", "Perf-internals benchmarks", internals_benchmarks },
> { "breakpoint", "Breakpoint benchmarks", breakpoint_benchmarks },
> + { "uprobe", "uprobe benchmarks", uprobe_benchmarks },
> { "all", "All benchmarks", NULL },
> { NULL, NULL, NULL }
> };
> --
> 2.41.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/5] perf bench uprobe: Show diff to previous
2023-07-19 20:49 ` [PATCH 3/5] perf bench uprobe: Show diff to previous Arnaldo Carvalho de Melo
@ 2023-07-21 14:48 ` Masami Hiramatsu
0 siblings, 0 replies; 12+ messages in thread
From: Masami Hiramatsu @ 2023-07-21 14:48 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Namhyung Kim, Ingo Molnar, Thomas Gleixner, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, Kate Carcia, linux-kernel,
linux-perf-users, Arnaldo Carvalho de Melo, Andre Fredette,
Dave Tucker, Derek Barbosa, Masami Hiramatsu
On Wed, 19 Jul 2023 17:49:08 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> Will be useful to show the incremental overhead as we do more stuff in
> the BPF program attached to the uprobes.
Looks good to me.
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
BTW, bench_uprobe_format__default_fprintf() looks like generic for micro benchmarks.
Can it be shared with other benchmarks?
Thank you,
>
> 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: Ian Rogers <irogers@google.com>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> tools/perf/bench/uprobe.c | 21 ++++++++++++++++-----
> 1 file changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c
> index 60e7c43298d8cf56..a90e09f791c540a9 100644
> --- a/tools/perf/bench/uprobe.c
> +++ b/tools/perf/bench/uprobe.c
> @@ -36,24 +36,35 @@ static const char * const bench_uprobe_usage[] = {
>
> static int bench_uprobe_format__default_fprintf(const char *name, const char *unit, u64 diff, FILE *fp)
> {
> - static u64 baseline;
> - s64 diff_to_baseline = diff - baseline;
> + static u64 baseline, previous;
> + s64 diff_to_baseline = diff - baseline,
> + diff_to_previous = diff - previous;
> int printed = fprintf(fp, "# Executed %'d %s calls\n", loops, name);
>
> printed += fprintf(fp, " %14s: %'" PRIu64 " %ss", "Total time", diff, unit);
>
> - if (baseline)
> + if (baseline) {
> printed += fprintf(fp, " %s%'" PRId64 " to baseline", diff_to_baseline > 0 ? "+" : "", diff_to_baseline);
>
> + if (previous != baseline)
> + fprintf(stdout, " %s%'" PRId64 " to previous", diff_to_previous > 0 ? "+" : "", diff_to_previous);
> + }
> +
> printed += fprintf(fp, "\n\n %'.3f %ss/op", (double)diff / (double)loops, unit);
>
> - if (baseline)
> + if (baseline) {
> printed += fprintf(fp, " %'.3f %ss/op to baseline", (double)diff_to_baseline / (double)loops, unit);
> - else
> +
> + if (previous != baseline)
> + printed += fprintf(fp, " %'.3f %ss/op to previous", (double)diff_to_previous / (double)loops, unit);
> + } else {
> baseline = diff;
> + }
>
> fputc('\n', fp);
>
> + previous = diff;
> +
> return printed + 1;
> }
>
> --
> 2.41.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2023-07-21 14:48 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-19 20:49 [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Arnaldo Carvalho de Melo
2023-07-19 20:49 ` [PATCH 1/5] perf bench uprobe: Add benchmark to test uprobe overhead Arnaldo Carvalho de Melo
2023-07-21 14:45 ` Masami Hiramatsu
2023-07-19 20:49 ` [PATCH 2/5] perf bench uprobe: Print diff to baseline Arnaldo Carvalho de Melo
2023-07-21 14:43 ` Masami Hiramatsu
2023-07-19 20:49 ` [PATCH 3/5] perf bench uprobe: Show diff to previous Arnaldo Carvalho de Melo
2023-07-21 14:48 ` Masami Hiramatsu
2023-07-19 20:49 ` [PATCH 4/5] perf bench uprobe empty: Add entry attaching an empty BPF program Arnaldo Carvalho de Melo
2023-07-19 20:49 ` [PATCH 5/5] perf bench uprobe trace_printk: Add entry attaching an BPF program that does a trace_printk Arnaldo Carvalho de Melo
2023-07-19 22:41 ` [PATCHES/RFC 1/5] perf bench uprobe + BPF skel Ian Rogers
2023-07-20 13:56 ` Arnaldo Carvalho de Melo
2023-07-21 14:32 ` Masami Hiramatsu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).