From 736c69379d9484b1785676deef757892213abf39 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 11 May 2022 16:11:37 +0200 Subject: [PATCH] cpumf/pai: Add support for PAI extension 1 NNPA counters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Processor Activity Instrumentation facility (PAI) Extension 1 adds support for the counter set for Neural Network Processing Assist (NNPA) counters. NNPA counter values are appended as raw data to the data report. Signed-off-by: Thomas Richter Reviewed-by: Jan Höppner Signed-off-by: Jan Höppner --- cpumf/man/pai.1 | 52 +++++++++++++++++++++++++++++++++++++++++++++---- cpumf/pai.c | 52 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 89 insertions(+), 15 deletions(-) diff --git a/cpumf/man/pai.1 b/cpumf/man/pai.1 index 2218b293..5893ed6e 100644 --- a/cpumf/man/pai.1 +++ b/cpumf/man/pai.1 @@ -21,6 +21,13 @@ .BR \-c | \-\-crypto [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ] .br \*c +.RB [ \-V ][ \-m | \-\-mapsize +.IR size ] +.RB [ \-i | \-\-interval +.IR ms ] +.BR \-n | \-\-nnpa [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ] +.br +\*c .RB [ \-V ][ \-H | \-\-humantime ][ \-S | \-\-summary "] " \-r | \-\-report " [" \fIfiles\fP ] .br \*c @@ -37,15 +44,25 @@ The \*c command records PAI counters in a ring buffer. \*c can record counter data for all CPUs or for selected CPUs. The main command options are .B \-c -for recording cryptographic CPU instructions and +for recording cryptographic CPU instructions, +.B \-n +for recording NNPA CPU instructions +and .B \-r for reporting. -If both options are omitted, option +If all three options are omitted, option .B \-r is assumed and a message is printed. Recording stores data, by CPU, in files -.I paicrypto., -where specifies the CPU number. +.I paicrypto., +for option +.B \-c +or +.I painnpa., +for option +.B \-n +where specifies the CPU number with leading +zeros. The files are created in the working directory, existing files are overwritten. Reporting evaluates files that are created by recording. @@ -85,6 +102,33 @@ execution. .RE . .TP +.BR \-n ", " \-\-nnpa "\fR[\fIcpulist\fR][:\fIdata\fR]" +Records data for all (default) or a specified list of CPUs. +The CPU list is a comma-separated list of CPU numbers and ranges. +In a range, a hyphen separates the first CPU number +from the last CPU number. +By default \*c lists all CPUs. +.RS +The optional data specification +follows the colon +and determines additional collection of data. +The specification consists of alphabetic +characters that can be upper or lower case: +.IP c|C +Include task rename system calls +.B exec +and +.BR prctl . +.IP f|F +Include task creation and deletion system calls +.B fork +and +.BR exit . +.IP s|S +Include context switch records created by the kernel scheduler. +.RE +. +.TP .BR \-r ", " \-\-report Generates a report from the specified files. Files is a list of blank-separated file names. diff --git a/cpumf/pai.c b/cpumf/pai.c index d16ee707..6610a6f6 100644 --- a/cpumf/pai.c +++ b/cpumf/pai.c @@ -42,6 +42,7 @@ #include "pai.h" #define S390_EVT_PAI_CRYPTO 0x1000 +#define S390_EVT_PAI_NNPA 0x1800 /* Default values for select() timeout: 1 second */ static unsigned long read_interval = 1000; @@ -104,7 +105,18 @@ static void ev_alloc(int enr, int cpu, int flags) event->flags = flags; event->attr.size = sizeof(event->attr); event->attr.config = enr; - event->attr.type = libcpumf_pmutype(S390_SYSFS_PAI_CRYPTO); + switch (enr) { + case S390_EVT_PAI_CRYPTO: + event->attr.type = libcpumf_pmutype(S390_SYSFS_PAI_CRYPTO); + break; + case S390_EVT_PAI_NNPA: + if ((flags & as)) { + warnx("NNPA does not support kernel/user space selector"); + flags &= ~as; + } + event->attr.type = libcpumf_pmutype(S390_SYSFS_PAI_NNPA); + break; + } event->attr.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_CPU | PERF_SAMPLE_TIME | PERF_SAMPLE_RAW; event->attr.disabled = 1; @@ -120,7 +132,7 @@ static void ev_alloc(int enr, int cpu, int flags) event->attr.comm = 1; event->attr.comm_exec = 1; } - if ((flags & as) != as) { + if ((flags & as) != as && enr == S390_EVT_PAI_CRYPTO) { /* User space or kernel space selector */ if (flags & S390_EVTATTR_USERSPACE) event->attr.exclude_kernel = 1; @@ -129,8 +141,8 @@ static void ev_alloc(int enr, int cpu, int flags) } event->cpu = cpu; event->map_size = mapsize; - snprintf(event->file_name, sizeof(event->file_name), - "paicrypto.%03d", cpu); + snprintf(event->file_name, sizeof(event->file_name), "pai%s.%03d", + enr == S390_EVT_PAI_CRYPTO ? "crypto" : "nnpa", cpu); ev_merge(event); } @@ -914,6 +926,11 @@ static struct util_opt opt_vec[] = { .argument = "CPULIST[:DATA]", .desc = "Collect PAI crypto counters" }, + { + .option = { "nnpa", optional_argument, NULL, 'n' }, + .argument = "CPULIST[:DATA]", + .desc = "Collect PAI nnpa counters" + }, { .option = { "mapsize", required_argument, NULL, 'm' }, .argument = "SIZE", @@ -957,13 +974,20 @@ static const struct util_prg prg = { } }; -static void record_cpus(const char *cp) +static void record_cpus_crypto(const char *cp) { if (!libcpumf_have_pai_crypto()) errx(EXIT_FAILURE, "No support for PAI crypto counters"); parse_cpulist(S390_EVT_PAI_CRYPTO, cp); } +static void record_cpus_nnpa(const char *cp) +{ + if (!libcpumf_have_pai_nnpa()) + errx(EXIT_FAILURE, "No support for PAI nnpa counters"); + parse_cpulist(S390_EVT_PAI_NNPA, cp); +} + /* Mapsize must be power of 2 and larger than 4. Count bits in n and * return 0 if input is invalid and has a bit count larger than one. */ @@ -981,7 +1005,8 @@ static unsigned long check_mapsize(unsigned long n) int main(int argc, char **argv) { - bool record = false, report = false, summary = false; + bool crypto_record = false, report = false, summary = false; + bool nnpa_record = false; unsigned long loop_count = 1; int ch, group = 0; char *slash; @@ -1012,8 +1037,8 @@ int main(int argc, char **argv) util_prg_print_version(); return EXIT_SUCCESS; case 'c': - record_cpus(optarg); - record = true; + record_cpus_crypto(optarg); + crypto_record = true; break; case 'i': errno = 0; @@ -1028,6 +1053,10 @@ int main(int argc, char **argv) if (errno || !mapsize || *slash) errx(EXIT_FAILURE, "Invalid argument for -%c", ch); break; + case 'n': + record_cpus_nnpa(optarg); + nnpa_record = true; + break; case 'r': report = true; break; @@ -1044,11 +1073,12 @@ int main(int argc, char **argv) } /* Without options do report on all files */ - if (!record && !report) { + if (!crypto_record && !nnpa_record && !report) { warnx("No action specified assume report"); report = true; } - if (record) { + + if (crypto_record || nnpa_record) { /* In record mode command line parameter is run-time */ if (optind < argc) { errno = 0; @@ -1076,7 +1106,7 @@ int main(int argc, char **argv) } else { /* Scan files in local directory */ struct dirent **de_vec; int count = util_scandir(&de_vec, alphasort, ".", - "paicrypto.[0-9]+"); + "pai(crypto|nnpa).[0-9]+"); for (int i = 0; i < count; i++) if (de_vec[i]->d_type == DT_REG) ch += map_check(de_vec[i]->d_name, evt_scan);