From: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
To: Ashutosh Dixit <ashutosh.dixit@intel.com>
Cc: <igt-dev@lists.freedesktop.org>
Subject: Re: [PATCH i-g-t 23/28] tools/xe-perf: xe_perf_reader, xe_perf_control and xe_perf_configs
Date: Thu, 20 Jun 2024 16:41:25 -0700 [thread overview]
Message-ID: <ZnS+JZ3SnQACfRfe@orsosgc001> (raw)
In-Reply-To: <20240620200054.3550653-24-ashutosh.dixit@intel.com>
On Thu, Jun 20, 2024 at 01:00:48PM -0700, Ashutosh Dixit wrote:
>Add xe_perf_reader, xe_perf_control and xe_perf_configs tools, similar to
>their i915 counterparts.
>
>Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
>---
> tools/xe-perf/meson.build | 17 ++
> tools/xe-perf/xe_perf_configs.c | 247 ++++++++++++++++++++++++
> tools/xe-perf/xe_perf_control.c | 117 ++++++++++++
> tools/xe-perf/xe_perf_reader.c | 325 ++++++++++++++++++++++++++++++++
> 4 files changed, 706 insertions(+)
> create mode 100644 tools/xe-perf/xe_perf_configs.c
> create mode 100644 tools/xe-perf/xe_perf_control.c
> create mode 100644 tools/xe-perf/xe_perf_reader.c
>
>diff --git a/tools/xe-perf/meson.build b/tools/xe-perf/meson.build
>index a5f59a67fe..8506aa320f 100644
>--- a/tools/xe-perf/meson.build
>+++ b/tools/xe-perf/meson.build
>@@ -1,5 +1,22 @@
>+executable('xe-perf-configs',
>+ [ 'xe_perf_configs.c' ],
>+ include_directories: inc,
>+ dependencies: [lib_igt_chipset, lib_igt_xe_oa],
>+ install: true)
>+
> executable('xe-perf-recorder',
> [ 'xe_perf_recorder.c' ],
> include_directories: inc,
> dependencies: [lib_igt, lib_igt_xe_oa],
> install: true)
>+
>+executable('xe-perf-control',
>+ [ 'xe_perf_control.c' ],
>+ include_directories: inc,
>+ install: true)
>+
>+executable('xe-perf-reader',
>+ [ 'xe_perf_reader.c' ],
>+ include_directories: inc,
>+ dependencies: [lib_igt, lib_igt_xe_oa],
>+ install: true)
>diff --git a/tools/xe-perf/xe_perf_configs.c b/tools/xe-perf/xe_perf_configs.c
>new file mode 100644
>index 0000000000..af33c0078c
>--- /dev/null
>+++ b/tools/xe-perf/xe_perf_configs.c
>@@ -0,0 +1,247 @@
>+// SPDX-License-Identifier: MIT
>+/*
>+ * Copyright © 2024 Intel Corporation
>+ */
>+
>+
>+#include <assert.h>
>+#include <dirent.h>
>+#include <errno.h>
>+#include <fcntl.h>
>+#include <getopt.h>
>+#include <inttypes.h>
>+#include <stdbool.h>
>+#include <stdint.h>
>+#include <stdio.h>
>+#include <stdlib.h>
>+#include <string.h>
>+#include <sys/ioctl.h>
>+#include <sys/sysmacros.h>
>+#include <sys/types.h>
>+#include <sys/stat.h>
>+#include <unistd.h>
>+
>+#include "intel_chipset.h"
>+#include "xe/xe_oa.h"
>+
>+static bool
>+read_file_uint64(const char *file, uint64_t *value)
>+{
>+ char buf[32];
>+ int fd, n;
>+
>+ fd = open(file, 0);
>+ if (fd < 0)
>+ return false;
>+ n = read(fd, buf, sizeof (buf) - 1);
>+ close(fd);
>+ if (n < 0)
>+ return false;
>+
>+ buf[n] = '\0';
>+ *value = strtoull(buf, 0, 0);
>+
>+ return true;
>+}
>+
>+static uint32_t
>+read_device_param(const char *stem, int id, const char *param)
>+{
>+ char *name;
>+ int ret = asprintf(&name, "/sys/class/drm/%s%u/device/%s", stem, id, param);
>+ uint64_t value;
>+ bool success;
>+
>+ assert(ret != -1);
>+
>+ success = read_file_uint64(name, &value);
>+ free(name);
>+
>+ return success ? value : 0;
>+}
>+
>+static int
>+find_intel_render_node(void)
>+{
>+ for (int i = 128; i < (128 + 16); i++) {
>+ if (read_device_param("renderD", i, "vendor") == 0x8086)
>+ return i;
>+ }
>+
>+ return -1;
>+}
>+
>+static int
>+open_render_node(uint32_t *devid)
>+{
>+ char *name;
>+ int ret;
>+ int fd;
>+
>+ int render = find_intel_render_node();
>+ if (render < 0)
>+ return -1;
>+
>+ ret = asprintf(&name, "/dev/dri/renderD%u", render);
>+ assert(ret != -1);
>+
>+ *devid = read_device_param("renderD", render, "device");
>+
>+ fd = open(name, O_RDWR);
>+ free(name);
>+
>+ return fd;
>+}
>+
>+static int
>+get_card_for_fd(int fd)
>+{
>+ struct stat sb;
>+ int mjr, mnr;
>+ char buffer[128];
>+ DIR *drm_dir;
>+ struct dirent *entry;
>+ int retval = -1;
>+
>+ if (fstat(fd, &sb)) {
>+ fprintf(stderr, "Failed to stat DRM fd\n");
>+ return -1;
>+ }
>+
>+ mjr = major(sb.st_rdev);
>+ mnr = minor(sb.st_rdev);
>+
>+ snprintf(buffer, sizeof(buffer), "/sys/dev/char/%d:%d/device/drm", mjr, mnr);
>+
>+ drm_dir = opendir(buffer);
>+ assert(drm_dir != NULL);
>+
>+ while ((entry = readdir(drm_dir))) {
>+ if (entry->d_type == DT_DIR && strncmp(entry->d_name, "card", 4) == 0) {
>+ retval = strtoull(entry->d_name + 4, NULL, 10);
>+ break;
>+ }
>+ }
>+
>+ closedir(drm_dir);
>+
>+ return retval;
>+}
>+
>+static const char *
>+metric_name(struct intel_xe_perf *perf, const char *hw_config_guid)
>+{
>+ struct intel_xe_perf_metric_set *metric_set;
>+
>+ igt_list_for_each_entry(metric_set, &perf->metric_sets, link) {
>+ if (!strcmp(metric_set->hw_config_guid, hw_config_guid))
>+ return metric_set->symbol_name;
>+ }
>+
>+ return "Unknown";
>+}
>+
>+static void
>+usage(void)
>+{
>+ printf("Usage: xe-perf-configs [options]\n"
>+ "Manages xe-perf configurations stored in xe.\n"
>+ " --purge, -p Purge configurations from the kernel\n"
>+ " --list, -l List configurations from the kernel\n");
>+}
>+
>+int
>+main(int argc, char *argv[])
>+{
>+ char metrics_path[128];
>+ DIR *metrics_dir;
>+ struct dirent *entry;
>+ int drm_fd, drm_card;
>+ int opt;
>+ bool purge = false;
>+ const struct option long_options[] = {
>+ {"help", no_argument, 0, 'h'},
>+ {"list", no_argument, 0, 'l'},
>+ {"purge", no_argument, 0, 'p'},
>+ {0, 0, 0, 0}
>+ };
>+ const struct intel_device_info *devinfo;
>+ struct intel_xe_perf *perf;
>+ uint32_t devid = 0;
>+
>+ while ((opt = getopt_long(argc, argv, "hlp", long_options, NULL)) != -1) {
>+ switch (opt) {
>+ case 'h':
>+ usage();
>+ return EXIT_SUCCESS;
>+ case 'l':
>+ break;
>+ case 'p':
>+ purge = true;
>+ break;
>+ default:
>+ fprintf(stderr, "Internal error: "
>+ "unexpected getopt value: %d\n", opt);
>+ usage();
>+ return EXIT_FAILURE;
>+ }
>+ }
>+
>+ drm_fd = open_render_node(&devid);
>+ drm_card = get_card_for_fd(drm_fd);
>+
>+ fprintf(stdout, "Found device id=0x%x\n", devid);
>+
>+ devinfo = intel_get_device_info(drm_fd);
>+ if (!devinfo) {
>+ fprintf(stderr, "No device info found.\n");
>+ return EXIT_FAILURE;
>+ }
>+
>+ fprintf(stdout, "Device graphics_ver=%i gt=%i\n", devinfo->graphics_ver, devinfo->gt);
>+
>+ perf = intel_xe_perf_for_fd(drm_fd, 0);
>+ if (!perf) {
>+ fprintf(stderr, "No perf data found.\n");
>+ return EXIT_FAILURE;
>+ }
>+
>+ snprintf(metrics_path, sizeof(metrics_path),
>+ "/sys/class/drm/card%d/metrics", drm_card);
>+ metrics_dir = opendir(metrics_path);
>+ if (!metrics_dir)
>+ return EXIT_FAILURE;
>+
>+ fprintf(stdout, "Looking at metrics in %s\n", metrics_path);
>+
>+ while ((entry = readdir(metrics_dir))) {
>+ char metric_id_path[400];
>+ uint64_t metric_id;
>+
>+ if (entry->d_type != DT_DIR)
>+ continue;
>+
>+ snprintf(metric_id_path, sizeof(metric_id_path),
>+ "%s/%s/id", metrics_path, entry->d_name);
>+
>+ if (!read_file_uint64(metric_id_path, &metric_id))
>+ continue;
>+
>+ if (purge) {
>+ if (intel_xe_perf_ioctl(drm_fd, DRM_XE_PERF_OP_REMOVE_CONFIG, &metric_id) == 0)
>+ fprintf(stdout, "\tRemoved config %s id=%03" PRIu64 " name=%s\n",
>+ entry->d_name, metric_id, metric_name(perf, entry->d_name));
>+ else
>+ fprintf(stdout, "\tFailed to remove config %s id=%03" PRIu64 " name=%s\n",
>+ entry->d_name, metric_id, metric_name(perf, entry->d_name));
>+ } else {
>+ fprintf(stdout, "\tConfig %s id=%03" PRIu64 " name=%s\n",
>+ entry->d_name, metric_id, metric_name(perf, entry->d_name));
>+ }
>+ }
>+
>+ closedir(metrics_dir);
>+ close(drm_fd);
>+
>+ return EXIT_SUCCESS;
>+}
>diff --git a/tools/xe-perf/xe_perf_control.c b/tools/xe-perf/xe_perf_control.c
>new file mode 100644
>index 0000000000..da96232bc8
>--- /dev/null
>+++ b/tools/xe-perf/xe_perf_control.c
>@@ -0,0 +1,117 @@
>+// SPDX-License-Identifier: MIT
>+/*
>+ * Copyright © 2024 Intel Corporation
>+ */
>+
>+
>+#include <getopt.h>
>+#include <stdbool.h>
>+#include <stdio.h>
>+#include <stdlib.h>
>+#include <string.h>
>+#include <unistd.h>
>+
>+#include "xe_perf_recorder_commands.h"
>+
>+static void
>+usage(const char *name)
>+{
>+ fprintf(stdout,
>+ "Usage: %s [options]\n"
>+ "\n"
>+ " --help, -h Print this screen\n"
>+ " --command-fifo, -f <path> Path to a command fifo\n"
>+ " --dump, -d <path> Write a content of circular buffer to path\n",
>+ name);
>+}
>+
>+int
>+main(int argc, char *argv[])
>+{
>+ const struct option long_options[] = {
>+ {"help", no_argument, 0, 'h'},
>+ {"dump", required_argument, 0, 'd'},
>+ {"command-fifo", required_argument, 0, 'f'},
>+ {"quit", no_argument, 0, 'q'},
>+ {0, 0, 0, 0}
>+ };
>+ const char *command_fifo = XE_PERF_RECORD_FIFO_PATH, *dump_file = NULL;
>+ FILE *command_fifo_file;
>+ int opt;
>+ bool quit = false;
>+
>+ while ((opt = getopt_long(argc, argv, "hd:f:q", long_options, NULL)) != -1) {
>+ switch (opt) {
>+ case 'h':
>+ usage(argv[0]);
>+ return EXIT_SUCCESS;
>+ case 'd':
>+ dump_file = optarg;
>+ break;
>+ case 'f':
>+ command_fifo = optarg;
>+ break;
>+ case 'q':
>+ quit = true;
>+ break;
>+ default:
>+ fprintf(stderr, "Internal error: "
>+ "unexpected getopt value: %d\n", opt);
>+ usage(argv[0]);
>+ return EXIT_FAILURE;
>+ }
>+ }
>+
>+ if (!command_fifo)
>+ return EXIT_FAILURE;
>+
>+ command_fifo_file = fopen(command_fifo, "r+");
>+ if (!command_fifo_file) {
>+ fprintf(stderr, "Unable to open command file\n");
>+ return EXIT_FAILURE;
>+ }
>+
>+ if (dump_file) {
>+ if (dump_file[0] == '/') {
>+ uint32_t total_len =
>+ sizeof(struct recorder_command_base) + strlen(dump_file) + 1;
>+ struct {
>+ struct recorder_command_base base;
>+ uint8_t dump[];
>+ } *data = malloc(total_len);
>+
>+ data->base.command = RECORDER_COMMAND_DUMP;
>+ data->base.size = total_len;
>+ snprintf((char *) data->dump, strlen(dump_file) + 1, "%s", dump_file);
>+
>+ fwrite(data, total_len, 1, command_fifo_file);
>+ } else {
>+ char *cwd = getcwd(NULL, 0);
>+ uint32_t path_len = strlen(cwd) + 1 + strlen(dump_file) + 1;
>+ uint32_t total_len = sizeof(struct recorder_command_base) + path_len;
>+ struct {
>+ struct recorder_command_base base;
>+ uint8_t dump[];
>+ } *data = malloc(total_len);
>+
>+ data->base.command = RECORDER_COMMAND_DUMP;
>+ data->base.size = total_len;
>+ snprintf((char *) data->dump, path_len, "%s/%s", cwd, dump_file);
>+
>+ fwrite(data, total_len, 1, command_fifo_file);
>+ }
>+ }
>+
>+ if (quit) {
>+ struct recorder_command_base base = {
>+ .command = RECORDER_COMMAND_QUIT,
>+ .size = sizeof(base),
>+ };
>+
>+ fwrite(&base, sizeof(base), 1, command_fifo_file);
>+ }
>+
>+ fclose(command_fifo_file);
>+
>+ return EXIT_SUCCESS;
>+}
>diff --git a/tools/xe-perf/xe_perf_reader.c b/tools/xe-perf/xe_perf_reader.c
>new file mode 100644
>index 0000000000..62a4237ee4
>--- /dev/null
>+++ b/tools/xe-perf/xe_perf_reader.c
>@@ -0,0 +1,325 @@
>+// SPDX-License-Identifier: MIT
>+/*
>+ * Copyright © 2024 Intel Corporation
>+ */
>+
>+#include <assert.h>
>+#include <errno.h>
>+#include <fcntl.h>
>+#include <getopt.h>
>+#include <inttypes.h>
>+#include <stdbool.h>
>+#include <stdint.h>
>+#include <stdio.h>
>+#include <stdlib.h>
>+#include <string.h>
>+#include <sys/types.h>
>+#include <sys/stat.h>
>+#include <unistd.h>
>+
>+#include "igt_core.h"
>+#include "intel_chipset.h"
>+#include "xe/xe_oa.h"
>+#include "xe/xe_oa_data_reader.h"
>+
>+#define MAX(a,b) ((a) > (b) ? (a) : (b))
>+#define MIN(a,b) ((a) > (b) ? (b) : (a))
>+
>+static void
>+usage(void)
>+{
>+ printf("Usage: xe-perf-reader [options] file\n"
>+ "Reads the content of an xe-perf recording.\n"
>+ "\n"
>+ " --help, -h Print this screen\n"
>+ " --counters, -c c1,c2,... List of counters to display values for.\n"
>+ " Use 'all' to display all counters.\n"
>+ " Use 'list' to list available counters.\n"
>+ " --reports, -r Print out data per report.\n");
>+}
>+
>+static struct intel_xe_perf_logical_counter *
>+find_counter(struct intel_xe_perf_metric_set *metric_set,
>+ const char *name)
>+{
>+ for (uint32_t i = 0; i < metric_set->n_counters; i++) {
>+ if (!strcmp(name, metric_set->counters[i].symbol_name)) {
>+ return &metric_set->counters[i];
>+ }
>+ }
>+
>+ return NULL;
>+}
>+
>+static void
>+append_counter(struct intel_xe_perf_logical_counter ***counters,
>+ int32_t *n_counters,
>+ uint32_t *n_allocated_counters,
>+ struct intel_xe_perf_logical_counter *counter)
>+{
>+ if (*n_counters < *n_allocated_counters) {
>+ (*counters)[(*n_counters)++] = counter;
>+ return;
>+ }
>+
>+ *n_allocated_counters = MAX(2, *n_allocated_counters * 2);
>+ *counters = realloc(*counters,
>+ sizeof(struct intel_xe_perf_logical_counter *) *
>+ (*n_allocated_counters));
>+ (*counters)[(*n_counters)++] = counter;
>+}
>+
>+static struct intel_xe_perf_logical_counter **
>+get_logical_counters(struct intel_xe_perf_metric_set *metric_set,
>+ const char *counter_list,
>+ int32_t *out_n_counters)
>+{
>+ struct intel_xe_perf_logical_counter **counters = NULL, *counter;
>+ uint32_t n_allocated_counters = 0;
>+ const char *current, *next;
>+ char counter_name[100];
>+
>+ if (!counter_list) {
>+ *out_n_counters = 0;
>+ return NULL;
>+ }
>+
>+ if (!strcmp(counter_list, "list")) {
>+ uint32_t longest_name = 0;
>+
>+ *out_n_counters = -1;
>+ for (uint32_t i = 0; i < metric_set->n_counters; i++) {
>+ longest_name = MAX(longest_name,
>+ strlen(metric_set->counters[i].symbol_name));
>+ }
>+
>+ fprintf(stdout, "Available counters:\n");
>+ for (uint32_t i = 0; i < metric_set->n_counters; i++) {
>+ fprintf(stdout, "%s:%*s%s\n",
>+ metric_set->counters[i].symbol_name,
>+ (int)(longest_name -
>+ strlen(metric_set->counters[i].symbol_name) + 1), " ",
>+ metric_set->counters[i].name);
>+ }
>+ return NULL;
>+ }
>+
>+ if (!strcmp(counter_list, "all")) {
>+ counters = malloc(sizeof(*counters) * metric_set->n_counters);
>+ *out_n_counters = metric_set->n_counters;
>+ for (uint32_t i = 0; i < metric_set->n_counters; i++)
>+ counters[i] = &metric_set->counters[i];
>+ return counters;
>+ }
>+
>+ *out_n_counters = 0;
>+ current = counter_list;
>+ while ((next = strstr(current, ","))) {
>+ snprintf(counter_name,
>+ MIN((uint32_t)(next - current) + 1, sizeof(counter_name)),
>+ "%s", current);
>+
>+ counter = find_counter(metric_set, counter_name);
>+ if (!counter) {
>+ fprintf(stderr, "Unknown counter '%s'.\n", counter_name);
>+ free(counters);
>+ *out_n_counters = -1;
>+ return NULL;
>+ }
>+
>+ append_counter(&counters, out_n_counters, &n_allocated_counters, counter);
>+
>+ current = next + 1;
>+ }
>+
>+ if (strlen(current) > 0) {
>+ counter = find_counter(metric_set, current);
>+ if (!counter) {
>+ fprintf(stderr, "Unknown counter '%s'.\n", current);
>+ free(counters);
>+ *out_n_counters = -1;
>+ return NULL;
>+ }
>+
>+ append_counter(&counters, out_n_counters, &n_allocated_counters, counter);
>+ }
>+
>+ return counters;
>+}
>+
>+static void
>+print_report_deltas(const struct intel_xe_perf_data_reader *reader,
>+ const struct intel_xe_perf_record_header *xe_report0,
>+ const struct intel_xe_perf_record_header *xe_report1,
>+ struct intel_xe_perf_logical_counter **counters,
>+ uint32_t n_counters)
>+{
>+ struct intel_xe_perf_accumulator accu;
>+
>+ intel_xe_perf_accumulate_reports(&accu,
>+ reader->perf, reader->metric_set,
>+ xe_report0, xe_report1);
>+
>+ for (uint32_t c = 0; c < n_counters; c++) {
>+ struct intel_xe_perf_logical_counter *counter = counters[c];
>+
>+ switch (counter->storage) {
>+ case INTEL_XE_PERF_LOGICAL_COUNTER_STORAGE_UINT64:
>+ case INTEL_XE_PERF_LOGICAL_COUNTER_STORAGE_UINT32:
>+ case INTEL_XE_PERF_LOGICAL_COUNTER_STORAGE_BOOL32:
>+ fprintf(stdout, " %s: %" PRIu64 "\n",
>+ counter->symbol_name, counter->read_uint64(reader->perf,
>+ reader->metric_set,
>+ accu.deltas));
>+ break;
>+ case INTEL_XE_PERF_LOGICAL_COUNTER_STORAGE_DOUBLE:
>+ case INTEL_XE_PERF_LOGICAL_COUNTER_STORAGE_FLOAT:
>+ fprintf(stdout, " %s: %f\n",
>+ counter->symbol_name, counter->read_float(reader->perf,
>+ reader->metric_set,
>+ accu.deltas));
>+ break;
>+ }
>+ }
>+}
>+
>+int
>+main(int argc, char *argv[])
>+{
>+ const struct option long_options[] = {
>+ {"help", no_argument, 0, 'h'},
>+ {"counters", required_argument, 0, 'c'},
>+ {"reports", no_argument, 0, 'r'},
>+ {0, 0, 0, 0}
>+ };
>+ struct intel_xe_perf_data_reader reader;
>+ struct intel_xe_perf_logical_counter **counters;
>+ const struct intel_device_info *devinfo;
>+ const char *counter_names = NULL;
>+ int32_t n_counters;
>+ int fd, opt;
>+ bool print_reports = false;
>+
>+ while ((opt = getopt_long(argc, argv, "hc:r", long_options, NULL)) != -1) {
>+ switch (opt) {
>+ case 'h':
>+ usage();
>+ return EXIT_SUCCESS;
>+ case 'c':
>+ counter_names = optarg;
>+ break;
>+ case 'r':
>+ print_reports = true;
>+ break;
>+ default:
>+ fprintf(stderr, "Internal error: "
>+ "unexpected getopt value: %d\n", opt);
>+ usage();
>+ return EXIT_FAILURE;
>+ }
>+ }
>+
>+ if (optind >= argc) {
>+ fprintf(stderr, "No recording file specified.\n");
>+ return EXIT_FAILURE;
>+ }
>+
>+ fd = open(argv[optind], 0, O_RDONLY);
>+ if (fd < 0) {
>+ fprintf(stderr, "Cannot open '%s': %s.\n",
>+ argv[optind], strerror(errno));
>+ return EXIT_FAILURE;
>+ }
>+
>+ if (!intel_xe_perf_data_reader_init(&reader, fd)) {
>+ fprintf(stderr, "Unable to parse '%s': %s.\n",
>+ argv[optind], reader.error_msg);
>+ return EXIT_FAILURE;
>+ }
>+
>+ counters = get_logical_counters(reader.metric_set, counter_names, &n_counters);
>+ if (n_counters < 0)
>+ goto exit;
>+
>+ devinfo = intel_get_device_info(reader.devinfo.devid);
>+
>+ fprintf(stdout, "Recorded on device=0x%x(%s) graphics_ver=%i\n",
>+ reader.devinfo.devid, devinfo->codename,
>+ reader.devinfo.graphics_ver);
>+ fprintf(stdout, "Metric used : %s (%s) uuid=%s\n",
>+ reader.metric_set->symbol_name, reader.metric_set->name,
>+ reader.metric_set->hw_config_guid);
>+ fprintf(stdout, "Reports: %u\n", reader.n_records);
>+ fprintf(stdout, "Context switches: %u\n", reader.n_timelines);
>+ fprintf(stdout, "Timestamp correlation points: %u\n", reader.n_correlations);
>+
>+ if (reader.n_correlations < 2) {
>+ fprintf(stderr, "Less than 2 CPU/GPU timestamp correlation points.\n");
>+ return EXIT_FAILURE;
>+ }
>+
>+ fprintf(stdout, "Timestamp correlation CPU range: 0x%016"PRIx64"-0x%016"PRIx64"\n",
>+ reader.correlations[0]->cpu_timestamp,
>+ reader.correlations[reader.n_correlations - 1]->cpu_timestamp);
>+ fprintf(stdout, "Timestamp correlation GPU range (64b): 0x%016"PRIx64"-0x%016"PRIx64"\n",
>+ reader.correlations[0]->gpu_timestamp,
>+ reader.correlations[reader.n_correlations - 1]->gpu_timestamp);
>+ fprintf(stdout, "Timestamp correlation GPU range (32b): 0x%016"PRIx64"-0x%016"PRIx64"\n",
>+ reader.correlations[0]->gpu_timestamp & 0xffffffff,
>+ reader.correlations[reader.n_correlations - 1]->gpu_timestamp & 0xffffffff);
>+
>+ fprintf(stdout, "OA data timestamp range: 0x%016"PRIx64"-0x%016"PRIx64"\n",
>+ intel_xe_perf_read_record_timestamp(reader.perf,
>+ reader.metric_set,
>+ reader.records[0]),
>+ intel_xe_perf_read_record_timestamp(reader.perf,
>+ reader.metric_set,
>+ reader.records[reader.n_records - 1]));
>+ fprintf(stdout, "OA raw data timestamp range: 0x%016"PRIx64"-0x%016"PRIx64"\n",
>+ intel_xe_perf_read_record_timestamp_raw(reader.perf,
>+ reader.metric_set,
>+ reader.records[0]),
>+ intel_xe_perf_read_record_timestamp_raw(reader.perf,
>+ reader.metric_set,
>+ reader.records[reader.n_records - 1]));
>+
>+ if (strcmp(reader.metric_set_uuid, reader.metric_set->hw_config_guid)) {
>+ fprintf(stdout,
>+ "WARNING: Recording used a different HW configuration.\n"
>+ "WARNING: This could lead to inconsistent counter values.\n");
>+ }
>+
>+ for (uint32_t i = 0; i < reader.n_timelines; i++) {
>+ const struct intel_xe_perf_timeline_item *item = &reader.timelines[i];
>+
>+ fprintf(stdout, "Time: CPU=0x%016" PRIx64 "-0x%016" PRIx64
>+ " GPU=0x%016" PRIx64 "-0x%016" PRIx64"\n",
>+ item->cpu_ts_start, item->cpu_ts_end,
>+ item->ts_start, item->ts_end);
>+ fprintf(stdout, "hw_id=0x%x %s\n",
>+ item->hw_id, item->hw_id == 0xffffffff ? "(idle)" : "");
>+
>+ print_report_deltas(&reader,
>+ reader.records[item->record_start],
>+ reader.records[item->record_end],
>+ counters, n_counters);
>+
>+ if (print_reports) {
>+ for (uint32_t r = item->record_start; r < item->record_end; r++) {
>+ fprintf(stdout, " report%i = %s\n",
>+ r - item->record_start,
>+ intel_xe_perf_read_report_reason(reader.perf, reader.records[r]));
>+ print_report_deltas(&reader,
>+ reader.records[r],
>+ reader.records[r + 1],
>+ counters, n_counters);
>+ }
>+ }
>+ }
>+
>+ exit:
>+ intel_xe_perf_data_reader_fini(&reader);
>+ close(fd);
>+
>+ return EXIT_SUCCESS;
>+}
>--
>2.41.0
>
next prev parent reply other threads:[~2024-06-20 23:41 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-20 20:00 [PATCH v4 i-g-t 00/28] Intel Xe OA IGT's Ashutosh Dixit
2024-06-20 20:00 ` [PATCH i-g-t 01/28] lib/xe/oa: Import OA metric generation files from i915 Ashutosh Dixit
2024-06-20 21:54 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 02/28] lib/xe/oa: Add LNL metric guids Ashutosh Dixit
2024-06-20 21:54 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 03/28] lib/xe/oa: Add OA LNL metrics (oa_lnl.xml) Ashutosh Dixit
2024-06-20 21:55 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 04/28] lib/xe/oa: Add truncated legacy Xe1 metrics XML's Ashutosh Dixit
2024-06-20 21:57 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 05/28] lib/xe/oa: Generate LNL metrics/registers files Ashutosh Dixit
2024-06-20 21:52 ` Umesh Nerlige Ramappa
2024-06-20 23:05 ` Dixit, Ashutosh
2024-06-20 20:00 ` [PATCH i-g-t 06/28] lib/xe/oa: Switch generated files to Xe namespace Ashutosh Dixit
2024-06-20 23:24 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 07/28] drm-uapi/xe: Sync with Perf/OA changes Ashutosh Dixit
2024-06-20 23:24 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 08/28] lib/xe: Complete xe_oa lib functionality Ashutosh Dixit
2024-06-20 23:24 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 09/28] tests/intel/xe_query: Add OA units query test Ashutosh Dixit
2024-06-20 23:25 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 10/28] tests/intel/xe_oa: Add first tests Ashutosh Dixit
2024-06-20 23:11 ` Umesh Nerlige Ramappa
2024-06-30 22:42 ` Dixit, Ashutosh
2024-06-20 20:00 ` [PATCH i-g-t 11/28] tests/intel/xe_oa: Add some negative tests Ashutosh Dixit
2024-06-20 23:12 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 12/28] tests/intel/xe_oa: Add "oa-formats" subtest Ashutosh Dixit
2024-06-20 23:15 ` Umesh Nerlige Ramappa
2024-06-30 22:43 ` Dixit, Ashutosh
2024-06-20 20:00 ` [PATCH i-g-t 13/28] tests/intel/xe_oa: Add oa exponent tests Ashutosh Dixit
2024-06-20 23:18 ` Umesh Nerlige Ramappa
2024-06-30 22:43 ` Dixit, Ashutosh
2024-06-20 20:00 ` [PATCH i-g-t 14/28] tests/intel/xe_oa: buffer-fill, non-zero-reason, enable-disable Ashutosh Dixit
2024-06-20 23:19 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 15/28] tests/intel/xe_oa: blocking and polling tests Ashutosh Dixit
2024-06-20 23:20 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 16/28] tests/intel/xe_oa: OAR/OAC tests Ashutosh Dixit
2024-06-20 23:46 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 17/28] tests/intel/xe_oa: Exclusive/concurrent access, rc6 and stress open close Ashutosh Dixit
2024-06-20 23:37 ` Umesh Nerlige Ramappa
2024-06-30 22:43 ` Dixit, Ashutosh
2024-06-20 20:00 ` [PATCH i-g-t 18/28] tests/intel/xe_oa: add remove OA config tests Ashutosh Dixit
2024-06-20 23:38 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 19/28] tests/intel/xe_oa: OA buffer mmap tests Ashutosh Dixit
2024-06-20 23:39 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 20/28] tests/intel/xe_oa: Register whitelisting and MMIO trigger tests Ashutosh Dixit
2024-06-20 23:39 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 21/28] lib/xe/oa: Add xe_oa_data_reader to IGT lib Ashutosh Dixit
2024-06-20 23:40 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 22/28] tools/xe-perf: Add xe_perf_recorder Ashutosh Dixit
2024-06-20 23:41 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 23/28] tools/xe-perf: xe_perf_reader, xe_perf_control and xe_perf_configs Ashutosh Dixit
2024-06-20 23:41 ` Umesh Nerlige Ramappa [this message]
2024-06-20 20:00 ` [PATCH i-g-t 24/28] xe/oa: Fix invalid escape warnings Ashutosh Dixit
2024-06-20 23:43 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 25/28] xe/oa/mdapi-xml-convert: Add support for 576B_PEC64LL format Ashutosh Dixit
2024-06-20 23:43 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 26/28] xe/oa: Regenerate oa-lnl.xml now parsing all counters Ashutosh Dixit
2024-06-20 23:43 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 27/28] xe/oa/oa-metricset-codegen: Fix XE_OA_FORMAT_PEC64u64 offsets Ashutosh Dixit
2024-06-20 23:44 ` Umesh Nerlige Ramappa
2024-06-20 20:00 ` [PATCH i-g-t 28/28] HAX: Add Xe OA tests to xe-fast-feedback.testlist Ashutosh Dixit
2024-06-20 23:45 ` Umesh Nerlige Ramappa
2024-06-30 22:43 ` Dixit, Ashutosh
2024-06-20 20:19 ` ✗ GitLab.Pipeline: warning for Intel Xe OA IGT's (rev4) Patchwork
2024-06-20 20:36 ` ✓ CI.xeBAT: success " Patchwork
2024-06-20 20:43 ` ✓ Fi.CI.BAT: " Patchwork
2024-06-20 23:01 ` ✗ CI.xeFULL: failure " Patchwork
2024-06-21 5:51 ` ✗ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZnS+JZ3SnQACfRfe@orsosgc001 \
--to=umesh.nerlige.ramappa@intel.com \
--cc=ashutosh.dixit@intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.