Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cb7d3ec authored by Thomas Richter's avatar Thomas Richter Committed by Arnaldo Carvalho de Melo
Browse files

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: default avatarThomas Richter <tmricht@linux.vnet.ibm.com>
Reviewed-by: default avatarHendrik 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent c59124fa
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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));
}
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+29 −18
Original line number Diff line number Diff line
@@ -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,32 +638,15 @@ 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;
}