Commit-ID:  4cb7d3ecfca90684ad00f893c34a2028fcc5f764
Gitweb:     https://git.kernel.org/tip/4cb7d3ecfca90684ad00f893c34a2028fcc5f764
Author:     Thomas Richter <tmri...@linux.vnet.ibm.com>
AuthorDate: Tue, 13 Feb 2018 16:14:18 +0100
Committer:  Arnaldo Carvalho de Melo <a...@redhat.com>
CommitDate: Fri, 16 Feb 2018 15:16:57 -0300

perf cpuid: Introduce a platform specific cpuid compare function

The function get_cpuid_str() is called by perf_pmu__getcpuid() and on
s390 returns a complete description of the CPU and its capabilities,
which is a comma separated list.

To map the CPU type with the value defined in the
pmu-events/arch/s390/mapfile.csv, introduce an architecture specific
cpuid compare function named strcmp_cpuid_str()

The currently used regex algorithm is defined as the weak default and
will be used if no platform specific one is defined. This matches the
current behavior.

Signed-off-by: Thomas Richter <tmri...@linux.vnet.ibm.com>
Reviewed-by: Hendrik Brueckner <brueck...@linux.vnet.ibm.com>
Cc: Heiko Carstens <heiko.carst...@de.ibm.com>
Cc: Martin Schwidefsky <schwidef...@de.ibm.com>
Link: http://lkml.kernel.org/r/20180213151419.80737-3-tmri...@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 tools/perf/arch/s390/util/header.c | 18 +++++++++++++++
 tools/perf/util/header.h           |  1 +
 tools/perf/util/pmu.c              | 47 +++++++++++++++++++++++---------------
 3 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/tools/perf/arch/s390/util/header.c 
b/tools/perf/arch/s390/util/header.c
index a78064c..231294b 100644
--- a/tools/perf/arch/s390/util/header.c
+++ b/tools/perf/arch/s390/util/header.c
@@ -146,3 +146,21 @@ char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
                zfree(&buf);
        return buf;
 }
+
+/*
+ * Compare the cpuid string returned by get_cpuid() function
+ * with the name generated by the jevents file read from
+ * pmu-events/arch/s390/mapfile.csv.
+ *
+ * Parameter mapcpuid is the cpuid as stored in the
+ * pmu-events/arch/s390/mapfile.csv. This is just the type number.
+ * Parameter cpuid is the cpuid returned by function get_cpuid().
+ */
+int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
+{
+       char *cp = strchr(cpuid, ',');
+
+       if (cp == NULL)
+               return -1;
+       return strncmp(cp + 1, mapcpuid, strlen(mapcpuid));
+}
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index f28aaaa..942bdec 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -174,4 +174,5 @@ int write_padded(struct feat_fd *fd, const void *bf,
 int get_cpuid(char *buffer, size_t sz);
 
 char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused);
+int strcmp_cpuid_str(const char *s1, const char *s2);
 #endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 57e38fd..1111d5b 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -576,6 +576,34 @@ char * __weak get_cpuid_str(struct perf_pmu *pmu 
__maybe_unused)
        return NULL;
 }
 
+/* Return zero when the cpuid from the mapfile.csv matches the
+ * cpuid string generated on this platform.
+ * Otherwise return non-zero.
+ */
+int __weak strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
+{
+       regex_t re;
+       regmatch_t pmatch[1];
+       int match;
+
+       if (regcomp(&re, mapcpuid, REG_EXTENDED) != 0) {
+               /* Warn unable to generate match particular string. */
+               pr_info("Invalid regular expression %s\n", mapcpuid);
+               return 1;
+       }
+
+       match = !regexec(&re, cpuid, 1, pmatch, 0);
+       regfree(&re);
+       if (match) {
+               size_t match_len = (pmatch[0].rm_eo - pmatch[0].rm_so);
+
+               /* Verify the entire string matched. */
+               if (match_len == strlen(cpuid))
+                       return 0;
+       }
+       return 1;
+}
+
 static char *perf_pmu__getcpuid(struct perf_pmu *pmu)
 {
        char *cpuid;
@@ -610,31 +638,14 @@ struct pmu_events_map *perf_pmu__find_map(struct perf_pmu 
*pmu)
 
        i = 0;
        for (;;) {
-               regex_t re;
-               regmatch_t pmatch[1];
-               int match;
-
                map = &pmu_events_map[i++];
                if (!map->table) {
                        map = NULL;
                        break;
                }
 
-               if (regcomp(&re, map->cpuid, REG_EXTENDED) != 0) {
-                       /* Warn unable to generate match particular string. */
-                       pr_info("Invalid regular expression %s\n", map->cpuid);
+               if (!strcmp_cpuid_str(map->cpuid, cpuid))
                        break;
-               }
-
-               match = !regexec(&re, cpuid, 1, pmatch, 0);
-               regfree(&re);
-               if (match) {
-                       size_t match_len = (pmatch[0].rm_eo - pmatch[0].rm_so);
-
-                       /* Verify the entire string matched. */
-                       if (match_len == strlen(cpuid))
-                               break;
-               }
        }
        free(cpuid);
        return map;

Reply via email to