@@ -1814,7 +1814,7 @@ struct i915_perf_stream_ops {
* Routine to emit the commands in the command streamer associated
* with the corresponding gpu engine.
*/
- void (*command_stream_hook)(struct drm_i915_gem_request *req);
+ void (*command_stream_hook)(struct drm_i915_gem_request *req, u32 tag);
};
enum i915_perf_stream_state {
@@ -1873,6 +1873,7 @@ struct i915_perf_cs_data_node {
u32 offset;
u32 ctx_id;
u32 pid;
+ u32 tag;
};
struct drm_i915_private {
@@ -2244,6 +2245,7 @@ struct drm_i915_private {
u32 last_ctx_id;
u32 last_pid;
+ u32 last_tag;
struct list_head node_list;
spinlock_t node_list_lock;
} perf;
@@ -3666,7 +3668,7 @@ void i915_oa_legacy_ctx_switch_notify(struct drm_i915_gem_request *req);
void i915_oa_update_reg_state(struct intel_engine_cs *engine,
struct i915_gem_context *ctx,
uint32_t *reg_state);
-void i915_perf_command_stream_hook(struct drm_i915_gem_request *req);
+void i915_perf_command_stream_hook(struct drm_i915_gem_request *req, u32 tag);
/* i915_gem_evict.c */
int __must_check i915_gem_evict_something(struct i915_address_space *vm,
@@ -58,6 +58,7 @@ struct i915_execbuffer_params {
struct intel_engine_cs *engine;
struct i915_gem_context *ctx;
struct drm_i915_gem_request *request;
+ uint32_t tag;
};
struct eb_vmas {
@@ -1523,7 +1524,7 @@ execbuf_submit(struct i915_execbuffer_params *params,
if (exec_len == 0)
exec_len = params->batch->size - params->args_batch_start_offset;
- i915_perf_command_stream_hook(params->request);
+ i915_perf_command_stream_hook(params->request, params->tag);
ret = params->engine->emit_bb_start(params->request,
exec_start, exec_len,
@@ -1531,7 +1532,7 @@ execbuf_submit(struct i915_execbuffer_params *params,
if (ret)
return ret;
- i915_perf_command_stream_hook(params->request);
+ i915_perf_command_stream_hook(params->request, params->tag);
trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags);
@@ -1843,6 +1844,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
params->engine = engine;
params->dispatch_flags = dispatch_flags;
params->ctx = ctx;
+ params->tag = i915_execbuffer2_get_tag(*args);
ret = execbuf_submit(params, args, &eb->vmas);
err_request:
@@ -255,6 +255,7 @@ struct oa_sample_data {
u32 source;
u32 ctx_id;
u32 pid;
+ u32 tag;
const u8 *report;
};
@@ -311,6 +312,7 @@ static const enum intel_engine_id user_ring_map[I915_USER_RINGS + 1] = {
#define SAMPLE_OA_SOURCE_INFO (1<<1)
#define SAMPLE_CTX_ID (1<<2)
#define SAMPLE_PID (1<<3)
+#define SAMPLE_TAG (1<<4)
struct perf_open_properties {
u32 sample_flags;
@@ -335,7 +337,8 @@ struct perf_open_properties {
* perf mutex lock.
*/
-void i915_perf_command_stream_hook(struct drm_i915_gem_request *request)
+void i915_perf_command_stream_hook(struct drm_i915_gem_request *request,
+ u32 tag)
{
struct intel_engine_cs *engine = request->engine;
struct drm_i915_private *dev_priv = engine->i915;
@@ -348,7 +351,7 @@ void i915_perf_command_stream_hook(struct drm_i915_gem_request *request)
list_for_each_entry(stream, &dev_priv->perf.streams, link) {
if ((stream->state == I915_PERF_STREAM_ENABLED) &&
stream->cs_mode)
- stream->ops->command_stream_hook(request);
+ stream->ops->command_stream_hook(request, tag);
}
mutex_unlock(&dev_priv->perf.streams_lock);
}
@@ -462,7 +465,8 @@ out_unlock:
return ret;
}
-static void i915_perf_command_stream_hook_oa(struct drm_i915_gem_request *req)
+static void i915_perf_command_stream_hook_oa(struct drm_i915_gem_request *req,
+ u32 tag)
{
struct drm_i915_private *dev_priv = req->i915;
struct intel_ring *ring = req->ring;
@@ -487,6 +491,7 @@ static void i915_perf_command_stream_hook_oa(struct drm_i915_gem_request *req)
entry->ctx_id = ctx->hw_id;
entry->pid = current->pid;
+ entry->tag = tag;
i915_gem_request_assign(&entry->request, req);
addr = dev_priv->perf.command_stream_buf.vma->node.start +
@@ -744,6 +749,12 @@ static int append_oa_sample(struct i915_perf_stream *stream,
buf += 4;
}
+ if (sample_flags & SAMPLE_TAG) {
+ if (copy_to_user(buf, &data->tag, 4))
+ return -EFAULT;
+ buf += 4;
+ }
+
if (sample_flags & SAMPLE_OA_REPORT) {
if (copy_to_user(buf, data->report, report_size))
return -EFAULT;
@@ -789,6 +800,9 @@ static int append_oa_buffer_sample(struct i915_perf_stream *stream,
if (sample_flags & SAMPLE_PID)
data.pid = dev_priv->perf.last_pid;
+ if (sample_flags & SAMPLE_TAG)
+ data.tag = dev_priv->perf.last_tag;
+
if (sample_flags & SAMPLE_OA_REPORT)
data.report = report;
@@ -1310,6 +1324,11 @@ static int append_oa_rcs_sample(struct i915_perf_stream *stream,
dev_priv->perf.last_pid = node->pid;
}
+ if (sample_flags & SAMPLE_TAG) {
+ data.tag = node->tag;
+ dev_priv->perf.last_tag = node->tag;
+ }
+
if (sample_flags & SAMPLE_OA_REPORT)
data.report = report;
@@ -2144,7 +2163,8 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
struct drm_i915_private *dev_priv = stream->dev_priv;
bool require_oa_unit = props->sample_flags & (SAMPLE_OA_REPORT |
SAMPLE_OA_SOURCE_INFO);
- bool require_cs_mode = props->sample_flags & SAMPLE_PID;
+ bool require_cs_mode = props->sample_flags & (SAMPLE_PID |
+ SAMPLE_TAG);
bool cs_sample_data = props->sample_flags & SAMPLE_OA_REPORT;
int ret;
@@ -2297,7 +2317,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
}
if (require_cs_mode && !props->cs_mode) {
- DRM_ERROR("PID sampling requires a ring to be specified");
+ DRM_ERROR("PID or TAG sampling require a ring to be specified");
ret = -EINVAL;
goto cs_error;
}
@@ -2330,6 +2350,11 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
stream->sample_size += 4;
}
+ if (props->sample_flags & SAMPLE_TAG) {
+ stream->sample_flags |= SAMPLE_TAG;
+ stream->sample_size += 4;
+ }
+
ret = alloc_command_stream_buf(dev_priv);
if (ret)
goto cs_error;
@@ -3005,6 +3030,9 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
case DRM_I915_PERF_PROP_SAMPLE_PID:
props->sample_flags |= SAMPLE_PID;
break;
+ case DRM_I915_PERF_PROP_SAMPLE_TAG:
+ props->sample_flags |= SAMPLE_TAG;
+ break;
case DRM_I915_PERF_PROP_MAX:
BUG();
}
@@ -832,6 +832,11 @@ struct drm_i915_gem_execbuffer2 {
#define i915_execbuffer2_get_context_id(eb2) \
((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
+/* upper 32 bits of rsvd1 field contain tag */
+#define I915_EXEC_TAG_MASK (0xffffffff00000000UL)
+#define i915_execbuffer2_get_tag(eb2) \
+ ((eb2).rsvd1 & I915_EXEC_TAG_MASK)
+
struct drm_i915_gem_pin {
/** Handle of the buffer to be pinned. */
__u32 handle;
@@ -1313,6 +1318,12 @@ enum drm_i915_perf_property_id {
*/
DRM_I915_PERF_PROP_SAMPLE_PID,
+ /**
+ * The value of this property set to 1 requests inclusion of tag in the
+ * perf sample data.
+ */
+ DRM_I915_PERF_PROP_SAMPLE_TAG,
+
DRM_I915_PERF_PROP_MAX /* non-ABI */
};
@@ -1380,6 +1391,7 @@ enum drm_i915_perf_record_type {
* { u32 source_info; } && DRM_I915_PERF_PROP_SAMPLE_OA_SOURCE
* { u32 ctx_id; } && DRM_I915_PERF_PROP_SAMPLE_CTX_ID
* { u32 pid; } && DRM_I915_PERF_PROP_SAMPLE_PID
+ * { u32 tag; } && DRM_I915_PERF_PROP_SAMPLE_TAG
* { u32 oa_report[]; } && DRM_I915_PERF_PROP_SAMPLE_OA
* };
*/