]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/xe/oa/uapi: Allow preemption to be disabled on the stream exec queue
authorAshutosh Dixit <ashutosh.dixit@intel.com>
Wed, 26 Jun 2024 18:18:17 +0000 (11:18 -0700)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Wed, 26 Jun 2024 22:25:46 +0000 (18:25 -0400)
Mesa VK_KHR_performance_query use case requires preemption and timeslicing
to be disabled for the stream exec queue. Implement this functionality
here.

v2: Minor change to debug print to print both ret values (Umesh)

Acked-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240626181817.1516229-3-ashutosh.dixit@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_oa.c
drivers/gpu/drm/xe/xe_oa_types.h
include/uapi/drm/xe_drm.h

index a68659fd5386067d3bb44f9fea9802b5e08ae178..6cc3f02173418062682ac6d651497df582221e41 100644 (file)
@@ -80,6 +80,7 @@ struct xe_oa_open_param {
        int engine_instance;
        struct xe_exec_queue *exec_q;
        struct xe_hw_engine *hwe;
+       bool no_preempt;
 };
 
 struct xe_oa_config_bo {
@@ -1013,11 +1014,55 @@ static void xe_oa_stream_disable(struct xe_oa_stream *stream)
                hrtimer_cancel(&stream->poll_check_timer);
 }
 
+static int xe_oa_enable_preempt_timeslice(struct xe_oa_stream *stream)
+{
+       struct xe_exec_queue *q = stream->exec_q;
+       int ret1, ret2;
+
+       /* Best effort recovery: try to revert both to original, irrespective of error */
+       ret1 = q->ops->set_timeslice(q, stream->hwe->eclass->sched_props.timeslice_us);
+       ret2 = q->ops->set_preempt_timeout(q, stream->hwe->eclass->sched_props.preempt_timeout_us);
+       if (ret1 || ret2)
+               goto err;
+       return 0;
+err:
+       drm_dbg(&stream->oa->xe->drm, "%s failed ret1 %d ret2 %d\n", __func__, ret1, ret2);
+       return ret1 ?: ret2;
+}
+
+static int xe_oa_disable_preempt_timeslice(struct xe_oa_stream *stream)
+{
+       struct xe_exec_queue *q = stream->exec_q;
+       int ret;
+
+       /* Setting values to 0 will disable timeslice and preempt_timeout */
+       ret = q->ops->set_timeslice(q, 0);
+       if (ret)
+               goto err;
+
+       ret = q->ops->set_preempt_timeout(q, 0);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       xe_oa_enable_preempt_timeslice(stream);
+       drm_dbg(&stream->oa->xe->drm, "%s failed %d\n", __func__, ret);
+       return ret;
+}
+
 static int xe_oa_enable_locked(struct xe_oa_stream *stream)
 {
        if (stream->enabled)
                return 0;
 
+       if (stream->no_preempt) {
+               int ret = xe_oa_disable_preempt_timeslice(stream);
+
+               if (ret)
+                       return ret;
+       }
+
        xe_oa_stream_enable(stream);
 
        stream->enabled = true;
@@ -1026,13 +1071,18 @@ static int xe_oa_enable_locked(struct xe_oa_stream *stream)
 
 static int xe_oa_disable_locked(struct xe_oa_stream *stream)
 {
+       int ret = 0;
+
        if (!stream->enabled)
                return 0;
 
        xe_oa_stream_disable(stream);
 
+       if (stream->no_preempt)
+               ret = xe_oa_enable_preempt_timeslice(stream);
+
        stream->enabled = false;
-       return 0;
+       return ret;
 }
 
 static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg)
@@ -1307,6 +1357,7 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
        stream->sample = param->sample;
        stream->periodic = param->period_exponent > 0;
        stream->period_exponent = param->period_exponent;
+       stream->no_preempt = param->no_preempt;
 
        /*
         * For Xe2+, when overrun mode is enabled, there are no partial reports at the end
@@ -1651,6 +1702,13 @@ static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value,
        return 0;
 }
 
+static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value,
+                               struct xe_oa_open_param *param)
+{
+       param->no_preempt = value;
+       return 0;
+}
+
 typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value,
                                     struct xe_oa_open_param *param);
 static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
@@ -1662,6 +1720,7 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
        [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_disabled,
        [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id,
        [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance,
+       [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt,
 };
 
 static int xe_oa_user_ext_set_property(struct xe_oa *oa, u64 extension,
@@ -1766,6 +1825,15 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
        if (param.exec_q && !param.sample)
                privileged_op = false;
 
+       if (param.no_preempt) {
+               if (!param.exec_q) {
+                       drm_dbg(&oa->xe->drm, "Preemption disable without exec_q!\n");
+                       ret = -EINVAL;
+                       goto err_exec_q;
+               }
+               privileged_op = true;
+       }
+
        if (privileged_op && xe_perf_stream_paranoid && !perfmon_capable()) {
                drm_dbg(&oa->xe->drm, "Insufficient privileges to open xe perf stream\n");
                ret = -EACCES;
index 706d45577daec04952c6b201fafc3313a58067fd..540c3ec53a6d79d69a80f43f0cd4a964b49074f5 100644 (file)
@@ -235,5 +235,8 @@ struct xe_oa_stream {
 
        /** @oa_status: temporary storage for oa_status register value */
        u32 oa_status;
+
+       /** @no_preempt: Whether preemption and timeslicing is disabled for stream exec_q */
+       u32 no_preempt;
 };
 #endif
index b410553faa9b3b657b0d47b3ce0bc45b4f8c287e..12eaa8532b5c3d42a02bb4704dde050182c09f14 100644 (file)
@@ -1611,6 +1611,12 @@ enum drm_xe_oa_property_id {
         * pass along with @DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID or will default to 0.
         */
        DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE,
+
+       /**
+        * @DRM_XE_OA_PROPERTY_NO_PREEMPT: Allow preemption and timeslicing
+        * to be disabled for the stream exec queue.
+        */
+       DRM_XE_OA_PROPERTY_NO_PREEMPT,
 };
 
 /**