@@ -2165,6 +2165,12 @@ struct i915_perf_cs_sample {
* @ctx_id: Context ID associated with this perf sample
*/
u32 ctx_id;
+
+ /**
+ * @pid: PID of the process in context of which the workload was
+ * submitted, pertaining to this perf sample
+ */
+ u32 pid;
};
struct intel_cdclk_state {
@@ -2620,6 +2626,7 @@ struct drm_i915_private {
} command_stream_buf;
u32 last_cmd_stream_ctx_id;
+ u32 last_pid;
struct list_head cs_samples;
spinlock_t sample_lock;
} perf;
@@ -289,6 +289,7 @@
struct oa_sample_data {
u32 source;
u32 ctx_id;
+ u32 pid;
const u8 *report;
};
@@ -342,6 +343,7 @@ struct oa_sample_data {
#define SAMPLE_OA_REPORT (1<<0)
#define SAMPLE_OA_SOURCE_INFO (1<<1)
#define SAMPLE_CTX_ID (1<<2)
+#define SAMPLE_PID (1<<3)
/**
* struct perf_open_properties - for validated properties given to open a stream
@@ -532,6 +534,7 @@ static void i915_perf_command_stream_hook_oa(struct i915_perf_stream *stream,
}
sample->ctx_id = ctx->hw_id;
+ sample->pid = current->pid;
i915_gem_request_assign(&sample->request, request);
insert_perf_sample(dev_priv, sample);
@@ -977,6 +980,12 @@ static int append_oa_sample(struct i915_perf_stream *stream,
buf += 4;
}
+ if (sample_flags & SAMPLE_PID) {
+ if (copy_to_user(buf, &data->pid, 4))
+ return -EFAULT;
+ buf += 4;
+ }
+
if (sample_flags & SAMPLE_OA_REPORT) {
if (copy_to_user(buf, data->report, report_size))
return -EFAULT;
@@ -1013,6 +1022,9 @@ static int append_oa_buffer_sample(struct i915_perf_stream *stream,
if (sample_flags & SAMPLE_CTX_ID)
data.ctx_id = dev_priv->perf.oa.ops.get_ctx_id(stream, report);
+ if (sample_flags & SAMPLE_PID)
+ data.pid = dev_priv->perf.last_pid;
+
if (sample_flags & SAMPLE_OA_REPORT)
data.report = report;
@@ -1589,6 +1601,11 @@ static int append_oa_rcs_sample(struct i915_perf_stream *stream,
dev_priv->perf.last_cmd_stream_ctx_id = node->ctx_id;
}
+ if (sample_flags & SAMPLE_PID) {
+ data.pid = node->pid;
+ dev_priv->perf.last_pid = node->pid;
+ }
+
if (sample_flags & SAMPLE_OA_REPORT)
data.report = report;
@@ -2665,6 +2682,7 @@ 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 cs_sample_data = props->sample_flags & SAMPLE_OA_REPORT;
int ret;
@@ -2790,6 +2808,20 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
if (props->sample_flags & SAMPLE_CTX_ID) {
stream->sample_flags |= SAMPLE_CTX_ID;
stream->sample_size += 4;
+
+ /*
+ * NB: it's meaningful to request SAMPLE_CTX_ID with just CS
+ * mode or periodic OA mode sampling but we don't allow
+ * SAMPLE_CTX_ID without either mode
+ */
+ if (!require_oa_unit)
+ require_cs_mode = true;
+ }
+
+ if (require_cs_mode && !props->cs_mode) {
+ DRM_ERROR("PID sampling requires a ring to be specified");
+ ret = -EINVAL;
+ goto err_enable;
}
if (props->cs_mode) {
@@ -2800,13 +2832,25 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
goto err_enable;
}
- if (!(props->sample_flags & SAMPLE_CTX_ID)) {
+ /*
+ * The only time we should allow enabling CS mode if it's not
+ * strictly required, is if SAMPLE_CTX_ID has been requested
+ * as it's usable with periodic OA or CS sampling.
+ */
+ if (!require_cs_mode &&
+ !(props->sample_flags & SAMPLE_CTX_ID)) {
DRM_ERROR(
"Stream engine given without requesting any CS specific property");
ret = -EINVAL;
goto err_enable;
}
stream->cs_mode = true;
+
+ if (props->sample_flags & SAMPLE_PID) {
+ stream->sample_flags |= SAMPLE_PID;
+ stream->sample_size += 4;
+ }
+
ret = alloc_command_stream_buf(dev_priv);
if (ret)
goto err_enable;
@@ -3601,7 +3645,9 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
case DRM_I915_PERF_PROP_SAMPLE_CTX_ID:
props->sample_flags |= SAMPLE_CTX_ID;
break;
-
+ case DRM_I915_PERF_PROP_SAMPLE_PID:
+ props->sample_flags |= SAMPLE_PID;
+ break;
default:
MISSING_CASE(id);
DRM_DEBUG("Unknown i915 perf property ID\n");
@@ -1373,6 +1373,12 @@ enum drm_i915_perf_property_id {
*/
DRM_I915_PERF_PROP_SAMPLE_CTX_ID,
+ /**
+ * The value of this property set to 1 requests inclusion of pid in the
+ * perf sample data.
+ */
+ DRM_I915_PERF_PROP_SAMPLE_PID,
+
DRM_I915_PERF_PROP_MAX /* non-ABI */
};
@@ -1440,6 +1446,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 oa_report[]; } && DRM_I915_PERF_PROP_SAMPLE_OA
* };
*/