Make all the internal necessary changes before we flip the switch.
v2: Use an unlimited number of intel contexts (Chris)
Signed-off-by: Lionel Landwerlin
---
drivers/gpu/drm/i915/i915_perf.c | 584 +++--
drivers/gpu/drm/i915/i915_perf_types.h | 23 +-
2 files changed, 362 insertions(+), 245 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 8b28afb0526e..112bb5bd6665 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -192,6 +192,7 @@
*/
#include
+#include
#include
#include
@@ -329,7 +330,8 @@ static const struct i915_oa_format
gen12_oa_formats[I915_OA_FORMAT_MAX] = {
* @single_context: Whether a single or all gpu contexts should be monitored
* @hold_preemption: Whether the preemption is disabled for the filtered
* context
- * @ctx_handle: A gem ctx handle for use with @single_context
+ * @n_ctx_handles: Length of @ctx_handles
+ * @ctx_handles: An array of gem context handles
* @metrics_set: An ID for an OA unit metric set advertised via sysfs
* @oa_format: An OA unit HW report format
* @oa_periodic: Whether to enable periodic OA unit sampling
@@ -349,9 +351,10 @@ static const struct i915_oa_format
gen12_oa_formats[I915_OA_FORMAT_MAX] = {
struct perf_open_properties {
u32 sample_flags;
- u64 single_context:1;
u64 hold_preemption:1;
- u64 ctx_handle;
+
+ u32 n_ctx_handles;
+ u32 *ctx_handles;
/* OA sampling state */
int metrics_set;
@@ -625,6 +628,21 @@ static int append_oa_sample(struct i915_perf_stream
*stream,
return 0;
}
+static int ctx_id_equal(const void *key, const void *elem)
+{
+ return *((int *) elem) - *((int *) key);
+}
+
+static inline bool ctx_id_match(struct i915_perf_stream *stream,
+ u32 masked_ctx_id)
+{
+ return bsearch(_ctx_id,
+ stream->ctx_ids,
+ stream->n_ctxs,
+ sizeof(*stream->ctx_ids),
+ ctx_id_equal) != NULL;
+}
+
/**
* Copies all buffered OA reports into userspace read() buffer.
* @stream: An i915-perf stream opened for OA metrics
@@ -736,7 +754,7 @@ static int gen8_append_oa_reports(struct i915_perf_stream
*stream,
continue;
}
- ctx_id = report32[2] & stream->specific_ctx_id_mask;
+ ctx_id = report32[2] & stream->ctx_id_mask;
/*
* Squash whatever is in the CTX_ID field if it's marked as
@@ -781,26 +799,33 @@ static int gen8_append_oa_reports(struct i915_perf_stream
*stream,
* switches since it's not-uncommon for periodic samples to
* identify a switch before any 'context switch' report.
*/
- if (!stream->perf->exclusive_stream->ctx ||
- stream->specific_ctx_id == ctx_id ||
- stream->oa_buffer.last_ctx_id == stream->specific_ctx_id ||
- reason & OAREPORT_REASON_CTX_SWITCH) {
-
- /*
-* While filtering for a single context we avoid
-* leaking the IDs of other contexts.
-*/
- if (stream->perf->exclusive_stream->ctx &&
- stream->specific_ctx_id != ctx_id) {
- report32[2] = INVALID_CTX_ID;
- }
-
+ if (!stream->perf->exclusive_stream->n_ctxs) {
ret = append_oa_sample(stream, buf, count, offset,
report);
if (ret)
break;
+ } else {
+ bool ctx_match = ctx_id != INVALID_CTX_ID &&
+ ctx_id_match(stream, ctx_id);
+
+ if (ctx_match ||
+ stream->oa_buffer.last_ctx_match ||
+ reason & OAREPORT_REASON_CTX_SWITCH) {
+
+ /*
+* While filtering for a single context we avoid
+* leaking the IDs of other contexts.
+*/
+ if (!ctx_match)
+ report32[2] = INVALID_CTX_ID;
+
+ ret = append_oa_sample(stream, buf, count,
offset,
+ report);
+ if (ret)
+ break;
+ }
- stream->oa_buffer.last_ctx_id = ctx_id;
+ stream->oa_buffer.last_ctx_match = ctx_match;
}
/*
@@ -1191,138 +1216,163 @@ static int i915_oa_read(struct