@@ -4190,6 +4190,85 @@ struct bpf_link *bpf_program__attach_uprobe(struct bpf_program *prog,
4190
4190
return link ;
4191
4191
}
4192
4192
4193
+ static int determine_tracepoint_id (const char * tp_category ,
4194
+ const char * tp_name )
4195
+ {
4196
+ char file [PATH_MAX ];
4197
+ int ret ;
4198
+
4199
+ ret = snprintf (file , sizeof (file ),
4200
+ "/sys/kernel/debug/tracing/events/%s/%s/id" ,
4201
+ tp_category , tp_name );
4202
+ if (ret < 0 )
4203
+ return - errno ;
4204
+ if (ret >= sizeof (file )) {
4205
+ pr_debug ("tracepoint %s/%s path is too long\n" ,
4206
+ tp_category , tp_name );
4207
+ return - E2BIG ;
4208
+ }
4209
+ return parse_uint_from_file (file , "%d\n" );
4210
+ }
4211
+
4212
+ static int perf_event_open_tracepoint (const char * tp_category ,
4213
+ const char * tp_name )
4214
+ {
4215
+ struct perf_event_attr attr = {};
4216
+ char errmsg [STRERR_BUFSIZE ];
4217
+ int tp_id , pfd , err ;
4218
+
4219
+ tp_id = determine_tracepoint_id (tp_category , tp_name );
4220
+ if (tp_id < 0 ) {
4221
+ pr_warning ("failed to determine tracepoint '%s/%s' perf event ID: %s\n" ,
4222
+ tp_category , tp_name ,
4223
+ libbpf_strerror_r (tp_id , errmsg , sizeof (errmsg )));
4224
+ return tp_id ;
4225
+ }
4226
+
4227
+ attr .type = PERF_TYPE_TRACEPOINT ;
4228
+ attr .size = sizeof (attr );
4229
+ attr .config = tp_id ;
4230
+
4231
+ pfd = syscall (__NR_perf_event_open , & attr , -1 /* pid */ , 0 /* cpu */ ,
4232
+ -1 /* group_fd */ , PERF_FLAG_FD_CLOEXEC );
4233
+ if (pfd < 0 ) {
4234
+ err = - errno ;
4235
+ pr_warning ("tracepoint '%s/%s' perf_event_open() failed: %s\n" ,
4236
+ tp_category , tp_name ,
4237
+ libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
4238
+ return err ;
4239
+ }
4240
+ return pfd ;
4241
+ }
4242
+
4243
+ struct bpf_link * bpf_program__attach_tracepoint (struct bpf_program * prog ,
4244
+ const char * tp_category ,
4245
+ const char * tp_name )
4246
+ {
4247
+ char errmsg [STRERR_BUFSIZE ];
4248
+ struct bpf_link * link ;
4249
+ int pfd , err ;
4250
+
4251
+ pfd = perf_event_open_tracepoint (tp_category , tp_name );
4252
+ if (pfd < 0 ) {
4253
+ pr_warning ("program '%s': failed to create tracepoint '%s/%s' perf event: %s\n" ,
4254
+ bpf_program__title (prog , false),
4255
+ tp_category , tp_name ,
4256
+ libbpf_strerror_r (pfd , errmsg , sizeof (errmsg )));
4257
+ return ERR_PTR (pfd );
4258
+ }
4259
+ link = bpf_program__attach_perf_event (prog , pfd );
4260
+ if (IS_ERR (link )) {
4261
+ close (pfd );
4262
+ err = PTR_ERR (link );
4263
+ pr_warning ("program '%s': failed to attach to tracepoint '%s/%s': %s\n" ,
4264
+ bpf_program__title (prog , false),
4265
+ tp_category , tp_name ,
4266
+ libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
4267
+ return link ;
4268
+ }
4269
+ return link ;
4270
+ }
4271
+
4193
4272
enum bpf_perf_event_ret
4194
4273
bpf_perf_event_read_simple (void * mmap_mem , size_t mmap_size , size_t page_size ,
4195
4274
void * * copy_mem , size_t * copy_size ,
0 commit comments