Skip to content

Commit

Permalink
perf vendor events: Use more flexible pattern matching for CPU identi…
Browse files Browse the repository at this point in the history
…fication for mapfile.csv

The powerpc cpuid information includes chip revision information.
Changes between chip revisions are usually minor bug fixes and usually
do not affect the operation of the performance monitoring hardware.

The original mapfile.csv matching requires enumerating every possible
cpuid string.  When a new minor chip revision is produced a new entry
has to be added to the mapfile.csv and the code recompiled to allow perf
to have the implementation specific perf events for this new minor
revision.  For users of various distibutions of Linux having to wait for
a new release of the kernel's perf tool to be built with these trivial
patches is inconvenient.

Using regular expressions rather than exactly string matching of the
entire cpuid string allows developers to write mapfile.csv files that do
not require patches and recompiles for each of these minor version
changes.  If special cases need to be made for some particular versions,
they can be placed earlier in the mapfile.csv file before the more
general matches.

Signed-off-by: William Cohen <wcohen@redhat.com>
Tested-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Shriya <shriyak@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/20171204145728.16792-1-wcohen@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
William Cohen authored and Arnaldo Carvalho de Melo committed Dec 5, 2017
1 parent 0125195 commit fbc2844
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 16 deletions.
12 changes: 2 additions & 10 deletions tools/perf/pmu-events/arch/powerpc/mapfile.csv
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,5 @@
#

# Power8 entries
004b0000,1,power8,core
004b0201,1,power8,core
004c0000,1,power8,core
004d0000,1,power8,core
004d0100,1,power8,core
004d0200,1,power8,core
004c0100,1,power8,core
004e0100,1,power9,core
004e0200,1,power9,core
004e1200,1,power9,core
004[bcd][[:xdigit:]]{4},1,power8,core
004e[[:xdigit:]]{4},1,power9,core
5 changes: 1 addition & 4 deletions tools/perf/pmu-events/arch/x86/mapfile.csv
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ GenuineIntel-6-1E,v2,nehalemep,core
GenuineIntel-6-1F,v2,nehalemep,core
GenuineIntel-6-1A,v2,nehalemep,core
GenuineIntel-6-2E,v2,nehalemex,core
GenuineIntel-6-4E,v24,skylake,core
GenuineIntel-6-5E,v24,skylake,core
GenuineIntel-6-8E,v24,skylake,core
GenuineIntel-6-9E,v24,skylake,core
GenuineIntel-6-[4589]E,v24,skylake,core
GenuineIntel-6-37,v13,silvermont,core
GenuineIntel-6-4D,v13,silvermont,core
GenuineIntel-6-4C,v13,silvermont,core
Expand Down
39 changes: 38 additions & 1 deletion tools/perf/pmu-events/jevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,43 @@ static void fixdesc(char *s)
*e = 0;
}

/* Add escapes for '\' so they are proper C strings. */
static char *fixregex(char *s)
{
int len = 0;
int esc_count = 0;
char *fixed = NULL;
char *p, *q;

/* Count the number of '\' in string */
for (p = s; *p; p++) {
++len;
if (*p == '\\')
++esc_count;
}

if (esc_count == 0)
return s;

/* allocate space for a new string */
fixed = (char *) malloc(len + 1);
if (!fixed)
return NULL;

/* copy over the characters */
q = fixed;
for (p = s; *p; p++) {
if (*p == '\\') {
*q = '\\';
++q;
}
*q = *p;
++q;
}
*q = '\0';
return fixed;
}

static struct msrmap {
const char *num;
const char *pname;
Expand Down Expand Up @@ -648,7 +685,7 @@ static int process_mapfile(FILE *outfp, char *fpath)
}
line[strlen(line)-1] = '\0';

cpuid = strtok_r(p, ",", &save);
cpuid = fixregex(strtok_r(p, ",", &save));
version = strtok_r(NULL, ",", &save);
fname = strtok_r(NULL, ",", &save);
type = strtok_r(NULL, ",", &save);
Expand Down
20 changes: 19 additions & 1 deletion tools/perf/util/pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <dirent.h>
#include <api/fs/fs.h>
#include <locale.h>
#include <regex.h>
#include "util.h"
#include "pmu.h"
#include "parse-events.h"
Expand Down Expand Up @@ -609,14 +610,31 @@ 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 (!strcmp(map->cpuid, cpuid))
if (regcomp(&re, map->cpuid, REG_EXTENDED) != 0) {
/* Warn unable to generate match particular string. */
pr_info("Invalid regular expression %s\n", map->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;
Expand Down

0 comments on commit fbc2844

Please sign in to comment.