// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2019 * Author(s): Thomas Richter <tmricht@linux.ibm.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License (version 2 only) * as published by the Free Software Foundation. * * Architecture specific trace_event function. Save event's bc000 raw data * to file. File name is aux.ctr.## where ## stands for the CPU number the * sample was taken from.
*/
/* CPU Measurement Counter Facility raw data is a byte stream. It is 8 byte * aligned and might have trailing padding bytes. * Display the raw data on screen.
*/ staticbool s390_cpumcfdg_testctr(struct perf_sample *sample)
{
size_t len = sample->raw_size, offset = 0; unsignedchar *buf = sample->raw_data; struct cf_trailer_entry *te; struct cf_ctrset_entry *cep, ce;
if (!ctrset_valid(&ce) || offset + ctrset_size(&ce) > len) { /* Raw data for counter sets are always multiple of 8 * bytes. Prepending a 4 bytes size field to the * raw data block in the sample causes the perf tool * to append 4 padding bytes to make the raw data part * of the sample a multiple of eight bytes again. * * If the last entry (trailer) is 4 bytes off the raw * area data end, all is good.
*/ if (len - offset - sizeof(*te) == 4) break;
pr_err("Invalid counter set entry at %zd\n", offset); returnfalse;
}
offset += ctrset_size(&ce);
} returntrue;
}
/* Return starting number of a counter set */ staticint get_counterset_start(int setnr)
{ switch (setnr) { case CPUMF_CTR_SET_BASIC: /* Basic counter set */ return 0; case CPUMF_CTR_SET_USER: /* Problem state counter set */ return 32; case CPUMF_CTR_SET_CRYPTO: /* Crypto counter set */ return 64; case CPUMF_CTR_SET_EXT: /* Extended counter set */ return 128; case CPUMF_CTR_SET_MT_DIAG: /* Diagnostic counter set */ return 448; case PERF_EVENT_PAI_NNPA_ALL: /* PAI NNPA counter set */ case PERF_EVENT_PAI_CRYPTO_ALL: /* PAI CRYPTO counter set */ return setnr; default: return -1;
}
}
struct get_counter_name_data { int wanted; char *result;
};
/* Scan the PMU and extract the logical name of a counter from the event. Input * is the counter set and counter number with in the set. Construct the event * number and use this as key. If they match return the name of this counter. * If no match is found a NULL pointer is returned.
*/ staticchar *get_counter_name(int set, int nr, struct perf_pmu *pmu)
{ struct get_counter_name_data data = {
.wanted = get_counterset_start(set) + nr,
.result = NULL,
};
#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" /* * Check for consistency of PAI_CRYPTO/PAI_NNPA raw data.
*/ struct pai_data { /* Event number and value */
u16 event_nr;
u64 event_val;
} __packed;
#pragma GCC diagnostic pop
/* * Test for valid raw data. At least one PAI event should be in the raw * data section.
*/ staticbool s390_pai_all_test(struct perf_sample *sample)
{
size_t len = sample->raw_size;
/* S390 specific trace event function. Check for PERF_RECORD_SAMPLE events * and if the event was triggered by a * - counter set diagnostic event * - processor activity assist (PAI) crypto counter event * - processor activity assist (PAI) neural network processor assist (NNPA) * counter event * display its raw data. * The function is only invoked when the dump flag -D is set. * * Function evlist__s390_sample_raw() is defined as call back after it has * been verified that the perf.data file was created on s390 platform.
*/ void evlist__s390_sample_raw(struct evlist *evlist, union perf_event *event, struct perf_sample *sample)
{ constchar *pai_name; struct evsel *evsel;
if (event->header.type != PERF_RECORD_SAMPLE) return;
evsel = evlist__event2evsel(evlist, event); if (!evsel) return;
/* Check for raw data in sample */ if (!sample->raw_size || !sample->raw_data) return;
/* Display raw data on screen */ if (evsel->core.attr.config == PERF_EVENT_CPUM_CF_DIAG) { if (!evsel->pmu)
evsel->pmu = perf_pmus__find("cpum_cf"); if (!s390_cpumcfdg_testctr(sample))
pr_err("Invalid counter set data encountered\n"); else
s390_cpumcfdg_dump(evsel->pmu, sample); return;
}
switch (evsel->core.attr.config) { case PERF_EVENT_PAI_NNPA_ALL:
pai_name = "NNPA_ALL"; break; case PERF_EVENT_PAI_CRYPTO_ALL:
pai_name = "CRYPTO_ALL"; break; default: return;
}
if (!s390_pai_all_test(sample)) {
pr_err("Invalid %s raw data encountered\n", pai_name);
} else { if (!evsel->pmu)
evsel->pmu = perf_pmus__find_by_type(evsel->core.attr.type);
s390_pai_all_dump(evsel, sample);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.