17c944106SAlexei Starovoitov // SPDX-License-Identifier: GPL-2.0
27c944106SAlexei Starovoitov // Copyright (c) 2019 Facebook
37c944106SAlexei Starovoitov #include <linux/sched.h>
47c944106SAlexei Starovoitov #include <linux/ptrace.h>
57c944106SAlexei Starovoitov #include <stdint.h>
67c944106SAlexei Starovoitov #include <stddef.h>
77c944106SAlexei Starovoitov #include <stdbool.h>
87c944106SAlexei Starovoitov #include <linux/bpf.h>
93e689141SToke Høiland-Jørgensen #include <bpf/bpf_helpers.h>
108c2b5e90SAndrii Nakryiko #include "bpf_misc.h"
117c944106SAlexei Starovoitov 
127c944106SAlexei Starovoitov #define FUNCTION_NAME_LEN 64
137c944106SAlexei Starovoitov #define FILE_NAME_LEN 128
147c944106SAlexei Starovoitov #define TASK_COMM_LEN 16
157c944106SAlexei Starovoitov 
167c944106SAlexei Starovoitov typedef struct {
177c944106SAlexei Starovoitov 	int PyThreadState_frame;
187c944106SAlexei Starovoitov 	int PyThreadState_thread;
197c944106SAlexei Starovoitov 	int PyFrameObject_back;
207c944106SAlexei Starovoitov 	int PyFrameObject_code;
217c944106SAlexei Starovoitov 	int PyFrameObject_lineno;
227c944106SAlexei Starovoitov 	int PyCodeObject_filename;
237c944106SAlexei Starovoitov 	int PyCodeObject_name;
247c944106SAlexei Starovoitov 	int String_data;
257c944106SAlexei Starovoitov 	int String_size;
267c944106SAlexei Starovoitov } OffsetConfig;
277c944106SAlexei Starovoitov 
287c944106SAlexei Starovoitov typedef struct {
297c944106SAlexei Starovoitov 	uintptr_t current_state_addr;
307c944106SAlexei Starovoitov 	uintptr_t tls_key_addr;
317c944106SAlexei Starovoitov 	OffsetConfig offsets;
327c944106SAlexei Starovoitov 	bool use_tls;
337c944106SAlexei Starovoitov } PidData;
347c944106SAlexei Starovoitov 
357c944106SAlexei Starovoitov typedef struct {
367c944106SAlexei Starovoitov 	uint32_t success;
377c944106SAlexei Starovoitov } Stats;
387c944106SAlexei Starovoitov 
397c944106SAlexei Starovoitov typedef struct {
407c944106SAlexei Starovoitov 	char name[FUNCTION_NAME_LEN];
417c944106SAlexei Starovoitov 	char file[FILE_NAME_LEN];
427c944106SAlexei Starovoitov } Symbol;
437c944106SAlexei Starovoitov 
447c944106SAlexei Starovoitov typedef struct {
457c944106SAlexei Starovoitov 	uint32_t pid;
467c944106SAlexei Starovoitov 	uint32_t tid;
477c944106SAlexei Starovoitov 	char comm[TASK_COMM_LEN];
487c944106SAlexei Starovoitov 	int32_t kernel_stack_id;
497c944106SAlexei Starovoitov 	int32_t user_stack_id;
507c944106SAlexei Starovoitov 	bool thread_current;
517c944106SAlexei Starovoitov 	bool pthread_match;
527c944106SAlexei Starovoitov 	bool stack_complete;
537c944106SAlexei Starovoitov 	int16_t stack_len;
547c944106SAlexei Starovoitov 	int32_t stack[STACK_MAX_LEN];
557c944106SAlexei Starovoitov 
567c944106SAlexei Starovoitov 	int has_meta;
577c944106SAlexei Starovoitov 	int metadata;
587c944106SAlexei Starovoitov 	char dummy_safeguard;
597c944106SAlexei Starovoitov } Event;
607c944106SAlexei Starovoitov 
617c944106SAlexei Starovoitov 
627c944106SAlexei Starovoitov typedef int pid_t;
637c944106SAlexei Starovoitov 
647c944106SAlexei Starovoitov typedef struct {
657c944106SAlexei Starovoitov 	void* f_back; // PyFrameObject.f_back, previous frame
667c944106SAlexei Starovoitov 	void* f_code; // PyFrameObject.f_code, pointer to PyCodeObject
677c944106SAlexei Starovoitov 	void* co_filename; // PyCodeObject.co_filename
687c944106SAlexei Starovoitov 	void* co_name; // PyCodeObject.co_name
697c944106SAlexei Starovoitov } FrameData;
707c944106SAlexei Starovoitov 
71fab45be1SAndrii Nakryiko #ifdef SUBPROGS
72fab45be1SAndrii Nakryiko __noinline
73fab45be1SAndrii Nakryiko #else
74fab45be1SAndrii Nakryiko __always_inline
75fab45be1SAndrii Nakryiko #endif
get_thread_state(void * tls_base,PidData * pidData)76fab45be1SAndrii Nakryiko static void *get_thread_state(void *tls_base, PidData *pidData)
777c944106SAlexei Starovoitov {
787c944106SAlexei Starovoitov 	void* thread_state;
797c944106SAlexei Starovoitov 	int key;
807c944106SAlexei Starovoitov 
8150f9aa44SDaniel Borkmann 	bpf_probe_read_user(&key, sizeof(key), (void*)(long)pidData->tls_key_addr);
8250f9aa44SDaniel Borkmann 	bpf_probe_read_user(&thread_state, sizeof(thread_state),
837c944106SAlexei Starovoitov 			    tls_base + 0x310 + key * 0x10 + 0x08);
847c944106SAlexei Starovoitov 	return thread_state;
857c944106SAlexei Starovoitov }
867c944106SAlexei Starovoitov 
get_frame_data(void * frame_ptr,PidData * pidData,FrameData * frame,Symbol * symbol)87d2f5bbbcSJiri Benc static __always_inline bool get_frame_data(void *frame_ptr, PidData *pidData,
88d2f5bbbcSJiri Benc 					   FrameData *frame, Symbol *symbol)
897c944106SAlexei Starovoitov {
907c944106SAlexei Starovoitov 	// read data from PyFrameObject
9150f9aa44SDaniel Borkmann 	bpf_probe_read_user(&frame->f_back,
927c944106SAlexei Starovoitov 			    sizeof(frame->f_back),
937c944106SAlexei Starovoitov 			    frame_ptr + pidData->offsets.PyFrameObject_back);
9450f9aa44SDaniel Borkmann 	bpf_probe_read_user(&frame->f_code,
957c944106SAlexei Starovoitov 			    sizeof(frame->f_code),
967c944106SAlexei Starovoitov 			    frame_ptr + pidData->offsets.PyFrameObject_code);
977c944106SAlexei Starovoitov 
987c944106SAlexei Starovoitov 	// read data from PyCodeObject
997c944106SAlexei Starovoitov 	if (!frame->f_code)
1007c944106SAlexei Starovoitov 		return false;
10150f9aa44SDaniel Borkmann 	bpf_probe_read_user(&frame->co_filename,
1027c944106SAlexei Starovoitov 			    sizeof(frame->co_filename),
1037c944106SAlexei Starovoitov 			    frame->f_code + pidData->offsets.PyCodeObject_filename);
10450f9aa44SDaniel Borkmann 	bpf_probe_read_user(&frame->co_name,
1057c944106SAlexei Starovoitov 			    sizeof(frame->co_name),
1067c944106SAlexei Starovoitov 			    frame->f_code + pidData->offsets.PyCodeObject_name);
1077c944106SAlexei Starovoitov 	// read actual names into symbol
1087c944106SAlexei Starovoitov 	if (frame->co_filename)
10950f9aa44SDaniel Borkmann 		bpf_probe_read_user_str(&symbol->file,
1107c944106SAlexei Starovoitov 					sizeof(symbol->file),
11150f9aa44SDaniel Borkmann 					frame->co_filename +
11250f9aa44SDaniel Borkmann 					pidData->offsets.String_data);
1137c944106SAlexei Starovoitov 	if (frame->co_name)
11450f9aa44SDaniel Borkmann 		bpf_probe_read_user_str(&symbol->name,
1157c944106SAlexei Starovoitov 					sizeof(symbol->name),
11650f9aa44SDaniel Borkmann 					frame->co_name +
11750f9aa44SDaniel Borkmann 					pidData->offsets.String_data);
1187c944106SAlexei Starovoitov 	return true;
1197c944106SAlexei Starovoitov }
1207c944106SAlexei Starovoitov 
1211639b17cSAndrii Nakryiko struct {
1221639b17cSAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_HASH);
1231639b17cSAndrii Nakryiko 	__uint(max_entries, 1);
1241639b17cSAndrii Nakryiko 	__type(key, int);
1251639b17cSAndrii Nakryiko 	__type(value, PidData);
1261639b17cSAndrii Nakryiko } pidmap SEC(".maps");
1277c944106SAlexei Starovoitov 
1281639b17cSAndrii Nakryiko struct {
1291639b17cSAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_HASH);
1301639b17cSAndrii Nakryiko 	__uint(max_entries, 1);
1311639b17cSAndrii Nakryiko 	__type(key, int);
1321639b17cSAndrii Nakryiko 	__type(value, Event);
1331639b17cSAndrii Nakryiko } eventmap SEC(".maps");
1347c944106SAlexei Starovoitov 
1351639b17cSAndrii Nakryiko struct {
1361639b17cSAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_HASH);
1371639b17cSAndrii Nakryiko 	__uint(max_entries, 1);
1381639b17cSAndrii Nakryiko 	__type(key, Symbol);
1391639b17cSAndrii Nakryiko 	__type(value, int);
1401639b17cSAndrii Nakryiko } symbolmap SEC(".maps");
1417c944106SAlexei Starovoitov 
1421639b17cSAndrii Nakryiko struct {
1431639b17cSAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_ARRAY);
1441639b17cSAndrii Nakryiko 	__uint(max_entries, 1);
1451639b17cSAndrii Nakryiko 	__type(key, int);
1461639b17cSAndrii Nakryiko 	__type(value, Stats);
1471639b17cSAndrii Nakryiko } statsmap SEC(".maps");
1487c944106SAlexei Starovoitov 
1491639b17cSAndrii Nakryiko struct {
1501639b17cSAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
1511639b17cSAndrii Nakryiko 	__uint(max_entries, 32);
1521639b17cSAndrii Nakryiko 	__uint(key_size, sizeof(int));
1531639b17cSAndrii Nakryiko 	__uint(value_size, sizeof(int));
1541639b17cSAndrii Nakryiko } perfmap SEC(".maps");
1557c944106SAlexei Starovoitov 
1561639b17cSAndrii Nakryiko struct {
1571639b17cSAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_STACK_TRACE);
1581639b17cSAndrii Nakryiko 	__uint(max_entries, 1000);
1591639b17cSAndrii Nakryiko 	__uint(key_size, sizeof(int));
1601639b17cSAndrii Nakryiko 	__uint(value_size, sizeof(long long) * 127);
1611639b17cSAndrii Nakryiko } stackmap SEC(".maps");
1627c944106SAlexei Starovoitov 
163f6e659b7SJoanne Koong #ifdef USE_BPF_LOOP
164f6e659b7SJoanne Koong struct process_frame_ctx {
165f6e659b7SJoanne Koong 	int cur_cpu;
166f6e659b7SJoanne Koong 	int32_t *symbol_counter;
167f6e659b7SJoanne Koong 	void *frame_ptr;
168f6e659b7SJoanne Koong 	FrameData *frame;
169f6e659b7SJoanne Koong 	PidData *pidData;
170f6e659b7SJoanne Koong 	Symbol *sym;
171f6e659b7SJoanne Koong 	Event *event;
172f6e659b7SJoanne Koong 	bool done;
173f6e659b7SJoanne Koong };
174f6e659b7SJoanne Koong 
process_frame_callback(__u32 i,struct process_frame_ctx * ctx)175f6e659b7SJoanne Koong static int process_frame_callback(__u32 i, struct process_frame_ctx *ctx)
176f6e659b7SJoanne Koong {
177f6e659b7SJoanne Koong 	int zero = 0;
178f6e659b7SJoanne Koong 	void *frame_ptr = ctx->frame_ptr;
179f6e659b7SJoanne Koong 	PidData *pidData = ctx->pidData;
180f6e659b7SJoanne Koong 	FrameData *frame = ctx->frame;
181f6e659b7SJoanne Koong 	int32_t *symbol_counter = ctx->symbol_counter;
182f6e659b7SJoanne Koong 	int cur_cpu = ctx->cur_cpu;
183f6e659b7SJoanne Koong 	Event *event = ctx->event;
184f6e659b7SJoanne Koong 	Symbol *sym = ctx->sym;
185f6e659b7SJoanne Koong 
186f6e659b7SJoanne Koong 	if (frame_ptr && get_frame_data(frame_ptr, pidData, frame, sym)) {
187f6e659b7SJoanne Koong 		int32_t new_symbol_id = *symbol_counter * 64 + cur_cpu;
188f6e659b7SJoanne Koong 		int32_t *symbol_id = bpf_map_lookup_elem(&symbolmap, sym);
189f6e659b7SJoanne Koong 
190f6e659b7SJoanne Koong 		if (!symbol_id) {
191f6e659b7SJoanne Koong 			bpf_map_update_elem(&symbolmap, sym, &zero, 0);
192f6e659b7SJoanne Koong 			symbol_id = bpf_map_lookup_elem(&symbolmap, sym);
193f6e659b7SJoanne Koong 			if (!symbol_id) {
194f6e659b7SJoanne Koong 				ctx->done = true;
195f6e659b7SJoanne Koong 				return 1;
196f6e659b7SJoanne Koong 			}
197f6e659b7SJoanne Koong 		}
198f6e659b7SJoanne Koong 		if (*symbol_id == new_symbol_id)
199f6e659b7SJoanne Koong 			(*symbol_counter)++;
200f6e659b7SJoanne Koong 
201f6e659b7SJoanne Koong 		barrier_var(i);
202f6e659b7SJoanne Koong 		if (i >= STACK_MAX_LEN)
203f6e659b7SJoanne Koong 			return 1;
204f6e659b7SJoanne Koong 
205f6e659b7SJoanne Koong 		event->stack[i] = *symbol_id;
206f6e659b7SJoanne Koong 
207f6e659b7SJoanne Koong 		event->stack_len = i + 1;
208f6e659b7SJoanne Koong 		frame_ptr = frame->f_back;
209f6e659b7SJoanne Koong 	}
210f6e659b7SJoanne Koong 	return 0;
211f6e659b7SJoanne Koong }
212f6e659b7SJoanne Koong #endif /* USE_BPF_LOOP */
213f6e659b7SJoanne Koong 
2146db2d81aSAlexei Starovoitov #ifdef GLOBAL_FUNC
215fab45be1SAndrii Nakryiko __noinline
216fab45be1SAndrii Nakryiko #elif defined(SUBPROGS)
217fab45be1SAndrii Nakryiko static __noinline
2186db2d81aSAlexei Starovoitov #else
2196db2d81aSAlexei Starovoitov static __always_inline
2206db2d81aSAlexei Starovoitov #endif
__on_event(struct bpf_raw_tracepoint_args * ctx)2216db2d81aSAlexei Starovoitov int __on_event(struct bpf_raw_tracepoint_args *ctx)
2227c944106SAlexei Starovoitov {
2237c944106SAlexei Starovoitov 	uint64_t pid_tgid = bpf_get_current_pid_tgid();
2247c944106SAlexei Starovoitov 	pid_t pid = (pid_t)(pid_tgid >> 32);
2257c944106SAlexei Starovoitov 	PidData* pidData = bpf_map_lookup_elem(&pidmap, &pid);
2267c944106SAlexei Starovoitov 	if (!pidData)
2277c944106SAlexei Starovoitov 		return 0;
2287c944106SAlexei Starovoitov 
2297c944106SAlexei Starovoitov 	int zero = 0;
2307c944106SAlexei Starovoitov 	Event* event = bpf_map_lookup_elem(&eventmap, &zero);
2317c944106SAlexei Starovoitov 	if (!event)
2327c944106SAlexei Starovoitov 		return 0;
2337c944106SAlexei Starovoitov 
2347c944106SAlexei Starovoitov 	event->pid = pid;
2357c944106SAlexei Starovoitov 
2367c944106SAlexei Starovoitov 	event->tid = (pid_t)pid_tgid;
2377c944106SAlexei Starovoitov 	bpf_get_current_comm(&event->comm, sizeof(event->comm));
2387c944106SAlexei Starovoitov 
2397c944106SAlexei Starovoitov 	event->user_stack_id = bpf_get_stackid(ctx, &stackmap, BPF_F_USER_STACK);
2407c944106SAlexei Starovoitov 	event->kernel_stack_id = bpf_get_stackid(ctx, &stackmap, 0);
2417c944106SAlexei Starovoitov 
2427c944106SAlexei Starovoitov 	void* thread_state_current = (void*)0;
24350f9aa44SDaniel Borkmann 	bpf_probe_read_user(&thread_state_current,
2447c944106SAlexei Starovoitov 			    sizeof(thread_state_current),
2457c944106SAlexei Starovoitov 			    (void*)(long)pidData->current_state_addr);
2467c944106SAlexei Starovoitov 
2477c944106SAlexei Starovoitov 	struct task_struct* task = (struct task_struct*)bpf_get_current_task();
2487c944106SAlexei Starovoitov 	void* tls_base = (void*)task;
2497c944106SAlexei Starovoitov 
2507c944106SAlexei Starovoitov 	void* thread_state = pidData->use_tls ? get_thread_state(tls_base, pidData)
2517c944106SAlexei Starovoitov 		: thread_state_current;
2527c944106SAlexei Starovoitov 	event->thread_current = thread_state == thread_state_current;
2537c944106SAlexei Starovoitov 
2547c944106SAlexei Starovoitov 	if (pidData->use_tls) {
2557c944106SAlexei Starovoitov 		uint64_t pthread_created;
2567c944106SAlexei Starovoitov 		uint64_t pthread_self;
25750f9aa44SDaniel Borkmann 		bpf_probe_read_user(&pthread_self, sizeof(pthread_self),
25850f9aa44SDaniel Borkmann 				    tls_base + 0x10);
2597c944106SAlexei Starovoitov 
26050f9aa44SDaniel Borkmann 		bpf_probe_read_user(&pthread_created,
2617c944106SAlexei Starovoitov 				    sizeof(pthread_created),
26250f9aa44SDaniel Borkmann 				    thread_state +
26350f9aa44SDaniel Borkmann 				    pidData->offsets.PyThreadState_thread);
2647c944106SAlexei Starovoitov 		event->pthread_match = pthread_created == pthread_self;
2657c944106SAlexei Starovoitov 	} else {
2667c944106SAlexei Starovoitov 		event->pthread_match = 1;
2677c944106SAlexei Starovoitov 	}
2687c944106SAlexei Starovoitov 
2697c944106SAlexei Starovoitov 	if (event->pthread_match || !pidData->use_tls) {
2707c944106SAlexei Starovoitov 		void* frame_ptr;
2717c944106SAlexei Starovoitov 		FrameData frame;
2727c944106SAlexei Starovoitov 		Symbol sym = {};
2737c944106SAlexei Starovoitov 		int cur_cpu = bpf_get_smp_processor_id();
2747c944106SAlexei Starovoitov 
27550f9aa44SDaniel Borkmann 		bpf_probe_read_user(&frame_ptr,
2767c944106SAlexei Starovoitov 				    sizeof(frame_ptr),
27750f9aa44SDaniel Borkmann 				    thread_state +
27850f9aa44SDaniel Borkmann 				    pidData->offsets.PyThreadState_frame);
2797c944106SAlexei Starovoitov 
2807c944106SAlexei Starovoitov 		int32_t* symbol_counter = bpf_map_lookup_elem(&symbolmap, &sym);
2817c944106SAlexei Starovoitov 		if (symbol_counter == NULL)
2827c944106SAlexei Starovoitov 			return 0;
283f6e659b7SJoanne Koong #ifdef USE_BPF_LOOP
284f6e659b7SJoanne Koong 	struct process_frame_ctx ctx = {
285f6e659b7SJoanne Koong 		.cur_cpu = cur_cpu,
286f6e659b7SJoanne Koong 		.symbol_counter = symbol_counter,
287f6e659b7SJoanne Koong 		.frame_ptr = frame_ptr,
288f6e659b7SJoanne Koong 		.frame = &frame,
289f6e659b7SJoanne Koong 		.pidData = pidData,
290f6e659b7SJoanne Koong 		.sym = &sym,
291f6e659b7SJoanne Koong 		.event = event,
292f6e659b7SJoanne Koong 	};
293f6e659b7SJoanne Koong 
294f6e659b7SJoanne Koong 	bpf_loop(STACK_MAX_LEN, process_frame_callback, &ctx, 0);
295f6e659b7SJoanne Koong 	if (ctx.done)
296f6e659b7SJoanne Koong 		return 0;
297f6e659b7SJoanne Koong #else
2988c2b5e90SAndrii Nakryiko #if defined(USE_ITER)
2998c2b5e90SAndrii Nakryiko /* no for loop, no unrolling */
3008c2b5e90SAndrii Nakryiko #elif defined(NO_UNROLL)
301b061017fSAlexei Starovoitov #pragma clang loop unroll(disable)
3028c2b5e90SAndrii Nakryiko #elif defined(UNROLL_COUNT)
3038c89b5dbSYonghong Song #pragma clang loop unroll_count(UNROLL_COUNT)
3048c89b5dbSYonghong Song #else
305b061017fSAlexei Starovoitov #pragma clang loop unroll(full)
306f6e659b7SJoanne Koong #endif /* NO_UNROLL */
3077c944106SAlexei Starovoitov 		/* Unwind python stack */
3088c2b5e90SAndrii Nakryiko #ifdef USE_ITER
3098c2b5e90SAndrii Nakryiko 		int i;
3108c2b5e90SAndrii Nakryiko 		bpf_for(i, 0, STACK_MAX_LEN) {
3118c2b5e90SAndrii Nakryiko #else /* !USE_ITER */
3127c944106SAlexei Starovoitov 		for (int i = 0; i < STACK_MAX_LEN; ++i) {
3138c2b5e90SAndrii Nakryiko #endif
3147c944106SAlexei Starovoitov 			if (frame_ptr && get_frame_data(frame_ptr, pidData, &frame, &sym)) {
3157c944106SAlexei Starovoitov 				int32_t new_symbol_id = *symbol_counter * 64 + cur_cpu;
3167c944106SAlexei Starovoitov 				int32_t *symbol_id = bpf_map_lookup_elem(&symbolmap, &sym);
3177c944106SAlexei Starovoitov 				if (!symbol_id) {
3187c944106SAlexei Starovoitov 					bpf_map_update_elem(&symbolmap, &sym, &zero, 0);
3197c944106SAlexei Starovoitov 					symbol_id = bpf_map_lookup_elem(&symbolmap, &sym);
3207c944106SAlexei Starovoitov 					if (!symbol_id)
3217c944106SAlexei Starovoitov 						return 0;
3227c944106SAlexei Starovoitov 				}
3237c944106SAlexei Starovoitov 				if (*symbol_id == new_symbol_id)
3247c944106SAlexei Starovoitov 					(*symbol_counter)++;
3257c944106SAlexei Starovoitov 				event->stack[i] = *symbol_id;
3267c944106SAlexei Starovoitov 				event->stack_len = i + 1;
3277c944106SAlexei Starovoitov 				frame_ptr = frame.f_back;
3287c944106SAlexei Starovoitov 			}
3297c944106SAlexei Starovoitov 		}
330f6e659b7SJoanne Koong #endif /* USE_BPF_LOOP */
3317c944106SAlexei Starovoitov 		event->stack_complete = frame_ptr == NULL;
3327c944106SAlexei Starovoitov 	} else {
3337c944106SAlexei Starovoitov 		event->stack_complete = 1;
3347c944106SAlexei Starovoitov 	}
3357c944106SAlexei Starovoitov 
3367c944106SAlexei Starovoitov 	Stats* stats = bpf_map_lookup_elem(&statsmap, &zero);
3377c944106SAlexei Starovoitov 	if (stats)
3387c944106SAlexei Starovoitov 		stats->success++;
3397c944106SAlexei Starovoitov 
3407c944106SAlexei Starovoitov 	event->has_meta = 0;
3417c944106SAlexei Starovoitov 	bpf_perf_event_output(ctx, &perfmap, 0, event, offsetof(Event, metadata));
3427c944106SAlexei Starovoitov 	return 0;
3437c944106SAlexei Starovoitov }
3447c944106SAlexei Starovoitov 
3457c944106SAlexei Starovoitov SEC("raw_tracepoint/kfree_skb")
3466db2d81aSAlexei Starovoitov int on_event(struct bpf_raw_tracepoint_args* ctx)
3477c944106SAlexei Starovoitov {
348*c8ed6685SAndrii Nakryiko 	int ret = 0;
3497c944106SAlexei Starovoitov 	ret |= __on_event(ctx);
3507c944106SAlexei Starovoitov 	ret |= __on_event(ctx);
3517c944106SAlexei Starovoitov 	ret |= __on_event(ctx);
3527c944106SAlexei Starovoitov 	ret |= __on_event(ctx);
3537c944106SAlexei Starovoitov 	ret |= __on_event(ctx);
3547c944106SAlexei Starovoitov 	return ret;
3557c944106SAlexei Starovoitov }
3567c944106SAlexei Starovoitov 
3577c944106SAlexei Starovoitov char _license[] SEC("license") = "GPL";
358