1
1
// SPDX-License-Identifier: GPL-2.0
2
+ #define _GNU_SOURCE
3
+ #include <pthread.h>
4
+ #include <sched.h>
5
+ #include <sys/socket.h>
2
6
#include <test_progs.h>
3
7
4
8
#define MAX_CNT_RAWTP 10ull
5
9
#define MAX_STACK_RAWTP 100
10
+
11
+ static int duration = 0 ;
12
+
6
13
struct get_stack_trace_t {
7
14
int pid ;
8
15
int kern_stack_size ;
@@ -13,7 +20,7 @@ struct get_stack_trace_t {
13
20
struct bpf_stack_build_id user_stack_buildid [MAX_STACK_RAWTP ];
14
21
};
15
22
16
- static int get_stack_print_output (void * data , int size )
23
+ static void get_stack_print_output (void * ctx , int cpu , void * data , __u32 size )
17
24
{
18
25
bool good_kern_stack = false, good_user_stack = false;
19
26
const char * nonjit_func = "___bpf_prog_run" ;
@@ -65,75 +72,76 @@ static int get_stack_print_output(void *data, int size)
65
72
if (e -> user_stack_size > 0 && e -> user_stack_buildid_size > 0 )
66
73
good_user_stack = true;
67
74
}
68
- if (!good_kern_stack || !good_user_stack )
69
- return LIBBPF_PERF_EVENT_ERROR ;
70
75
71
- if (cnt == MAX_CNT_RAWTP )
72
- return LIBBPF_PERF_EVENT_DONE ;
73
-
74
- return LIBBPF_PERF_EVENT_CONT ;
76
+ if (! good_kern_stack )
77
+ CHECK (! good_kern_stack , "kern_stack" , "corrupted kernel stack\n" ) ;
78
+ if (! good_user_stack )
79
+ CHECK (! good_user_stack , "user_stack" , "corrupted user stack\n" ) ;
75
80
}
76
81
77
82
void test_get_stack_raw_tp (void )
78
83
{
79
84
const char * file = "./test_get_stack_rawtp.o" ;
80
- int i , efd , err , prog_fd , pmu_fd , perfmap_fd ;
81
- struct perf_event_attr attr = {};
85
+ const char * prog_name = "raw_tracepoint/sys_enter" ;
86
+ int i , err , prog_fd , exp_cnt = MAX_CNT_RAWTP ;
87
+ struct perf_buffer_opts pb_opts = {};
88
+ struct perf_buffer * pb = NULL ;
89
+ struct bpf_link * link = NULL ;
82
90
struct timespec tv = {0 , 10 };
83
- __u32 key = 0 , duration = 0 ;
91
+ struct bpf_program * prog ;
84
92
struct bpf_object * obj ;
93
+ struct bpf_map * map ;
94
+ cpu_set_t cpu_set ;
85
95
86
96
err = bpf_prog_load (file , BPF_PROG_TYPE_RAW_TRACEPOINT , & obj , & prog_fd );
87
97
if (CHECK (err , "prog_load raw tp" , "err %d errno %d\n" , err , errno ))
88
98
return ;
89
99
90
- efd = bpf_raw_tracepoint_open ( "sys_enter" , prog_fd );
91
- if (CHECK (efd < 0 , "raw_tp_open " , "err %d errno %d \n" , efd , errno ))
100
+ prog = bpf_object__find_program_by_title ( obj , prog_name );
101
+ if (CHECK (! prog , "find_probe " , "prog '%s' not found \n" , prog_name ))
92
102
goto close_prog ;
93
103
94
- perfmap_fd = bpf_find_map (__func__ , obj , "perfmap" );
95
- if (CHECK (perfmap_fd < 0 , "bpf_find_map" , "err %d errno %d\n" ,
96
- perfmap_fd , errno ))
104
+ map = bpf_object__find_map_by_name (obj , "perfmap" );
105
+ if (CHECK (!map , "bpf_find_map" , "not found\n" ))
97
106
goto close_prog ;
98
107
99
108
err = load_kallsyms ();
100
109
if (CHECK (err < 0 , "load_kallsyms" , "err %d errno %d\n" , err , errno ))
101
110
goto close_prog ;
102
111
103
- attr .sample_type = PERF_SAMPLE_RAW ;
104
- attr .type = PERF_TYPE_SOFTWARE ;
105
- attr .config = PERF_COUNT_SW_BPF_OUTPUT ;
106
- pmu_fd = syscall (__NR_perf_event_open , & attr , getpid ()/*pid*/ , -1 /*cpu*/ ,
107
- -1 /*group_fd*/ , 0 );
108
- if (CHECK (pmu_fd < 0 , "perf_event_open" , "err %d errno %d\n" , pmu_fd ,
109
- errno ))
112
+ CPU_ZERO (& cpu_set );
113
+ CPU_SET (0 , & cpu_set );
114
+ err = pthread_setaffinity_np (pthread_self (), sizeof (cpu_set ), & cpu_set );
115
+ if (CHECK (err , "set_affinity" , "err %d, errno %d\n" , err , errno ))
110
116
goto close_prog ;
111
117
112
- err = bpf_map_update_elem (perfmap_fd , & key , & pmu_fd , BPF_ANY );
113
- if (CHECK (err < 0 , "bpf_map_update_elem" , "err %d errno %d\n" , err ,
114
- errno ))
118
+ link = bpf_program__attach_raw_tracepoint (prog , "sys_enter" );
119
+ if (CHECK (IS_ERR (link ), "attach_raw_tp" , "err %ld\n" , PTR_ERR (link )))
115
120
goto close_prog ;
116
121
117
- err = ioctl (pmu_fd , PERF_EVENT_IOC_ENABLE , 0 );
118
- if (CHECK (err < 0 , "ioctl PERF_EVENT_IOC_ENABLE" , "err %d errno %d\n" ,
119
- err , errno ))
120
- goto close_prog ;
121
-
122
- err = perf_event_mmap (pmu_fd );
123
- if (CHECK (err < 0 , "perf_event_mmap" , "err %d errno %d\n" , err , errno ))
122
+ pb_opts .sample_cb = get_stack_print_output ;
123
+ pb = perf_buffer__new (bpf_map__fd (map ), 8 , & pb_opts );
124
+ if (CHECK (IS_ERR (pb ), "perf_buf__new" , "err %ld\n" , PTR_ERR (pb )))
124
125
goto close_prog ;
125
126
126
127
/* trigger some syscall action */
127
128
for (i = 0 ; i < MAX_CNT_RAWTP ; i ++ )
128
129
nanosleep (& tv , NULL );
129
130
130
- err = perf_event_poller (pmu_fd , get_stack_print_output );
131
- if (CHECK (err < 0 , "perf_event_poller" , "err %d errno %d\n" , err , errno ))
132
- goto close_prog ;
131
+ while (exp_cnt > 0 ) {
132
+ err = perf_buffer__poll (pb , 100 );
133
+ if (err < 0 && CHECK (err < 0 , "pb__poll" , "err %d\n" , err ))
134
+ goto close_prog ;
135
+ exp_cnt -= err ;
136
+ }
133
137
134
138
goto close_prog_noerr ;
135
139
close_prog :
136
140
error_cnt ++ ;
137
141
close_prog_noerr :
142
+ if (!IS_ERR_OR_NULL (link ))
143
+ bpf_link__destroy (link );
144
+ if (!IS_ERR_OR_NULL (pb ))
145
+ perf_buffer__free (pb );
138
146
bpf_object__close (obj );
139
147
}
0 commit comments