]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/multi_queue: Add multi queue priority property
authorNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Thu, 11 Dec 2025 01:02:52 +0000 (17:02 -0800)
committerNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Fri, 12 Dec 2025 03:20:51 +0000 (19:20 -0800)
Add support for queues of a multi queue group to set
their priority within the queue group by adding property
DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY.
This is the only other property supported by secondary
queues of a multi queue group, other than
DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE.

v2: Add kernel doc for enum xe_multi_queue_priority,
    Add assert for priority values, fix includes and
    declarations (Matt Brost)
v3: update uapi kernel-doc (Matt Brost)
v4: uapi change due to rebase

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patch.msgid.link/20251211010249.1647839-23-niranjana.vishwanathapura@intel.com
drivers/gpu/drm/xe/xe_exec_queue.c
drivers/gpu/drm/xe/xe_exec_queue_types.h
drivers/gpu/drm/xe/xe_guc_submit.c
drivers/gpu/drm/xe/xe_lrc.c
drivers/gpu/drm/xe/xe_lrc.h
include/uapi/drm/xe_drm.h

index f76ec277c5afbb763fcfa610eeb7cc7fb374d113..aa46d154d04a75854a6da968b6ce9aacde2759c7 100644 (file)
@@ -180,6 +180,7 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
        INIT_LIST_HEAD(&q->multi_gt_link);
        INIT_LIST_HEAD(&q->hw_engine_group_link);
        INIT_LIST_HEAD(&q->pxp.link);
+       q->multi_queue.priority = XE_MULTI_QUEUE_PRIORITY_NORMAL;
 
        q->sched_props.timeslice_us = hwe->eclass->sched_props.timeslice_us;
        q->sched_props.preempt_timeout_us =
@@ -764,6 +765,17 @@ static int exec_queue_set_multi_group(struct xe_device *xe, struct xe_exec_queue
        return xe_exec_queue_group_validate(xe, q, value);
 }
 
+static int exec_queue_set_multi_queue_priority(struct xe_device *xe, struct xe_exec_queue *q,
+                                              u64 value)
+{
+       if (XE_IOCTL_DBG(xe, value > XE_MULTI_QUEUE_PRIORITY_HIGH))
+               return -EINVAL;
+
+       q->multi_queue.priority = value;
+
+       return 0;
+}
+
 typedef int (*xe_exec_queue_set_property_fn)(struct xe_device *xe,
                                             struct xe_exec_queue *q,
                                             u64 value);
@@ -774,6 +786,8 @@ static const xe_exec_queue_set_property_fn exec_queue_set_property_funcs[] = {
        [DRM_XE_EXEC_QUEUE_SET_PROPERTY_PXP_TYPE] = exec_queue_set_pxp_type,
        [DRM_XE_EXEC_QUEUE_SET_HANG_REPLAY_STATE] = exec_queue_set_hang_replay_state,
        [DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP] = exec_queue_set_multi_group,
+       [DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY] =
+                                                       exec_queue_set_multi_queue_priority,
 };
 
 static int exec_queue_user_ext_set_property(struct xe_device *xe,
@@ -796,7 +810,8 @@ static int exec_queue_user_ext_set_property(struct xe_device *xe,
                         ext.property != DRM_XE_EXEC_QUEUE_SET_PROPERTY_TIMESLICE &&
                         ext.property != DRM_XE_EXEC_QUEUE_SET_PROPERTY_PXP_TYPE &&
                         ext.property != DRM_XE_EXEC_QUEUE_SET_HANG_REPLAY_STATE &&
-                        ext.property != DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP))
+                        ext.property != DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP &&
+                        ext.property != DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY))
                return -EINVAL;
 
        idx = array_index_nospec(ext.property, ARRAY_SIZE(exec_queue_set_property_funcs));
index 06fb518b85333f4b9a9aaebf7e0267c3b0018946..46e5f4715a0da194584e2b41c854a2f1396e1d91 100644 (file)
@@ -32,6 +32,20 @@ enum xe_exec_queue_priority {
        XE_EXEC_QUEUE_PRIORITY_COUNT
 };
 
+/**
+ * enum xe_multi_queue_priority - Multi Queue priority values
+ *
+ * The priority values of the queues within the multi queue group.
+ */
+enum xe_multi_queue_priority {
+       /** @XE_MULTI_QUEUE_PRIORITY_LOW: Priority low */
+       XE_MULTI_QUEUE_PRIORITY_LOW = 0,
+       /** @XE_MULTI_QUEUE_PRIORITY_NORMAL: Priority normal */
+       XE_MULTI_QUEUE_PRIORITY_NORMAL,
+       /** @XE_MULTI_QUEUE_PRIORITY_HIGH: Priority high */
+       XE_MULTI_QUEUE_PRIORITY_HIGH,
+};
+
 /**
  * struct xe_exec_queue_group - Execution multi queue group
  *
@@ -131,6 +145,8 @@ struct xe_exec_queue {
        struct {
                /** @multi_queue.group: Queue group information */
                struct xe_exec_queue_group *group;
+               /** @multi_queue.priority: Queue priority within the multi-queue group */
+               enum xe_multi_queue_priority priority;
                /** @multi_queue.pos: Position of queue within the multi-queue group */
                u8 pos;
                /** @multi_queue.valid: Queue belongs to a multi queue group */
index bafe42393d2214fc7a6a6101dc884b2d253af204..7cca03d4296c63d25d7938c70a17bc99ff516ba3 100644 (file)
@@ -640,6 +640,7 @@ static void xe_guc_exec_queue_group_cgp_sync(struct xe_guc *guc,
                return;
        }
 
+       xe_lrc_set_multi_queue_priority(q->lrc[0], q->multi_queue.priority);
        xe_guc_exec_queue_group_cgp_update(xe, q);
 
        WRITE_ONCE(group->sync_pending, true);
index a05060f75e7e29a1911e1292bfaba3dfba1e62c1..70eae7d03a2724058e8382e12b22c0c0ecdf2025 100644 (file)
 #define LRC_INDIRECT_CTX_BO_SIZE               SZ_4K
 #define LRC_INDIRECT_RING_STATE_SIZE           SZ_4K
 
+#define LRC_PRIORITY                           GENMASK_ULL(10, 9)
+#define LRC_PRIORITY_LOW                       0
+#define LRC_PRIORITY_NORMAL                    1
+#define LRC_PRIORITY_HIGH                      2
+
 /*
  * Layout of the LRC and associated data allocated as
  * lrc->bo:
@@ -1399,6 +1404,30 @@ setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe)
        return 0;
 }
 
+static u8 xe_multi_queue_prio_to_lrc(struct xe_lrc *lrc, enum xe_multi_queue_priority priority)
+{
+       struct xe_device *xe = gt_to_xe(lrc->gt);
+
+       xe_assert(xe, (priority >= XE_MULTI_QUEUE_PRIORITY_LOW &&
+                      priority <= XE_MULTI_QUEUE_PRIORITY_HIGH));
+
+       /* xe_multi_queue_priority is directly mapped to LRC priority values */
+       return priority;
+}
+
+/**
+ * xe_lrc_set_multi_queue_priority() - Set multi queue priority in LRC
+ * @lrc: Logical Ring Context
+ * @priority: Multi queue priority of the exec queue
+ *
+ * Convert @priority to LRC multi queue priority and update the @lrc descriptor
+ */
+void xe_lrc_set_multi_queue_priority(struct xe_lrc *lrc, enum xe_multi_queue_priority priority)
+{
+       lrc->desc &= ~LRC_PRIORITY;
+       lrc->desc |= FIELD_PREP(LRC_PRIORITY, xe_multi_queue_prio_to_lrc(lrc, priority));
+}
+
 static int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
                       struct xe_vm *vm, void *replay_state, u32 ring_size,
                       u16 msix_vec,
index a32472b922425c27d2f0bd95e7792ee53dd4bc33..8acf85273c1a79410e67c9b5d14bd402216ee8c5 100644 (file)
@@ -13,6 +13,7 @@ struct drm_printer;
 struct xe_bb;
 struct xe_device;
 struct xe_exec_queue;
+enum xe_multi_queue_priority;
 enum xe_engine_class;
 struct xe_gt;
 struct xe_hw_engine;
@@ -135,6 +136,8 @@ void xe_lrc_dump_default(struct drm_printer *p,
 
 u32 *xe_lrc_emit_hwe_state_instructions(struct xe_exec_queue *q, u32 *cs);
 
+void xe_lrc_set_multi_queue_priority(struct xe_lrc *lrc, enum xe_multi_queue_priority priority);
+
 struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc);
 void xe_lrc_snapshot_capture_delayed(struct xe_lrc_snapshot *snapshot);
 void xe_lrc_snapshot_print(struct xe_lrc_snapshot *snapshot, struct drm_printer *p);
index 19a8ae856a17dc069e69aed0e9df17297b2ce4cb..fd79d78de2e9a12bd0fbf3224b3d8b66735f022c 100644 (file)
@@ -1280,6 +1280,9 @@ struct drm_xe_vm_bind {
  *    queue's exec_queue_id is specified in the lower 32 bits of the 'value' field.
  *    All the other non-relevant bits of extension's 'value' field while adding the
  *    primary or the secondary queues of the group must be set to 0.
+ *  - %DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY - Set the queue
+ *    priority within the multi-queue group. Current valid priority values are 0–2
+ *    (default is 1), with higher values indicating higher priority.
  *
  * The example below shows how to use @drm_xe_exec_queue_create to create
  * a simple exec_queue (no parallel submission) of class
@@ -1323,6 +1326,7 @@ struct drm_xe_exec_queue_create {
 #define   DRM_XE_EXEC_QUEUE_SET_HANG_REPLAY_STATE              3
 #define   DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP           4
 #define     DRM_XE_MULTI_GROUP_CREATE                          (1ull << 63)
+#define   DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY  5
        /** @extensions: Pointer to the first extension struct, if any */
        __u64 extensions;