mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
drm/xe/multi_queue: Add multi queue priority property
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
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -44,6 +44,11 @@
|
||||
#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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user