@@ -58,6 +58,11 @@ struct perf_pmu_alias {
5858 struct list_head terms ;
5959 /** @list: List element of struct perf_pmu aliases. */
6060 struct list_head list ;
61+ /**
62+ * @pmu_name: The name copied from the json struct pmu_event. This can
63+ * differ from the PMU name as it won't have suffixes.
64+ */
65+ char * pmu_name ;
6166 /** @unit: Units for the event, such as bytes or cache lines. */
6267 char unit [UNIT_MAX_LEN + 1 ];
6368 /** @scale: Value to scale read counter values by. */
@@ -79,11 +84,10 @@ struct perf_pmu_alias {
7984 * default.
8085 */
8186 bool deprecated ;
82- /**
83- * @pmu_name: The name copied from the json struct pmu_event. This can
84- * differ from the PMU name as it won't have suffixes.
85- */
86- char * pmu_name ;
87+ /** @from_sysfs: Was the alias from sysfs or a json event? */
88+ bool from_sysfs ;
89+ /** @info_loaded: Have the scale, unit and other values been read from disk? */
90+ bool info_loaded ;
8791};
8892
8993/**
@@ -280,17 +284,21 @@ int perf_pmu__convert_scale(const char *scale, char **end, double *sval)
280284 return ret ;
281285}
282286
283- static int perf_pmu__parse_scale (struct perf_pmu_alias * alias , int dirfd , const char * name )
287+ static int perf_pmu__parse_scale (struct perf_pmu * pmu , struct perf_pmu_alias * alias )
284288{
285289 struct stat st ;
286290 ssize_t sret ;
291+ size_t len ;
287292 char scale [128 ];
288293 int fd , ret = -1 ;
289294 char path [PATH_MAX ];
290295
291- scnprintf (path , PATH_MAX , "%s.scale" , name );
296+ len = perf_pmu__event_source_devices_scnprintf (path , sizeof (path ));
297+ if (!len )
298+ return 0 ;
299+ scnprintf (path + len , sizeof (path ) - len , "%s/%s.scale" , pmu -> name , alias -> name );
292300
293- fd = openat ( dirfd , path , O_RDONLY );
301+ fd = open ( path , O_RDONLY );
294302 if (fd == -1 )
295303 return -1 ;
296304
@@ -312,15 +320,20 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, int dirfd, const
312320 return ret ;
313321}
314322
315- static int perf_pmu__parse_unit (struct perf_pmu_alias * alias , int dirfd , const char * name )
323+ static int perf_pmu__parse_unit (struct perf_pmu * pmu , struct perf_pmu_alias * alias )
316324{
317325 char path [PATH_MAX ];
326+ size_t len ;
318327 ssize_t sret ;
319328 int fd ;
320329
321- scnprintf (path , PATH_MAX , "%s.unit" , name );
322330
323- fd = openat (dirfd , path , O_RDONLY );
331+ len = perf_pmu__event_source_devices_scnprintf (path , sizeof (path ));
332+ if (!len )
333+ return 0 ;
334+ scnprintf (path + len , sizeof (path ) - len , "%s/%s.unit" , pmu -> name , alias -> name );
335+
336+ fd = open (path , O_RDONLY );
324337 if (fd == -1 )
325338 return -1 ;
326339
@@ -343,14 +356,18 @@ static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, int dirfd, const c
343356}
344357
345358static int
346- perf_pmu__parse_per_pkg (struct perf_pmu_alias * alias , int dirfd , const char * name )
359+ perf_pmu__parse_per_pkg (struct perf_pmu * pmu , struct perf_pmu_alias * alias )
347360{
348361 char path [PATH_MAX ];
362+ size_t len ;
349363 int fd ;
350364
351- scnprintf (path , PATH_MAX , "%s.per-pkg" , name );
365+ len = perf_pmu__event_source_devices_scnprintf (path , sizeof (path ));
366+ if (!len )
367+ return 0 ;
368+ scnprintf (path + len , sizeof (path ) - len , "%s/%s.per-pkg" , pmu -> name , alias -> name );
352369
353- fd = openat ( dirfd , path , O_RDONLY );
370+ fd = open ( path , O_RDONLY );
354371 if (fd == -1 )
355372 return -1 ;
356373
@@ -360,15 +377,18 @@ perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, int dirfd, const char *nam
360377 return 0 ;
361378}
362379
363- static int perf_pmu__parse_snapshot (struct perf_pmu_alias * alias ,
364- int dirfd , const char * name )
380+ static int perf_pmu__parse_snapshot (struct perf_pmu * pmu , struct perf_pmu_alias * alias )
365381{
366382 char path [PATH_MAX ];
383+ size_t len ;
367384 int fd ;
368385
369- scnprintf (path , PATH_MAX , "%s.snapshot" , name );
386+ len = perf_pmu__event_source_devices_scnprintf (path , sizeof (path ));
387+ if (!len )
388+ return 0 ;
389+ scnprintf (path + len , sizeof (path ) - len , "%s/%s.snapshot" , pmu -> name , alias -> name );
370390
371- fd = openat ( dirfd , path , O_RDONLY );
391+ fd = open ( path , O_RDONLY );
372392 if (fd == -1 )
373393 return -1 ;
374394
@@ -429,32 +449,52 @@ static bool assign_str(const char *name, const char *field, char **old_str,
429449 return true;
430450}
431451
452+ static void read_alias_info (struct perf_pmu * pmu , struct perf_pmu_alias * alias )
453+ {
454+ if (!alias -> from_sysfs || alias -> info_loaded )
455+ return ;
456+
457+ /*
458+ * load unit name and scale if available
459+ */
460+ perf_pmu__parse_unit (pmu , alias );
461+ perf_pmu__parse_scale (pmu , alias );
462+ perf_pmu__parse_per_pkg (pmu , alias );
463+ perf_pmu__parse_snapshot (pmu , alias );
464+ }
465+
466+ struct update_alias_data {
467+ struct perf_pmu * pmu ;
468+ struct perf_pmu_alias * alias ;
469+ };
470+
432471static int update_alias (const struct pmu_event * pe ,
433472 const struct pmu_events_table * table __maybe_unused ,
434473 void * vdata )
435474{
436- struct perf_pmu_alias * alias = vdata ;
475+ struct update_alias_data * data = vdata ;
437476 int ret = 0 ;
438477
439- assign_str (pe -> name , "desc" , & alias -> desc , pe -> desc );
440- assign_str (pe -> name , "long_desc" , & alias -> long_desc , pe -> long_desc );
441- assign_str (pe -> name , "topic" , & alias -> topic , pe -> topic );
442- alias -> per_pkg = pe -> perpkg ;
443- if (assign_str (pe -> name , "value" , & alias -> str , pe -> event )) {
444- parse_events_terms__purge (& alias -> terms );
445- ret = parse_events_terms (& alias -> terms , pe -> event , /*input=*/ NULL );
478+ read_alias_info (data -> pmu , data -> alias );
479+ assign_str (pe -> name , "desc" , & data -> alias -> desc , pe -> desc );
480+ assign_str (pe -> name , "long_desc" , & data -> alias -> long_desc , pe -> long_desc );
481+ assign_str (pe -> name , "topic" , & data -> alias -> topic , pe -> topic );
482+ data -> alias -> per_pkg = pe -> perpkg ;
483+ if (assign_str (pe -> name , "value" , & data -> alias -> str , pe -> event )) {
484+ parse_events_terms__purge (& data -> alias -> terms );
485+ ret = parse_events_terms (& data -> alias -> terms , pe -> event , /*input=*/ NULL );
446486 }
447487 if (!ret && pe -> unit ) {
448488 char * unit ;
449489
450- ret = perf_pmu__convert_scale (pe -> unit , & unit , & alias -> scale );
490+ ret = perf_pmu__convert_scale (pe -> unit , & unit , & data -> alias -> scale );
451491 if (!ret )
452- snprintf (alias -> unit , sizeof (alias -> unit ), "%s" , unit );
492+ snprintf (data -> alias -> unit , sizeof (data -> alias -> unit ), "%s" , unit );
453493 }
454494 return ret ;
455495}
456496
457- static int perf_pmu__new_alias (struct perf_pmu * pmu , int dirfd , const char * name ,
497+ static int perf_pmu__new_alias (struct perf_pmu * pmu , const char * name ,
458498 const char * desc , const char * val , FILE * val_fd ,
459499 const struct pmu_event * pe )
460500{
@@ -498,16 +538,6 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, int dirfd, const char *name
498538 }
499539
500540 alias -> name = strdup (name );
501- if (dirfd >= 0 ) {
502- /*
503- * load unit name and scale if available
504- */
505- perf_pmu__parse_unit (alias , dirfd , name );
506- perf_pmu__parse_scale (alias , dirfd , name );
507- perf_pmu__parse_per_pkg (alias , dirfd , name );
508- perf_pmu__parse_snapshot (alias , dirfd , name );
509- }
510-
511541 alias -> desc = desc ? strdup (desc ) : NULL ;
512542 alias -> long_desc = long_desc ? strdup (long_desc ) :
513543 desc ? strdup (desc ) : NULL ;
@@ -522,9 +552,15 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, int dirfd, const char *name
522552 }
523553 if (!pe ) {
524554 /* Update an event from sysfs with json data. */
555+ struct update_alias_data data = {
556+ .pmu = pmu ,
557+ .alias = alias ,
558+ };
559+
560+ alias -> from_sysfs = true;
525561 if (pmu -> events_table ) {
526562 if (pmu_events_table__find_event (pmu -> events_table , pmu , name ,
527- update_alias , alias ) == 0 )
563+ update_alias , & data ) == 0 )
528564 pmu -> loaded_json_aliases ++ ;
529565 }
530566 }
@@ -612,7 +648,7 @@ static int pmu_aliases_parse(struct perf_pmu *pmu, int dirfd)
612648 continue ;
613649 }
614650
615- if (perf_pmu__new_alias (pmu , dirfd , name , /*desc=*/ NULL ,
651+ if (perf_pmu__new_alias (pmu , name , /*desc=*/ NULL ,
616652 /*val=*/ NULL , file , /*pe=*/ NULL ) < 0 )
617653 pr_debug ("Cannot set up %s\n" , name );
618654 fclose (file );
@@ -865,7 +901,7 @@ static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe,
865901{
866902 struct perf_pmu * pmu = vdata ;
867903
868- perf_pmu__new_alias (pmu , -1 , pe -> name , pe -> desc , pe -> event , /*val_fd=*/ NULL , pe );
904+ perf_pmu__new_alias (pmu , pe -> name , pe -> desc , pe -> event , /*val_fd=*/ NULL , pe );
869905 return 0 ;
870906}
871907
@@ -901,7 +937,7 @@ static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe,
901937
902938 if (!strcmp (pmu -> id , pe -> compat ) &&
903939 pmu_uncore_alias_match (pe -> pmu , pmu -> name )) {
904- perf_pmu__new_alias (pmu , -1 ,
940+ perf_pmu__new_alias (pmu ,
905941 pe -> name ,
906942 pe -> desc ,
907943 pe -> event ,
@@ -1417,11 +1453,13 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
14171453}
14181454
14191455
1420- static int check_info_data (struct perf_pmu_alias * alias ,
1456+ static int check_info_data (struct perf_pmu * pmu ,
1457+ struct perf_pmu_alias * alias ,
14211458 struct perf_pmu_info * info ,
14221459 struct parse_events_error * err ,
14231460 int column )
14241461{
1462+ read_alias_info (pmu , alias );
14251463 /*
14261464 * Only one term in event definition can
14271465 * define unit, scale and snapshot, fail
@@ -1491,7 +1529,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
14911529 return ret ;
14921530 }
14931531
1494- ret = check_info_data (alias , info , err , term -> err_term );
1532+ ret = check_info_data (pmu , alias , info , err , term -> err_term );
14951533 if (ret )
14961534 return ret ;
14971535
0 commit comments