perf: Expose get/put_callchain_entry()
authorSong Liu <songliubraving@fb.com>
Tue, 30 Jun 2020 06:28:43 +0000 (23:28 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 1 Jul 2020 15:22:08 +0000 (08:22 -0700)
Sanitize and expose get/put_callchain_entry(). This would be used by bpf
stack map.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/20200630062846.664389-2-songliubraving@fb.com
include/linux/perf_event.h
kernel/events/callchain.c

index b4bb320..00ab5ef 100644 (file)
@@ -1244,6 +1244,8 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
 extern struct perf_callchain_entry *perf_callchain(struct perf_event *event, struct pt_regs *regs);
 extern int get_callchain_buffers(int max_stack);
 extern void put_callchain_buffers(void);
+extern struct perf_callchain_entry *get_callchain_entry(int *rctx);
+extern void put_callchain_entry(int rctx);
 
 extern int sysctl_perf_event_max_stack;
 extern int sysctl_perf_event_max_contexts_per_stack;
index 334d48b..c6ce894 100644 (file)
@@ -149,7 +149,7 @@ void put_callchain_buffers(void)
        }
 }
 
-static struct perf_callchain_entry *get_callchain_entry(int *rctx)
+struct perf_callchain_entry *get_callchain_entry(int *rctx)
 {
        int cpu;
        struct callchain_cpus_entries *entries;
@@ -159,8 +159,10 @@ static struct perf_callchain_entry *get_callchain_entry(int *rctx)
                return NULL;
 
        entries = rcu_dereference(callchain_cpus_entries);
-       if (!entries)
+       if (!entries) {
+               put_recursion_context(this_cpu_ptr(callchain_recursion), *rctx);
                return NULL;
+       }
 
        cpu = smp_processor_id();
 
@@ -168,7 +170,7 @@ static struct perf_callchain_entry *get_callchain_entry(int *rctx)
                (*rctx * perf_callchain_entry__sizeof()));
 }
 
-static void
+void
 put_callchain_entry(int rctx)
 {
        put_recursion_context(this_cpu_ptr(callchain_recursion), rctx);
@@ -183,11 +185,8 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
        int rctx;
 
        entry = get_callchain_entry(&rctx);
-       if (rctx == -1)
-               return NULL;
-
        if (!entry)
-               goto exit_put;
+               return NULL;
 
        ctx.entry     = entry;
        ctx.max_stack = max_stack;