@@ -285,7 +285,8 @@ static struct perf_evsel *
285285__add_event (struct list_head * list , int * idx ,
286286 struct perf_event_attr * attr ,
287287 char * name , struct cpu_map * cpus ,
288- struct list_head * config_terms )
288+ struct list_head * config_terms ,
289+ struct list_head * drv_config_terms )
289290{
290291 struct perf_evsel * evsel ;
291292
@@ -304,6 +305,9 @@ __add_event(struct list_head *list, int *idx,
304305 if (config_terms )
305306 list_splice (config_terms , & evsel -> config_terms );
306307
308+ if (drv_config_terms )
309+ list_splice (drv_config_terms , & evsel -> drv_config_terms );
310+
307311 list_add_tail (& evsel -> node , list );
308312 return evsel ;
309313}
@@ -312,7 +316,8 @@ static int add_event(struct list_head *list, int *idx,
312316 struct perf_event_attr * attr , char * name ,
313317 struct list_head * config_terms )
314318{
315- return __add_event (list , idx , attr , name , NULL , config_terms ) ? 0 : - ENOMEM ;
319+ return __add_event (list , idx , attr , name ,
320+ NULL , config_terms , NULL ) ? 0 : - ENOMEM ;
316321}
317322
318323static int parse_aliases (char * str , const char * names [][PERF_EVSEL__MAX_ALIASES ], int size )
@@ -823,7 +828,8 @@ static int config_term_pmu(struct perf_event_attr *attr,
823828 struct parse_events_term * term ,
824829 struct parse_events_error * err )
825830{
826- if (term -> type_term == PARSE_EVENTS__TERM_TYPE_USER )
831+ if (term -> type_term == PARSE_EVENTS__TERM_TYPE_USER ||
832+ term -> type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG )
827833 /*
828834 * Always succeed for sysfs terms, as we dont know
829835 * at this point what type they need to have.
@@ -869,10 +875,7 @@ static int config_attr(struct perf_event_attr *attr,
869875 return 0 ;
870876}
871877
872- static int get_config_terms (struct list_head * head_config ,
873- struct list_head * head_terms __maybe_unused )
874- {
875- #define ADD_CONFIG_TERM (__type , __name , __val ) \
878+ #define ADD_CONFIG_TERM (__type , __name , __val , __head_terms ) \
876879do { \
877880 struct perf_evsel_config_term *__t; \
878881 \
@@ -883,33 +886,43 @@ do { \
883886 INIT_LIST_HEAD(&__t->list); \
884887 __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \
885888 __t->val.__name = __val; \
886- list_add_tail(&__t->list, head_terms); \
889+ list_add_tail(&__t->list, __head_terms); \
887890} while (0)
888891
892+ static int get_config_terms (struct list_head * head_config ,
893+ struct list_head * head_terms __maybe_unused )
894+ {
889895 struct parse_events_term * term ;
890896
891897 list_for_each_entry (term , head_config , list ) {
892898 switch (term -> type_term ) {
893899 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD :
894- ADD_CONFIG_TERM (PERIOD , period , term -> val .num );
900+ ADD_CONFIG_TERM (PERIOD , period ,
901+ term -> val .num , head_terms );
895902 break ;
896903 case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ :
897- ADD_CONFIG_TERM (FREQ , freq , term -> val .num );
904+ ADD_CONFIG_TERM (FREQ , freq ,
905+ term -> val .num , head_terms );
898906 break ;
899907 case PARSE_EVENTS__TERM_TYPE_TIME :
900- ADD_CONFIG_TERM (TIME , time , term -> val .num );
908+ ADD_CONFIG_TERM (TIME , time ,
909+ term -> val .num , head_terms );
901910 break ;
902911 case PARSE_EVENTS__TERM_TYPE_CALLGRAPH :
903- ADD_CONFIG_TERM (CALLGRAPH , callgraph , term -> val .str );
912+ ADD_CONFIG_TERM (CALLGRAPH , callgraph ,
913+ term -> val .str , head_terms );
904914 break ;
905915 case PARSE_EVENTS__TERM_TYPE_STACKSIZE :
906- ADD_CONFIG_TERM (STACK_USER , stack_user , term -> val .num );
916+ ADD_CONFIG_TERM (STACK_USER , stack_user ,
917+ term -> val .num , head_terms );
907918 break ;
908919 case PARSE_EVENTS__TERM_TYPE_INHERIT :
909- ADD_CONFIG_TERM (INHERIT , inherit , term -> val .num ? 1 : 0 );
920+ ADD_CONFIG_TERM (INHERIT , inherit ,
921+ term -> val .num ? 1 : 0 , head_terms );
910922 break ;
911923 case PARSE_EVENTS__TERM_TYPE_NOINHERIT :
912- ADD_CONFIG_TERM (INHERIT , inherit , term -> val .num ? 0 : 1 );
924+ ADD_CONFIG_TERM (INHERIT , inherit ,
925+ term -> val .num ? 0 : 1 , head_terms );
913926 break ;
914927 default :
915928 break ;
@@ -919,6 +932,21 @@ do { \
919932 return 0 ;
920933}
921934
935+ static int get_drv_config_terms (struct list_head * head_config ,
936+ struct list_head * head_terms )
937+ {
938+ struct parse_events_term * term ;
939+
940+ list_for_each_entry (term , head_config , list ) {
941+ if (term -> type_term != PARSE_EVENTS__TERM_TYPE_DRV_CFG )
942+ continue ;
943+
944+ ADD_CONFIG_TERM (DRV_CFG , drv_cfg , term -> val .str , head_terms );
945+ }
946+
947+ return 0 ;
948+ }
949+
922950int parse_events_add_tracepoint (struct list_head * list , int * idx ,
923951 char * sys , char * event ,
924952 struct parse_events_error * err ,
@@ -989,6 +1017,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
9891017 struct perf_pmu * pmu ;
9901018 struct perf_evsel * evsel ;
9911019 LIST_HEAD (config_terms );
1020+ LIST_HEAD (drv_config_terms );
9921021
9931022 pmu = perf_pmu__find (name );
9941023 if (!pmu )
@@ -1003,7 +1032,8 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
10031032
10041033 if (!head_config ) {
10051034 attr .type = pmu -> type ;
1006- evsel = __add_event (list , & data -> idx , & attr , NULL , pmu -> cpus , NULL );
1035+ evsel = __add_event (list , & data -> idx , & attr ,
1036+ NULL , pmu -> cpus , NULL , NULL );
10071037 return evsel ? 0 : - ENOMEM ;
10081038 }
10091039
@@ -1020,12 +1050,15 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
10201050 if (get_config_terms (head_config , & config_terms ))
10211051 return - ENOMEM ;
10221052
1053+ if (get_drv_config_terms (head_config , & drv_config_terms ))
1054+ return - ENOMEM ;
1055+
10231056 if (perf_pmu__config (pmu , & attr , head_config , data -> error ))
10241057 return - EINVAL ;
10251058
10261059 evsel = __add_event (list , & data -> idx , & attr ,
10271060 pmu_event_name (head_config ), pmu -> cpus ,
1028- & config_terms );
1061+ & config_terms , & drv_config_terms );
10291062 if (evsel ) {
10301063 evsel -> unit = info .unit ;
10311064 evsel -> scale = info .scale ;
0 commit comments