@@ -1173,6 +1173,7 @@ SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h $(SKEL_OUT)/sample_filter.skel.h
SKELETONS += $(SKEL_OUT)/kwork_top.skel.h
SKELETONS += $(SKEL_OUT)/bench_uprobe.skel.h
SKELETONS += $(SKEL_OUT)/augmented_raw_syscalls.skel.h
+SKELETONS += $(SKEL_OUT)/auxtrace_pause.skel.h
$(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT):
$(Q)$(MKDIR) -p $@
new file mode 100644
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+// Copyright 2024 Arm Limited
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(key_size, sizeof(__u32));
+ __uint(value_size, sizeof(__u8));
+ __uint(max_entries, 1);
+} cpu_filter SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(key_size, sizeof(__u32));
+ __uint(value_size, sizeof(__u8));
+ __uint(max_entries, 1);
+} task_filter SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+ __uint(key_size, sizeof(__u32));
+ __uint(value_size, sizeof(int));
+ __uint(max_entries, 1);
+} events SEC(".maps");
+
+int enabled = 0;
+
+const volatile int has_cpu = 0;
+const volatile int has_task = 0;
+
+static int event_aux_pause(void)
+{
+ __u64 key;
+
+ if (!enabled)
+ return 0;
+
+ if (has_cpu) {
+ __u32 cpu = bpf_get_smp_processor_id();
+ __u8 *ok;
+
+ ok = bpf_map_lookup_elem(&cpu_filter, &cpu);
+ if (!ok)
+ return 0;
+
+ key = cpu;
+ }
+
+ if (has_task) {
+ __u32 pid = bpf_get_current_pid_tgid() & 0xffffffff;
+ __u8 *ok;
+
+ ok = bpf_map_lookup_elem(&task_filter, &pid);
+ if (!ok)
+ return 0;
+
+ key = 0;
+ }
+
+ bpf_perf_event_aux_pause(&events, key, 1);
+ return 0;
+}
+
+static int event_aux_resume(void)
+{
+ __u64 key;
+
+ if (!enabled)
+ return 0;
+
+ if (has_cpu) {
+ __u32 cpu = bpf_get_smp_processor_id();
+ __u8 *ok;
+
+ ok = bpf_map_lookup_elem(&cpu_filter, &cpu);
+ if (!ok)
+ return 0;
+
+ key = cpu;
+ }
+
+ if (has_task) {
+ __u32 pid = bpf_get_current_pid_tgid() & 0xffffffff;
+ __u8 *ok;
+
+ ok = bpf_map_lookup_elem(&task_filter, &pid);
+ if (!ok)
+ return 0;
+
+ key = 0;
+ }
+
+ bpf_perf_event_aux_pause(&events, key, 0);
+ return 0;
+}
+
+SEC("kprobe/func_pause")
+int BPF_PROG(kprobe_event_pause)
+{
+ return event_aux_pause();
+}
+
+SEC("kretprobe/func_pause")
+int BPF_PROG(kretprobe_event_pause)
+{
+ return event_aux_pause();
+}
+
+SEC("tp/func_pause")
+int BPF_PROG(tp_event_pause)
+{
+ return event_aux_pause();
+}
+
+SEC("kprobe/func_resume")
+int BPF_PROG(kprobe_event_resume)
+{
+ return event_aux_resume();
+}
+
+SEC("kretprobe/func_resume")
+int BPF_PROG(kretprobe_event_resume)
+{
+ return event_aux_resume();
+}
+
+SEC("tp/func_resume")
+int BPF_PROG(tp_event_resume)
+{
+ return event_aux_resume();
+}
+
+char LICENSE[] SEC("license") = "Dual BSD/GPL";
This commit introduces eBPF program as backend to trigger AUX pause and resume. The eBPF programs are prepared for attaching kprobe, kretprobe and tracepoints. When a eBPF program is invoked, it calls the eBPF API bpf_perf_event_aux_pause() for controlling AUX pause and resume. Signed-off-by: Leo Yan <leo.yan@arm.com> --- tools/perf/Makefile.perf | 1 + tools/perf/util/bpf_skel/auxtrace_pause.bpf.c | 135 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 tools/perf/util/bpf_skel/auxtrace_pause.bpf.c