intel/perf: Add intel_perf_stream_read_samples()

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 <lionel.g.landwerlin@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29421>
This commit is contained in:
José Roberto de Souza
2024-05-15 10:57:57 -07:00
committed by Marge Bot
parent 9841aeb6ad
commit a47c5c9eee
6 changed files with 62 additions and 10 deletions

View File

@@ -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");
}

View File

@@ -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;
}

View File

@@ -6,6 +6,7 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
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);

View File

@@ -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;
}
}

View File

@@ -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"

View File

@@ -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;