bpf_loop.c (2063B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (c) 2021 Facebook */ 3 4#include "vmlinux.h" 5#include <bpf/bpf_helpers.h> 6#include "bpf_misc.h" 7 8char _license[] SEC("license") = "GPL"; 9 10struct callback_ctx { 11 int output; 12}; 13 14/* These should be set by the user program */ 15u32 nested_callback_nr_loops; 16u32 stop_index = -1; 17u32 nr_loops; 18int pid; 19 20/* Making these global variables so that the userspace program 21 * can verify the output through the skeleton 22 */ 23int nr_loops_returned; 24int g_output; 25int err; 26 27static int callback(__u32 index, void *data) 28{ 29 struct callback_ctx *ctx = data; 30 31 if (index >= stop_index) 32 return 1; 33 34 ctx->output += index; 35 36 return 0; 37} 38 39static int empty_callback(__u32 index, void *data) 40{ 41 return 0; 42} 43 44static int nested_callback2(__u32 index, void *data) 45{ 46 nr_loops_returned += bpf_loop(nested_callback_nr_loops, callback, data, 0); 47 48 return 0; 49} 50 51static int nested_callback1(__u32 index, void *data) 52{ 53 bpf_loop(nested_callback_nr_loops, nested_callback2, data, 0); 54 return 0; 55} 56 57SEC("fentry/" SYS_PREFIX "sys_nanosleep") 58int test_prog(void *ctx) 59{ 60 struct callback_ctx data = {}; 61 62 if (bpf_get_current_pid_tgid() >> 32 != pid) 63 return 0; 64 65 nr_loops_returned = bpf_loop(nr_loops, callback, &data, 0); 66 67 if (nr_loops_returned < 0) 68 err = nr_loops_returned; 69 else 70 g_output = data.output; 71 72 return 0; 73} 74 75SEC("fentry/" SYS_PREFIX "sys_nanosleep") 76int prog_null_ctx(void *ctx) 77{ 78 if (bpf_get_current_pid_tgid() >> 32 != pid) 79 return 0; 80 81 nr_loops_returned = bpf_loop(nr_loops, empty_callback, NULL, 0); 82 83 return 0; 84} 85 86SEC("fentry/" SYS_PREFIX "sys_nanosleep") 87int prog_invalid_flags(void *ctx) 88{ 89 struct callback_ctx data = {}; 90 91 if (bpf_get_current_pid_tgid() >> 32 != pid) 92 return 0; 93 94 err = bpf_loop(nr_loops, callback, &data, 1); 95 96 return 0; 97} 98 99SEC("fentry/" SYS_PREFIX "sys_nanosleep") 100int prog_nested_calls(void *ctx) 101{ 102 struct callback_ctx data = {}; 103 104 if (bpf_get_current_pid_tgid() >> 32 != pid) 105 return 0; 106 107 nr_loops_returned = 0; 108 bpf_loop(nr_loops, nested_callback1, &data, 0); 109 110 g_output = data.output; 111 112 return 0; 113}