@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
25572557 return 0 ;
25582558}
25592559
2560- static int __add_probe_trace_events (struct perf_probe_event * pev ,
2561- struct probe_trace_event * tevs ,
2562- int ntevs , bool allow_suffix )
2560+ static int __open_probe_file_and_namelist (bool uprobe ,
2561+ struct strlist * * namelist )
25632562{
2564- int i , fd , ret ;
2565- struct probe_trace_event * tev = NULL ;
2566- struct probe_cache * cache = NULL ;
2567- struct strlist * namelist ;
2563+ int fd ;
25682564
2569- fd = probe_file__open (PF_FL_RW | (pev -> uprobes ? PF_FL_UPROBE : 0 ));
2565+ fd = probe_file__open (PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0 ));
25702566 if (fd < 0 )
25712567 return fd ;
25722568
25732569 /* Get current event names */
2574- namelist = probe_file__get_namelist (fd );
2575- if (!namelist ) {
2570+ * namelist = probe_file__get_namelist (fd );
2571+ if (!( * namelist ) ) {
25762572 pr_debug ("Failed to get current event list.\n" );
2577- ret = - ENOMEM ;
2578- goto close_out ;
2573+ close ( fd ) ;
2574+ return - ENOMEM ;
25792575 }
2576+ return fd ;
2577+ }
2578+
2579+ static int __add_probe_trace_events (struct perf_probe_event * pev ,
2580+ struct probe_trace_event * tevs ,
2581+ int ntevs , bool allow_suffix )
2582+ {
2583+ int i , fd [2 ] = {-1 , -1 }, up , ret ;
2584+ struct probe_trace_event * tev = NULL ;
2585+ struct probe_cache * cache = NULL ;
2586+ struct strlist * namelist [2 ] = {NULL , NULL };
2587+
2588+ up = pev -> uprobes ? 1 : 0 ;
2589+ fd [up ] = __open_probe_file_and_namelist (up , & namelist [up ]);
2590+ if (fd [up ] < 0 )
2591+ return fd [up ];
25802592
25812593 ret = 0 ;
25822594 for (i = 0 ; i < ntevs ; i ++ ) {
25832595 tev = & tevs [i ];
2596+ up = tev -> uprobes ? 1 : 0 ;
2597+ if (fd [up ] == -1 ) { /* Open the kprobe/uprobe_events */
2598+ fd [up ] = __open_probe_file_and_namelist (up ,
2599+ & namelist [up ]);
2600+ if (fd [up ] < 0 )
2601+ goto close_out ;
2602+ }
25842603 /* Skip if the symbol is out of .text or blacklisted */
25852604 if (!tev -> point .symbol && !pev -> uprobes )
25862605 continue ;
25872606
25882607 /* Set new name for tev (and update namelist) */
2589- ret = probe_trace_event__set_name (tev , pev , namelist ,
2608+ ret = probe_trace_event__set_name (tev , pev , namelist [ up ] ,
25902609 allow_suffix );
25912610 if (ret < 0 )
25922611 break ;
25932612
2594- ret = probe_file__add_event (fd , tev );
2613+ ret = probe_file__add_event (fd [ up ] , tev );
25952614 if (ret < 0 )
25962615 break ;
25972616
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
26142633 probe_cache__delete (cache );
26152634 }
26162635
2617- strlist__delete (namelist );
26182636close_out :
2619- close (fd );
2637+ for (up = 0 ; up < 2 ; up ++ ) {
2638+ strlist__delete (namelist [up ]);
2639+ if (fd [up ] >= 0 )
2640+ close (fd [up ]);
2641+ }
26202642 return ret ;
26212643}
26222644
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event *pev,
29893011 return ret ;
29903012}
29913013
3014+ /* Try to find probe_trace_event from all probe caches */
3015+ static int find_cached_events_all (struct perf_probe_event * pev ,
3016+ struct probe_trace_event * * tevs )
3017+ {
3018+ struct probe_trace_event * tmp_tevs = NULL ;
3019+ struct strlist * bidlist ;
3020+ struct str_node * nd ;
3021+ char * pathname ;
3022+ int ntevs = 0 ;
3023+ int ret ;
3024+
3025+ /* Get the buildid list of all valid caches */
3026+ bidlist = build_id_cache__list_all (true);
3027+ if (!bidlist ) {
3028+ ret = - errno ;
3029+ pr_debug ("Failed to get buildids: %d\n" , ret );
3030+ return ret ;
3031+ }
3032+
3033+ ret = 0 ;
3034+ strlist__for_each_entry (nd , bidlist ) {
3035+ pathname = build_id_cache__origname (nd -> s );
3036+ ret = find_cached_events (pev , & tmp_tevs , pathname );
3037+ /* In the case of cnt == 0, we just skip it */
3038+ if (ret > 0 )
3039+ ret = concat_probe_trace_events (tevs , & ntevs ,
3040+ & tmp_tevs , ret );
3041+ free (pathname );
3042+ if (ret < 0 )
3043+ break ;
3044+ }
3045+ strlist__delete (bidlist );
3046+
3047+ if (ret < 0 ) {
3048+ clear_probe_trace_events (* tevs , ntevs );
3049+ zfree (tevs );
3050+ } else
3051+ ret = ntevs ;
3052+
3053+ return ret ;
3054+ }
3055+
29923056static int find_probe_trace_events_from_cache (struct perf_probe_event * pev ,
29933057 struct probe_trace_event * * tevs )
29943058{
@@ -2998,10 +3062,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
29983062 struct str_node * node ;
29993063 int ret , i ;
30003064
3001- if (pev -> sdt )
3065+ if (pev -> sdt ) {
30023066 /* For SDT/cached events, we use special search functions */
3003- return find_cached_events (pev , tevs , pev -> target );
3004-
3067+ if (!pev -> target )
3068+ return find_cached_events_all (pev , tevs );
3069+ else
3070+ return find_cached_events (pev , tevs , pev -> target );
3071+ }
30053072 cache = probe_cache__new (pev -> target );
30063073 if (!cache )
30073074 return 0 ;
0 commit comments