diff options
Diffstat (limited to 'tools/testing/selftests/bpf/progs/pyperf.h')
| -rw-r--r-- | tools/testing/selftests/bpf/progs/pyperf.h | 71 | 
1 files changed, 70 insertions, 1 deletions
| diff --git a/tools/testing/selftests/bpf/progs/pyperf.h b/tools/testing/selftests/bpf/progs/pyperf.h index 2fb7adafb6b6..1ed28882daf3 100644 --- a/tools/testing/selftests/bpf/progs/pyperf.h +++ b/tools/testing/selftests/bpf/progs/pyperf.h @@ -159,6 +159,59 @@ struct {  	__uint(value_size, sizeof(long long) * 127);  } stackmap SEC(".maps"); +#ifdef USE_BPF_LOOP +struct process_frame_ctx { +	int cur_cpu; +	int32_t *symbol_counter; +	void *frame_ptr; +	FrameData *frame; +	PidData *pidData; +	Symbol *sym; +	Event *event; +	bool done; +}; + +#define barrier_var(var) asm volatile("" : "=r"(var) : "0"(var)) + +static int process_frame_callback(__u32 i, struct process_frame_ctx *ctx) +{ +	int zero = 0; +	void *frame_ptr = ctx->frame_ptr; +	PidData *pidData = ctx->pidData; +	FrameData *frame = ctx->frame; +	int32_t *symbol_counter = ctx->symbol_counter; +	int cur_cpu = ctx->cur_cpu; +	Event *event = ctx->event; +	Symbol *sym = ctx->sym; + +	if (frame_ptr && get_frame_data(frame_ptr, pidData, frame, sym)) { +		int32_t new_symbol_id = *symbol_counter * 64 + cur_cpu; +		int32_t *symbol_id = bpf_map_lookup_elem(&symbolmap, sym); + +		if (!symbol_id) { +			bpf_map_update_elem(&symbolmap, sym, &zero, 0); +			symbol_id = bpf_map_lookup_elem(&symbolmap, sym); +			if (!symbol_id) { +				ctx->done = true; +				return 1; +			} +		} +		if (*symbol_id == new_symbol_id) +			(*symbol_counter)++; + +		barrier_var(i); +		if (i >= STACK_MAX_LEN) +			return 1; + +		event->stack[i] = *symbol_id; + +		event->stack_len = i + 1; +		frame_ptr = frame->f_back; +	} +	return 0; +} +#endif /* USE_BPF_LOOP */ +  #ifdef GLOBAL_FUNC  __noinline  #elif defined(SUBPROGS) @@ -228,11 +281,26 @@ int __on_event(struct bpf_raw_tracepoint_args *ctx)  		int32_t* symbol_counter = bpf_map_lookup_elem(&symbolmap, &sym);  		if (symbol_counter == NULL)  			return 0; +#ifdef USE_BPF_LOOP +	struct process_frame_ctx ctx = { +		.cur_cpu = cur_cpu, +		.symbol_counter = symbol_counter, +		.frame_ptr = frame_ptr, +		.frame = &frame, +		.pidData = pidData, +		.sym = &sym, +		.event = event, +	}; + +	bpf_loop(STACK_MAX_LEN, process_frame_callback, &ctx, 0); +	if (ctx.done) +		return 0; +#else  #ifdef NO_UNROLL  #pragma clang loop unroll(disable)  #else  #pragma clang loop unroll(full) -#endif +#endif /* NO_UNROLL */  		/* Unwind python stack */  		for (int i = 0; i < STACK_MAX_LEN; ++i) {  			if (frame_ptr && get_frame_data(frame_ptr, pidData, &frame, &sym)) { @@ -251,6 +319,7 @@ int __on_event(struct bpf_raw_tracepoint_args *ctx)  				frame_ptr = frame.f_back;  			}  		} +#endif /* USE_BPF_LOOP */  		event->stack_complete = frame_ptr == NULL;  	} else {  		event->stack_complete = 1; | 
