perf test: Fix libpfm4 support (63) test error for nested event groups
authorThomas Richter <tmricht@linux.ibm.com>
Mon, 17 May 2021 14:09:31 +0000 (16:09 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 19 May 2021 13:30:37 +0000 (10:30 -0300)
Compiling perf with make LIBPFM4=1 includes libpfm support and
enables test case 63 'Test libpfm4 support'. This test reports an error
on all platforms for subtest 63.2 'test groups of --pfm-events'.
The reported error message is 'nested event groups not supported'

 # ./perf test -F 63
 63: Test libpfm4 support                                            :
 63.1: test of individual --pfm-events                               :
 Error:
 failed to parse event stereolab : event not found
 Error:
 failed to parse event stereolab,instructions : event not found
 Error:
 failed to parse event instructions,stereolab : event not found
  Ok
 63.2: test groups of --pfm-events                                   :
 Error:
 nested event groups not supported    <------ Error message here
 Error:
 failed to parse event {stereolab} : event not found
 Error:
 failed to parse event {instructions,cycles},{instructions,stereolab} :\
 event not found
 Ok
 #

This patch addresses the error message 'nested event groups not supported'.
The root cause is function parse_libpfm_events_option() which parses the
event string '{},{instructions}' and can not handle a leading empty
group notation '{},...'.

The code detects the first (empty) group indicator '{' but does not
terminate group processing on the following group closing character '}'.
So when the second group indicator '{' is detected, the code assumes
a nested group and returns an error.

With the error message fixed, also change the expected event number to
one for the test case to succeed.

While at it also fix a memory leak. In good case the function does not
free the duplicated string given as first parameter.

Output after:
 # ./perf test -F 63
 63: Test libpfm4 support                                            :
 63.1: test of individual --pfm-events                               :
 Error:
 failed to parse event stereolab : event not found
 Error:
 failed to parse event stereolab,instructions : event not found
 Error:
 failed to parse event instructions,stereolab : event not found
  Ok
 63.2: test groups of --pfm-events                                   :
 Error:
 failed to parse event {stereolab} : event not found
 Error:
 failed to parse event {instructions,cycles},{instructions,stereolab} : \
 event not found
  Ok
 #
Error message 'nested event groups not supported' is gone.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-By: Ian Rogers <irogers@google.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Link: http://lore.kernel.org/lkml/20210517140931.2559364-1-tmricht@linux.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/tests/pfm.c
tools/perf/util/pfm.c

index 76a5312..d4b0ef7 100644 (file)
@@ -131,8 +131,8 @@ static int test__pfm_group(void)
                },
                {
                        .events = "{},{instructions}",
-                       .nr_events = 0,
-                       .nr_groups = 0,
+                       .nr_events = 1,
+                       .nr_groups = 1,
                },
                {
                        .events = "{instructions},{instructions}",
index d735acb..6eef6df 100644 (file)
@@ -62,8 +62,16 @@ int parse_libpfm_events_option(const struct option *opt, const char *str,
                }
 
                /* no event */
-               if (*q == '\0')
+               if (*q == '\0') {
+                       if (*sep == '}') {
+                               if (grp_evt < 0) {
+                                       ui__error("cannot close a non-existing event group\n");
+                                       goto error;
+                               }
+                               grp_evt--;
+                       }
                        continue;
+               }
 
                memset(&attr, 0, sizeof(attr));
                event_attr_init(&attr);
@@ -107,6 +115,7 @@ int parse_libpfm_events_option(const struct option *opt, const char *str,
                        grp_evt = -1;
                }
        }
+       free(p_orig);
        return 0;
 error:
        free(p_orig);