@@ -9011,59 +9011,17 @@ int bpf_link__unpin(struct bpf_link *link)
90119011 return 0 ;
90129012}
90139013
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-
90599014struct bpf_link_perf {
90609015 struct bpf_link link ;
90619016 int perf_event_fd ;
90629017 /* legacy kprobe support: keep track of probe identifier and type */
90639018 char * legacy_probe_name ;
9019+ bool legacy_is_kprobe ;
90649020 bool legacy_is_retprobe ;
90659021};
90669022
9023+ static int remove_kprobe_event_legacy (const char * probe_name , bool retprobe );
9024+
90679025static int bpf_link_perf_detach (struct bpf_link * link )
90689026{
90699027 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)
90779035 close (link -> fd );
90789036
90799037 /* 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+ }
90839044
90849045 return err ;
90859046}
@@ -9202,18 +9163,6 @@ static int parse_uint_from_file(const char *file, const char *fmt)
92029163 return ret ;
92039164}
92049165
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-
92179166static int determine_kprobe_perf_type (void )
92189167{
92199168 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,
92969245 return pfd ;
92979246}
92989247
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 )
93009305{
93019306 struct perf_event_attr attr = {};
93029307 char errmsg [STRERR_BUFSIZE ];
93039308 int type , pfd , err ;
93049309
9305- err = add_kprobe_event_legacy (name , retprobe , offset );
9310+ err = add_kprobe_event_legacy (probe_name , retprobe , kfunc_name , offset );
93069311 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 ,
93089314 libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
93099315 return err ;
93109316 }
9311- type = determine_kprobe_perf_type_legacy (name , retprobe );
9317+ type = determine_kprobe_perf_type_legacy (probe_name , retprobe );
93129318 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 ,
93149321 libbpf_strerror_r (type , errmsg , sizeof (errmsg )));
93159322 return type ;
93169323 }
@@ -9340,7 +9347,7 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog,
93409347 char errmsg [STRERR_BUFSIZE ];
93419348 char * legacy_probe = NULL ;
93429349 struct bpf_link * link ;
9343- unsigned long offset ;
9350+ size_t offset ;
93449351 bool retprobe , legacy ;
93459352 int pfd , err ;
93469353
@@ -9357,33 +9364,41 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog,
93579364 func_name , offset ,
93589365 -1 /* pid */ , 0 /* ref_ctr_off */ );
93599366 } else {
9367+ char probe_name [256 ];
9368+
9369+ gen_kprobe_legacy_event_name (probe_name , sizeof (probe_name ),
9370+ func_name , offset );
9371+
93609372 legacy_probe = strdup (func_name );
93619373 if (!legacy_probe )
93629374 return libbpf_err_ptr (- ENOMEM );
93639375
9364- pfd = perf_event_kprobe_open_legacy (retprobe , func_name ,
9376+ pfd = perf_event_kprobe_open_legacy (legacy_probe , retprobe , func_name ,
93659377 offset , -1 /* pid */ );
93669378 }
93679379 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 ,
93719384 libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
93729385 goto err_out ;
93739386 }
93749387 link = bpf_program__attach_perf_event_opts (prog , pfd , & pe_opts );
93759388 err = libbpf_get_error (link );
93769389 if (err ) {
93779390 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 ,
93809394 libbpf_strerror_r (err , errmsg , sizeof (errmsg )));
93819395 goto err_out ;
93829396 }
93839397 if (legacy ) {
93849398 struct bpf_link_perf * perf_link = container_of (link , struct bpf_link_perf , link );
93859399
93869400 perf_link -> legacy_probe_name = legacy_probe ;
9401+ perf_link -> legacy_is_kprobe = true;
93879402 perf_link -> legacy_is_retprobe = retprobe ;
93889403 }
93899404
0 commit comments