@@ -477,6 +477,69 @@ static int get_syms(char ***symsp, size_t *cntp, bool kernel)
477477 return err ;
478478}
479479
480+ static int get_addrs (unsigned long * * addrsp , size_t * cntp , bool kernel )
481+ {
482+ unsigned long * addr , * addrs , * tmp_addrs ;
483+ int err = 0 , max_cnt , inc_cnt ;
484+ char * name = NULL ;
485+ size_t cnt = 0 ;
486+ char buf [256 ];
487+ FILE * f ;
488+
489+ if (access ("/sys/kernel/tracing/trace" , F_OK ) == 0 )
490+ f = fopen ("/sys/kernel/tracing/available_filter_functions_addrs" , "r" );
491+ else
492+ f = fopen ("/sys/kernel/debug/tracing/available_filter_functions_addrs" , "r" );
493+
494+ if (!f )
495+ return - ENOENT ;
496+
497+ /* In my local setup, the number of entries is 50k+ so Let us initially
498+ * allocate space to hold 64k entries. If 64k is not enough, incrementally
499+ * increase 1k each time.
500+ */
501+ max_cnt = 65536 ;
502+ inc_cnt = 1024 ;
503+ addrs = malloc (max_cnt * sizeof (long ));
504+ if (addrs == NULL ) {
505+ err = - ENOMEM ;
506+ goto error ;
507+ }
508+
509+ while (fgets (buf , sizeof (buf ), f )) {
510+ if (is_invalid_entry (buf , kernel ))
511+ continue ;
512+
513+ free (name );
514+ if (sscanf (buf , "%p %ms$*[^\n]\n" , & addr , & name ) != 2 )
515+ continue ;
516+ if (skip_entry (name ))
517+ continue ;
518+
519+ if (cnt == max_cnt ) {
520+ max_cnt += inc_cnt ;
521+ tmp_addrs = realloc (addrs , max_cnt );
522+ if (!tmp_addrs ) {
523+ err = - ENOMEM ;
524+ goto error ;
525+ }
526+ addrs = tmp_addrs ;
527+ }
528+
529+ addrs [cnt ++ ] = (unsigned long )addr ;
530+ }
531+
532+ * addrsp = addrs ;
533+ * cntp = cnt ;
534+
535+ error :
536+ free (name );
537+ fclose (f );
538+ if (err )
539+ free (addrs );
540+ return err ;
541+ }
542+
480543static void do_bench_test (struct kprobe_multi_empty * skel , struct bpf_kprobe_multi_opts * opts )
481544{
482545 long attach_start_ns , attach_end_ns ;
@@ -529,6 +592,37 @@ static void test_kprobe_multi_bench_attach(bool kernel)
529592 free (syms );
530593}
531594
595+ static void test_kprobe_multi_bench_attach_addr (bool kernel )
596+ {
597+ LIBBPF_OPTS (bpf_kprobe_multi_opts , opts );
598+ struct kprobe_multi_empty * skel = NULL ;
599+ unsigned long * addrs = NULL ;
600+ size_t cnt = 0 ;
601+ int err ;
602+
603+ err = get_addrs (& addrs , & cnt , kernel );
604+ if (err == - ENOENT ) {
605+ test__skip ();
606+ return ;
607+ }
608+
609+ if (!ASSERT_OK (err , "get_addrs" ))
610+ return ;
611+
612+ skel = kprobe_multi_empty__open_and_load ();
613+ if (!ASSERT_OK_PTR (skel , "kprobe_multi_empty__open_and_load" ))
614+ goto cleanup ;
615+
616+ opts .addrs = addrs ;
617+ opts .cnt = cnt ;
618+
619+ do_bench_test (skel , & opts );
620+
621+ cleanup :
622+ kprobe_multi_empty__destroy (skel );
623+ free (addrs );
624+ }
625+
532626static void test_attach_override (void )
533627{
534628 struct kprobe_multi_override * skel = NULL ;
@@ -569,6 +663,10 @@ void serial_test_kprobe_multi_bench_attach(void)
569663 test_kprobe_multi_bench_attach (true);
570664 if (test__start_subtest ("modules" ))
571665 test_kprobe_multi_bench_attach (false);
666+ if (test__start_subtest ("kernel" ))
667+ test_kprobe_multi_bench_attach_addr (true);
668+ if (test__start_subtest ("modules" ))
669+ test_kprobe_multi_bench_attach_addr (false);
572670}
573671
574672void test_kprobe_multi_test (void )
0 commit comments