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 <tmricht@linux.vnet.ibm.com> Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Link: http://lkml.kernel.org/r/20180213151419.80737-3-tmricht@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Родитель
c59124fa59
Коммит
4cb7d3ecfc
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче