@@ -9011,59 +9011,17 @@ int bpf_link__unpin(struct bpf_link *link)
9011
9011
return 0 ;
9012
9012
}
9013
9013
9014
- static int poke_kprobe_events (bool add , const char * name , bool retprobe , uint64_t offset )
9015
- {
9016
- int fd , ret = 0 ;
9017
- pid_t p = getpid ();
9018
- char cmd [260 ], probename [128 ], probefunc [128 ];
9019
- const char * file = "/sys/kernel/debug/tracing/kprobe_events" ;
9020
-
9021
- if (retprobe )
9022
- snprintf (probename , sizeof (probename ), "kretprobes/%s_libbpf_%u" , name , p );
9023
- else
9024
- snprintf (probename , sizeof (probename ), "kprobes/%s_libbpf_%u" , name , p );
9025
-
9026
- if (offset )
9027
- snprintf (probefunc , sizeof (probefunc ), "%s+%zu" , name , (size_t )offset );
9028
-
9029
- if (add ) {
9030
- snprintf (cmd , sizeof (cmd ), "%c:%s %s" ,
9031
- retprobe ? 'r' : 'p' ,
9032
- probename ,
9033
- offset ? probefunc : name );
9034
- } else {
9035
- snprintf (cmd , sizeof (cmd ), "-:%s" , probename );
9036
- }
9037
-
9038
- fd = open (file , O_WRONLY | O_APPEND , 0 );
9039
- if (!fd )
9040
- return - errno ;
9041
- ret = write (fd , cmd , strlen (cmd ));
9042
- if (ret < 0 )
9043
- ret = - errno ;
9044
- close (fd );
9045
-
9046
- return ret ;
9047
- }
9048
-
9049
- static inline int add_kprobe_event_legacy (const char * name , bool retprobe , uint64_t offset )
9050
- {
9051
- return poke_kprobe_events (true, name , retprobe , offset );
9052
- }
9053
-
9054
- static inline int remove_kprobe_event_legacy (const char * name , bool retprobe )
9055
- {
9056
- return poke_kprobe_events (false, name , retprobe , 0 );
9057
- }
9058
-
9059
9014
struct bpf_link_perf {
9060
9015
struct bpf_link link ;
9061
9016
int perf_event_fd ;
9062
9017
/* legacy kprobe support: keep track of probe identifier and type */
9063
9018
char * legacy_probe_name ;
9019
+ bool legacy_is_kprobe ;
9064
9020
bool legacy_is_retprobe ;
9065
9021
};
9066
9022
9023
+ static int remove_kprobe_event_legacy (const char * probe_name , bool retprobe );
9024
+
9067
9025
static int bpf_link_perf_detach (struct bpf_link * link )
9068
9026
{
9069
9027
struct bpf_link_perf * perf_link = container_of (link , struct bpf_link_perf , link );
@@ -9077,9 +9035,12 @@ static int bpf_link_perf_detach(struct bpf_link *link)
9077
9035
close (link -> fd );
9078
9036
9079
9037
/* legacy kprobe needs to be removed after perf event fd closure */
9080
- if (perf_link -> legacy_probe_name )
9081
- err = remove_kprobe_event_legacy (perf_link -> legacy_probe_name ,
9082
- perf_link -> legacy_is_retprobe );
9038
+ if (perf_link -> legacy_probe_name ) {
9039
+ if (perf_link -> legacy_is_kprobe ) {
9040
+ err = remove_kprobe_event_legacy (perf_link -> legacy_probe_name ,
9041
+ perf_link -> legacy_is_retprobe );
9042
+ }
9043
+ }
9083
9044
9084
9045
return err ;
9085
9046
}
@@ -9202,18 +9163,6 @@ static int parse_uint_from_file(const char *file, const char *fmt)
9202
9163
return ret ;
9203
9164
}
9204
9165
9205
- static int determine_kprobe_perf_type_legacy (const char * func_name , bool is_retprobe )
9206
- {
9207
- char file [192 ];
9208
-
9209
- snprintf (file , sizeof (file ),
9210
- "/sys/kernel/debug/tracing/events/%s/%s_libbpf_%d/id" ,
9211
- is_retprobe ? "kretprobes" : "kprobes" ,
9212
- func_name , getpid ());
9213
-
9214
- return parse_uint_from_file (file , "%d\n" );
9215
- }
9216
-
9217
9166
static int determine_kprobe_perf_type (void )
9218
9167
{
9219
9168
const char * file = "/sys/bus/event_source/devices/kprobe/type" ;
@@ -9296,21 +9245,79 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
9296
9245
return pfd ;
9297
9246
}
9298
9247
9299
- static int perf_event_kprobe_open_legacy (bool retprobe , const char * name , uint64_t offset , int pid )
9248
+ static int append_to_file (const char * file , const char * fmt , ...)
9249
+ {
9250
+ int fd , n , err = 0 ;
9251
+ va_list ap ;
9252
+
9253
+ fd = open (file , O_WRONLY | O_APPEND , 0 );
9254
+ if (fd < 0 )
9255
+ return - errno ;
9256
+
9257
+ va_start (ap , fmt );
9258
+ n = vdprintf (fd , fmt , ap );
9259
+ va_end (ap );
9260
+
9261
+ if (n < 0 )
9262
+ err = - errno ;
9263
+
9264
+ close (fd );
9265
+ return err ;
9266
+ }
9267
+
9268
+ static void gen_kprobe_legacy_event_name (char * buf , size_t buf_sz ,
9269
+ const char * kfunc_name , size_t offset )
9270
+ {
9271
+ snprintf (buf , buf_sz , "libbpf_%u_%s_0x%zx" , getpid (), kfunc_name , offset );
9272
+ }
9273
+
9274
+ static int add_kprobe_event_legacy (const char * probe_name , bool retprobe ,
9275
+ const char * kfunc_name , size_t offset )
9276
+ {
9277
+ const char * file = "/sys/kernel/debug/tracing/kprobe_events" ;
9278
+
9279
+ return append_to_file (file , "%c:%s/%s %s+0x%zx" ,
9280
+ retprobe ? 'r' : 'p' ,
9281
+ retprobe ? "kretprobes" : "kprobes" ,
9282
+ probe_name , kfunc_name , offset );
9283
+ }
9284
+
9285
+ static int remove_kprobe_event_legacy (const char * probe_name , bool retprobe )
9286
+ {
9287
+ const char * file = "/sys/kernel/debug/tracing/kprobe_events" ;
9288
+
9289
+ return append_to_file (file , "-:%s/%s" , retprobe ? "kretprobes" : "kprobes" , probe_name );
9290
+ }
9291
+
9292
+ static int determine_kprobe_perf_type_legacy (const char * probe_name , bool retprobe )
9293
+ {
9294
+ char file [256 ];
9295
+
9296
+ snprintf (file , sizeof (file ),
9297
+ "/sys/kernel/debug/tracing/events/%s/%s/id" ,
9298
+ retprobe ? "kretprobes" : "kprobes" , probe_name );
9299
+
9300
+ return parse_uint_from_file (file , "%d\n" );
9301
+ }
9302
+
9303
+ static int perf_event_kprobe_open_legacy (const char * probe_name , bool retprobe ,
9304
+ const char * kfunc_name , size_t offset , int pid )
9300
9305
{
9301
9306
struct perf_event_attr attr = {};
9302
9307
char errmsg [STRERR_BUFSIZE ];
9303
9308
int type , pfd , err ;
9304
9309
9305
- err = add_kprobe_event_legacy (name , retprobe , offset );
9310
+ err = add_kprobe_event_legacy (probe_name , retprobe , kfunc_name , offset );
9306
9311
if (err < 0 ) {
9307
- pr_warn ("failed to add legacy kprobe event: %s\n" ,
9312
+ pr_warn ("failed to add legacy kprobe event for '%s+0x%zx': %s\n" ,
9313
+ kfunc_name , offset ,
9308
9314
libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
9309
9315
return err ;
9310
9316
}
9311
- type = determine_kprobe_perf_type_legacy (name , retprobe );
9317
+ type = determine_kprobe_perf_type_legacy (probe_name , retprobe );
9312
9318
if (type < 0 ) {
9313
- pr_warn ("failed to determine legacy kprobe event id: %s\n" ,
9319
+ pr_warn ("failed to determine legacy kprobe event id for '%s+0x%zx': %s\n" ,
9320
+ kfunc_name , offset ,
9314
9321
libbpf_strerror_r (type , errmsg , sizeof (errmsg )));
9315
9322
return type ;
9316
9323
}
@@ -9340,7 +9347,7 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog,
9340
9347
char errmsg [STRERR_BUFSIZE ];
9341
9348
char * legacy_probe = NULL ;
9342
9349
struct bpf_link * link ;
9343
- unsigned long offset ;
9350
+ size_t offset ;
9344
9351
bool retprobe , legacy ;
9345
9352
int pfd , err ;
9346
9353
@@ -9357,33 +9364,41 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog,
9357
9364
func_name , offset ,
9358
9365
-1 /* pid */ , 0 /* ref_ctr_off */ );
9359
9366
} else {
9367
+ char probe_name [256 ];
9368
+
9369
+ gen_kprobe_legacy_event_name (probe_name , sizeof (probe_name ),
9370
+ func_name , offset );
9371
+
9360
9372
legacy_probe = strdup (func_name );
9361
9373
if (!legacy_probe )
9362
9374
return libbpf_err_ptr (- ENOMEM );
9363
9375
9364
- pfd = perf_event_kprobe_open_legacy (retprobe , func_name ,
9376
+ pfd = perf_event_kprobe_open_legacy (legacy_probe , retprobe , func_name ,
9365
9377
offset , -1 /* pid */ );
9366
9378
}
9367
9379
if (pfd < 0 ) {
9368
- err = pfd ;
9369
- pr_warn ("prog '%s': failed to create %s '%s' perf event: %s\n" ,
9370
- prog -> name , retprobe ? "kretprobe" : "kprobe" , func_name ,
9380
+ err = - errno ;
9381
+ pr_warn ("prog '%s': failed to create %s '%s+0x%zx' perf event: %s\n" ,
9382
+ prog -> name , retprobe ? "kretprobe" : "kprobe" ,
9383
+ func_name , offset ,
9371
9384
libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
9372
9385
goto err_out ;
9373
9386
}
9374
9387
link = bpf_program__attach_perf_event_opts (prog , pfd , & pe_opts );
9375
9388
err = libbpf_get_error (link );
9376
9389
if (err ) {
9377
9390
close (pfd );
9378
- pr_warn ("prog '%s': failed to attach to %s '%s': %s\n" ,
9379
- prog -> name , retprobe ? "kretprobe" : "kprobe" , func_name ,
9391
+ pr_warn ("prog '%s': failed to attach to %s '%s+0x%zx': %s\n" ,
9392
+ prog -> name , retprobe ? "kretprobe" : "kprobe" ,
9393
+ func_name , offset ,
9380
9394
libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
9381
9395
goto err_out ;
9382
9396
}
9383
9397
if (legacy ) {
9384
9398
struct bpf_link_perf * perf_link = container_of (link , struct bpf_link_perf , link );
9385
9399
9386
9400
perf_link -> legacy_probe_name = legacy_probe ;
9401
+ perf_link -> legacy_is_kprobe = true;
9387
9402
perf_link -> legacy_is_retprobe = retprobe ;
9388
9403
}
9389
9404
0 commit comments