From a47c5c9eee93c5fb2d70800d5b4b07c3583b1947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Wed, 15 May 2024 10:57:57 -0700 Subject: [PATCH] intel/perf: Add intel_perf_stream_read_samples() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because of the differences between i915 and Xe KMD this function is needed to abstract the special handling that Xe KMD needs while reading perf stream. This special handling will be implemented in the next patch. Reviewed-by: Lionel Landwerlin Signed-off-by: José Roberto de Souza Part-of: --- src/intel/ds/intel_pps_driver.cc | 12 +++++++----- src/intel/perf/i915/intel_perf.c | 22 ++++++++++++++++++++++ src/intel/perf/i915/intel_perf.h | 2 ++ src/intel/perf/intel_perf.c | 22 ++++++++++++++++++++++ src/intel/perf/intel_perf.h | 3 +++ src/intel/perf/intel_perf_query.c | 11 ++++++----- 6 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/intel/ds/intel_pps_driver.cc b/src/intel/ds/intel_pps_driver.cc index 9cc5c0c2731..cc64c6e166a 100644 --- a/src/intel/ds/intel_pps_driver.cc +++ b/src/intel/ds/intel_pps_driver.cc @@ -253,17 +253,19 @@ void IntelDriver::read_data_from_metric_set() { assert(metric_buffer.size() >= 1024 && "Metric buffer should have space for reading"); - ssize_t bytes_read = 0; - while ((bytes_read = perf->read_oa_stream(metric_buffer.data() + total_bytes_read, - metric_buffer.size() - total_bytes_read)) > 0 || - errno == EINTR) { + do { + ssize_t bytes_read = perf->read_oa_stream(metric_buffer.data() + total_bytes_read, + metric_buffer.size() - total_bytes_read); + if (bytes_read <= 0) + break; + total_bytes_read += std::max(ssize_t(0), bytes_read); // Increase size of the buffer for the next read if (metric_buffer.size() / 2 < total_bytes_read) { metric_buffer.resize(metric_buffer.size() * 2); } - } + } while (true); assert(total_bytes_read < metric_buffer.size() && "Buffer not big enough"); } diff --git a/src/intel/perf/i915/intel_perf.c b/src/intel/perf/i915/intel_perf.c index 66496e14c80..2277b89d0ce 100644 --- a/src/intel/perf/i915/intel_perf.c +++ b/src/intel/perf/i915/intel_perf.c @@ -210,3 +210,25 @@ i915_oa_metrics_available(struct intel_perf_config *perf, int fd, bool use_regis return i915_perf_oa_available; } + +int +i915_perf_stream_read_samples(int perf_stream_fd, uint8_t *buffer, + size_t buffer_len) +{ + int len; + + if (buffer_len < INTEL_PERF_OA_HEADER_SAMPLE_SIZE) + return -ENOSPC; + + do { + len = read(perf_stream_fd, buffer, buffer_len); + } while (len < 0 && errno == EINTR); + + if (len <= 0) + return len < 0 ? -errno : 0; + + /* works as long drm_i915_perf_record_header and intel_perf_record_header + * definition matches + */ + return len; +} diff --git a/src/intel/perf/i915/intel_perf.h b/src/intel/perf/i915/intel_perf.h index cfa3cbde519..81c4e2189f7 100644 --- a/src/intel/perf/i915/intel_perf.h +++ b/src/intel/perf/i915/intel_perf.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include struct intel_perf_config; @@ -17,6 +18,7 @@ int i915_perf_stream_open(struct intel_perf_config *perf_config, int drm_fd, uint32_t ctx_id, uint64_t metrics_set_id, uint64_t report_format, uint64_t period_exponent, bool hold_preemption, bool enable); +int i915_perf_stream_read_samples(int perf_stream_fd, uint8_t *buffer, size_t buffer_len); struct intel_perf_registers *i915_perf_load_configurations(struct intel_perf_config *perf_cfg, int fd, const char *guid); diff --git a/src/intel/perf/intel_perf.c b/src/intel/perf/intel_perf.c index 9c884a695c7..294e6839d09 100644 --- a/src/intel/perf/intel_perf.c +++ b/src/intel/perf/intel_perf.c @@ -1490,3 +1490,25 @@ intel_perf_stream_open(struct intel_perf_config *perf_config, int drm_fd, return 0; } } + +/* + * Read perf stream samples. + * + * buffer will be filled with multiple struct intel_perf_record_header + data. + * + * Returns 0 if no sample is available, -errno value if a error happened or + * the number of bytes read on success. + */ +int +intel_perf_stream_read_samples(struct intel_perf_config *perf_config, + int perf_stream_fd, uint8_t *buffer, + size_t buffer_len) +{ + switch (perf_config->devinfo->kmd_type) { + case INTEL_KMD_TYPE_I915: + return i915_perf_stream_read_samples(perf_stream_fd, buffer, buffer_len); + default: + unreachable("missing"); + return -1; + } +} diff --git a/src/intel/perf/intel_perf.h b/src/intel/perf/intel_perf.h index 625b03104e6..8a85604fa5a 100644 --- a/src/intel/perf/intel_perf.h +++ b/src/intel/perf/intel_perf.h @@ -588,6 +588,9 @@ int intel_perf_stream_open(struct intel_perf_config *perf_config, int drm_fd, uint32_t ctx_id, uint64_t metrics_set_id, uint64_t period_exponent, bool hold_preemption, bool enable); +int intel_perf_stream_read_samples(struct intel_perf_config *perf_config, + int perf_stream_fd, uint8_t *buffer, + size_t buffer_len); #ifdef __cplusplus } // extern "C" diff --git a/src/intel/perf/intel_perf_query.c b/src/intel/perf/intel_perf_query.c index be7fa7d6802..6070809ed0d 100644 --- a/src/intel/perf/intel_perf_query.c +++ b/src/intel/perf/intel_perf_query.c @@ -944,7 +944,8 @@ intel_perf_read_oa_stream(struct intel_perf_context *perf_ctx, void* buf, size_t nbytes) { - return read(perf_ctx->oa_stream_fd, buf, nbytes); + return intel_perf_stream_read_samples(perf_ctx->perf, perf_ctx->oa_stream_fd, + buf, nbytes); } enum OaReadStatus { @@ -971,9 +972,9 @@ read_oa_samples_until(struct intel_perf_context *perf_ctx, uint32_t offset; int len; - while ((len = read(perf_ctx->oa_stream_fd, buf->buf, - sizeof(buf->buf))) < 0 && errno == EINTR) - ; + len = intel_perf_stream_read_samples(perf_ctx->perf, + perf_ctx->oa_stream_fd, + buf->buf, sizeof(buf->buf)); if (len <= 0) { exec_list_push_tail(&perf_ctx->free_sample_buffers, &buf->link); @@ -986,7 +987,7 @@ read_oa_samples_until(struct intel_perf_context *perf_ctx, return OA_READ_STATUS_ERROR; } - if (errno != EAGAIN) { + if (len != -EAGAIN) { if (sample_read) return OA_READ_STATUS_FINISHED;