Add arch_record__collect_final_data to collect additional data before closing the event. Define the callback in util/powerpc-htm.c
Invoke record__mmap_read_all till the complete trace data is collected in auxtrace buffer and copied to perf.data . When the auxtrace buffer is full, perf_aux_output_end will disable the event till data is written. Hence enable the event using evlist__enable after reading event using htm_read_data function. The perf_evsel__read returns zero, when the trace data is completely read and completed. If the count returns zero for the event, stop the data collection. Signed-off-by: Athira Rajeev <[email protected]> --- tools/perf/util/Build | 1 + tools/perf/util/powerpc-htm.c | 74 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 tools/perf/util/powerpc-htm.c diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 330311cac550..7fa354853d2a 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -141,6 +141,7 @@ perf-util-y += hisi-ptt.o perf-util-y += hisi-ptt-decoder/ perf-util-y += s390-cpumsf.o perf-util-y += powerpc-vpadtl.o +perf-util-y += powerpc-htm.o ifdef CONFIG_LIBOPENCSD perf-util-y += cs-etm.o diff --git a/tools/perf/util/powerpc-htm.c b/tools/perf/util/powerpc-htm.c new file mode 100644 index 000000000000..5043ff41a609 --- /dev/null +++ b/tools/perf/util/powerpc-htm.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * HTM support + */ + +#include "../../../util/record.h" +#include "evlist.h" +#include "evsel.h" +#include "session.h" +#include "debug.h" +#include <internal/xyarray.h> + +/* + * Check if HTM events have more data to collect. + * + * This function reads the HTM event counts. When the kernel driver + * has more data available, it returns a non-zero count. When all + * data has been collected, it returns zero. + * + * Returns: 1 if more data exists, 0 if collection is complete + */ +int arch_perf_record__need_read(struct evlist *evlist) +{ + struct evsel *evsel; + int found_htm = 0; + + /* there was an error during record__open */ + if (!evlist) + return 0; + + /* First, check if any HTM events exist */ + evlist__for_each_entry(evlist, evsel) { + if (strstr(evsel->name, "htm") != NULL) + found_htm = 1; + } + + if (!found_htm) + return 0; + + /* Read HTM event counts to check if more data is available */ + evlist__for_each_entry(evlist, evsel) { + struct xyarray *xy = evsel->core.sample_id; + + if (strstr(evsel->name, "htm") == NULL) + continue; + + if (xy == NULL || evsel->core.fd == NULL) + continue; + if (xyarray__max_x(evsel->core.fd) != xyarray__max_x(xy) || + xyarray__max_y(evsel->core.fd) != xyarray__max_y(xy)) { + pr_debug("Unmatched FD vs. sample ID: skip reading LOST count\n"); + continue; + } + + for (int x = 0; x < xyarray__max_x(xy); x++) { + for (int y = 0; y < xyarray__max_y(xy); y++) { + struct perf_counts_values count; + + if (!strcmp(evsel->name, "dummy:u")) + continue; + + if (strstr(evsel->name, "htm")) { + perf_evsel__read(&evsel->core, x, y, &count); + y = xyarray__max_y(xy); + x = xyarray__max_x(xy); + } + if (!count.val) + return 0; + } + } + } + + return 1; +} -- 2.52.0
