9
9
#include <linux/zalloc.h>
10
10
#include "debug.h"
11
11
#include "../pmu-events/pmu-events.h"
12
+ #include <perf/evlist.h>
12
13
#include "util/evlist.h"
13
14
#include "util/expr.h"
14
15
#include "util/parse-events.h"
15
16
#include "metricgroup.h"
17
+ #include "stat.h"
16
18
17
19
struct perf_pmu_test_event {
18
20
/* used for matching against events from generated pmu-events.c */
@@ -801,27 +803,6 @@ static int check_parse_id(const char *id, struct parse_events_error *error,
801
803
return ret ;
802
804
}
803
805
804
- static int check_parse_cpu (const char * id , bool same_cpu , const struct pmu_event * pe )
805
- {
806
- struct parse_events_error error ;
807
- int ret ;
808
-
809
- parse_events_error__init (& error );
810
- ret = check_parse_id (id , & error , NULL );
811
- if (ret && same_cpu ) {
812
- pr_warning ("Parse event failed metric '%s' id '%s' expr '%s'\n" ,
813
- pe -> metric_name , id , pe -> metric_expr );
814
- pr_warning ("Error string '%s' help '%s'\n" , error .str ,
815
- error .help );
816
- } else if (ret ) {
817
- pr_debug3 ("Parse event failed, but for an event that may not be supported by this CPU.\nid '%s' metric '%s' expr '%s'\n" ,
818
- id , pe -> metric_name , pe -> metric_expr );
819
- ret = 0 ;
820
- }
821
- parse_events_error__exit (& error );
822
- return ret ;
823
- }
824
-
825
806
static int check_parse_fake (const char * id )
826
807
{
827
808
struct parse_events_error error ;
@@ -838,160 +819,111 @@ struct metric {
838
819
struct metric_ref metric_ref ;
839
820
};
840
821
841
- static int resolve_metric_simple (struct expr_parse_ctx * pctx ,
842
- struct list_head * compound_list ,
843
- const struct pmu_event * map ,
844
- const char * metric_name )
845
- {
846
- struct hashmap_entry * cur , * cur_tmp ;
847
- struct metric * metric , * tmp ;
848
- size_t bkt ;
849
- bool all ;
850
- int rc ;
851
-
852
- do {
853
- all = true;
854
- hashmap__for_each_entry_safe (pctx -> ids , cur , cur_tmp , bkt ) {
855
- struct metric_ref * ref ;
856
- const struct pmu_event * pe ;
857
-
858
- pe = metricgroup__find_metric (cur -> key , map );
859
- if (!pe )
860
- continue ;
861
-
862
- if (!strcmp (metric_name , (char * )cur -> key )) {
863
- pr_warning ("Recursion detected for metric %s\n" , metric_name );
864
- rc = -1 ;
865
- goto out_err ;
866
- }
867
-
868
- all = false;
869
-
870
- /* The metric key itself needs to go out.. */
871
- expr__del_id (pctx , cur -> key );
872
-
873
- metric = malloc (sizeof (* metric ));
874
- if (!metric ) {
875
- rc = - ENOMEM ;
876
- goto out_err ;
877
- }
878
-
879
- ref = & metric -> metric_ref ;
880
- ref -> metric_name = pe -> metric_name ;
881
- ref -> metric_expr = pe -> metric_expr ;
882
- list_add_tail (& metric -> list , compound_list );
883
-
884
- rc = expr__find_ids (pe -> metric_expr , NULL , pctx );
885
- if (rc )
886
- goto out_err ;
887
- break ; /* The hashmap has been modified, so restart */
888
- }
889
- } while (!all );
890
-
891
- return 0 ;
892
-
893
- out_err :
894
- list_for_each_entry_safe (metric , tmp , compound_list , list )
895
- free (metric );
896
-
897
- return rc ;
898
-
899
- }
900
-
901
- static void expr_failure (const char * msg , const struct pmu_event * pe )
902
- {
903
- pr_debug ("%s\nOn metric %s\nOn expression %s\n" , msg , pe -> metric_name , pe -> metric_expr );
904
- }
905
-
906
-
907
- struct test__parsing_data {
908
- const struct pmu_event * cpus_table ;
909
- struct expr_parse_ctx * ctx ;
910
- int failures ;
911
- };
912
-
913
822
static int test__parsing_callback (const struct pmu_event * pe , const struct pmu_event * table ,
914
- void * vdata )
823
+ void * data )
915
824
{
916
- struct test__parsing_data * data = vdata ;
917
- struct metric * metric , * tmp ;
918
- struct hashmap_entry * cur ;
919
- LIST_HEAD (compound_list );
920
- size_t bkt ;
825
+ int * failures = data ;
921
826
int k ;
922
- double result ;
827
+ struct evlist * evlist ;
828
+ struct perf_cpu_map * cpus ;
829
+ struct runtime_stat st ;
830
+ struct evsel * evsel ;
831
+ struct rblist metric_events = {
832
+ .nr_entries = 0 ,
833
+ };
834
+ int err = 0 ;
923
835
924
836
if (!pe -> metric_expr )
925
837
return 0 ;
926
838
927
839
pr_debug ("Found metric '%s'\n" , pe -> metric_name );
840
+ (* failures )++ ;
928
841
929
- expr__ctx_clear (data -> ctx );
930
- if (expr__find_ids (pe -> metric_expr , NULL , data -> ctx ) < 0 ) {
931
- expr_failure ("Parse find ids failed" , pe );
932
- data -> failures ++ ;
933
- return 0 ;
842
+ /*
843
+ * We need to prepare evlist for stat mode running on CPU 0
844
+ * because that's where all the stats are going to be created.
845
+ */
846
+ evlist = evlist__new ();
847
+ if (!evlist )
848
+ return - ENOMEM ;
849
+
850
+ cpus = perf_cpu_map__new ("0" );
851
+ if (!cpus ) {
852
+ evlist__delete (evlist );
853
+ return - ENOMEM ;
934
854
}
935
855
936
- if (resolve_metric_simple (data -> ctx , & compound_list , table ,
937
- pe -> metric_name )) {
938
- expr_failure ("Could not resolve metrics" , pe );
939
- data -> failures ++ ;
940
- return TEST_FAIL ; /* Don't tolerate errors due to severity */
856
+ perf_evlist__set_maps (& evlist -> core , cpus , NULL );
857
+ runtime_stat__init (& st );
858
+
859
+ err = metricgroup__parse_groups_test (evlist , table , pe -> metric_name ,
860
+ false, false,
861
+ & metric_events );
862
+ if (err ) {
863
+ if (!strcmp (pe -> metric_name , "M1" ) || !strcmp (pe -> metric_name , "M2" ) ||
864
+ !strcmp (pe -> metric_name , "M3" )) {
865
+ (* failures )-- ;
866
+ pr_debug ("Expected broken metric %s skipping\n" , pe -> metric_name );
867
+ err = 0 ;
868
+ }
869
+ goto out_err ;
941
870
}
942
871
872
+ err = evlist__alloc_stats (evlist , false);
873
+ if (err )
874
+ goto out_err ;
943
875
/*
944
876
* Add all ids with a made up value. The value may trigger divide by
945
877
* zero when subtracted and so try to make them unique.
946
878
*/
947
879
k = 1 ;
948
- hashmap__for_each_entry ( data -> ctx -> ids , cur , bkt )
949
- expr__add_id_val ( data -> ctx , strdup ( cur -> key ), k ++ );
950
-
951
- hashmap__for_each_entry ( data -> ctx -> ids , cur , bkt ) {
952
- if ( check_parse_cpu ( cur -> key , table == data -> cpus_table , pe ))
953
- data -> failures ++ ;
880
+ perf_stat__reset_shadow_stats ();
881
+ evlist__for_each_entry ( evlist , evsel ) {
882
+ perf_stat__update_shadow_stats ( evsel , k , 0 , & st );
883
+ if (! strcmp ( evsel -> name , "duration_time" ))
884
+ update_stats ( & walltime_nsecs_stats , k );
885
+ k ++ ;
954
886
}
887
+ evlist__for_each_entry (evlist , evsel ) {
888
+ struct metric_event * me = metricgroup__lookup (& metric_events , evsel , false);
955
889
956
- list_for_each_entry_safe (metric , tmp , & compound_list , list ) {
957
- expr__add_ref (data -> ctx , & metric -> metric_ref );
958
- free (metric );
959
- }
890
+ if (me != NULL ) {
891
+ struct metric_expr * mexp ;
960
892
961
- if (expr__parse (& result , data -> ctx , pe -> metric_expr )) {
962
- /*
963
- * Parsing failed, make numbers go from large to small which can
964
- * resolve divide by zero issues.
965
- */
966
- k = 1024 ;
967
- hashmap__for_each_entry (data -> ctx -> ids , cur , bkt )
968
- expr__add_id_val (data -> ctx , strdup (cur -> key ), k -- );
969
- if (expr__parse (& result , data -> ctx , pe -> metric_expr )) {
970
- expr_failure ("Parse failed" , pe );
971
- data -> failures ++ ;
893
+ list_for_each_entry (mexp , & me -> head , nd ) {
894
+ if (strcmp (mexp -> metric_name , pe -> metric_name ))
895
+ continue ;
896
+ pr_debug ("Result %f\n" , test_generic_metric (mexp , 0 , & st ));
897
+ err = 0 ;
898
+ (* failures )-- ;
899
+ goto out_err ;
900
+ }
972
901
}
973
902
}
974
- return 0 ;
903
+ pr_debug ("Didn't find parsed metric %s" , pe -> metric_name );
904
+ err = 1 ;
905
+ out_err :
906
+ if (err )
907
+ pr_debug ("Broken metric %s\n" , pe -> metric_name );
908
+
909
+ /* ... cleanup. */
910
+ metricgroup__rblist_exit (& metric_events );
911
+ runtime_stat__exit (& st );
912
+ evlist__free_stats (evlist );
913
+ perf_cpu_map__put (cpus );
914
+ evlist__delete (evlist );
915
+ return err ;
975
916
}
976
917
977
918
static int test__parsing (struct test_suite * test __maybe_unused ,
978
919
int subtest __maybe_unused )
979
920
{
980
- struct test__parsing_data data = {
981
- .cpus_table = pmu_events_table__find (),
982
- .ctx = expr__ctx_new (),
983
- .failures = 0 ,
984
- };
921
+ int failures = 0 ;
985
922
986
- if (!data .ctx ) {
987
- pr_debug ("expr__ctx_new failed" );
988
- return TEST_FAIL ;
989
- }
990
- pmu_for_each_core_event (test__parsing_callback , & data );
991
- pmu_for_each_sys_event (test__parsing_callback , & data );
923
+ pmu_for_each_core_event (test__parsing_callback , & failures );
924
+ pmu_for_each_sys_event (test__parsing_callback , & failures );
992
925
993
- expr__ctx_free (data .ctx );
994
- return data .failures == 0 ? TEST_OK : TEST_FAIL ;
926
+ return failures == 0 ? TEST_OK : TEST_FAIL ;
995
927
}
996
928
997
929
struct test_metric {
0 commit comments