Commit 71e7d7e8 authored by Niranjana Vishwanathapura's avatar Niranjana Vishwanathapura
Browse files

drm/xe/multi_queue: Add support for multi queue dynamic priority change



Support dynamic priority change for multi queue group queues via
exec queue set_property ioctl. Issue CGP_SYNC command to GuC through
the drm scheduler message interface for priority to take effect.

v2: Move is_multi_queue check to exec_queue layer and assert
    is_multi_queue being set in guc submission layer (Matt Brost)
v3: Assert CGP_SYNC message length is valid (Matt Brost)

Signed-off-by: default avatarPallavi Mishra <pallavi.mishra@intel.com>
Signed-off-by: default avatarNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Reviewed-by: default avatarMatthew Brost <matthew.brost@intel.com>
Link: https://patch.msgid.link/20251211010249.1647839-26-niranjana.vishwanathapura@intel.com
parent 2a31ea17
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -771,11 +771,18 @@ static int exec_queue_set_multi_queue_priority(struct xe_device *xe, struct xe_e
	if (XE_IOCTL_DBG(xe, value > XE_MULTI_QUEUE_PRIORITY_HIGH))
		return -EINVAL;

	/* For queue creation time (!q->xef) setting, just store the priority value */
	if (!q->xef) {
		q->multi_queue.priority = value;

		return 0;
	}

	if (!xe_exec_queue_is_multi_queue(q))
		return -EINVAL;

	return q->ops->set_multi_queue_priority(q, value);
}

typedef int (*xe_exec_queue_set_property_fn)(struct xe_device *xe,
					     struct xe_exec_queue *q,
					     u64 value);
+3 −0
Original line number Diff line number Diff line
@@ -260,6 +260,9 @@ struct xe_exec_queue_ops {
	int (*set_timeslice)(struct xe_exec_queue *q, u32 timeslice_us);
	/** @set_preempt_timeout: Set preemption timeout for exec queue */
	int (*set_preempt_timeout)(struct xe_exec_queue *q, u32 preempt_timeout_us);
	/** @set_multi_queue_priority: Set multi queue priority */
	int (*set_multi_queue_priority)(struct xe_exec_queue *q,
					enum xe_multi_queue_priority priority);
	/**
	 * @suspend: Suspend exec queue from executing, allowed to be called
	 * multiple times in a row before resume with the caveat that
+53 −4
Original line number Diff line number Diff line
@@ -1779,10 +1779,34 @@ static void __guc_exec_queue_process_msg_resume(struct xe_sched_msg *msg)
	}
}

static void __guc_exec_queue_process_msg_set_multi_queue_priority(struct xe_sched_msg *msg)
{
	struct xe_exec_queue *q = msg->private_data;

	if (guc_exec_queue_allowed_to_change_state(q)) {
#define MAX_MULTI_QUEUE_CGP_SYNC_SIZE        (2)
		struct xe_guc *guc = exec_queue_to_guc(q);
		struct xe_exec_queue_group *group = q->multi_queue.group;
		u32 action[MAX_MULTI_QUEUE_CGP_SYNC_SIZE];
		int len = 0;

		action[len++] = XE_GUC_ACTION_MULTI_QUEUE_CONTEXT_CGP_SYNC;
		action[len++] = group->primary->guc->id;

		xe_gt_assert(guc_to_gt(guc), len <= MAX_MULTI_QUEUE_CGP_SYNC_SIZE);
#undef MAX_MULTI_QUEUE_CGP_SYNC_SIZE

		xe_guc_exec_queue_group_cgp_sync(guc, q, action, len);
	}

	kfree(msg);
}

#define CLEANUP				1	/* Non-zero values to catch uninitialized msg */
#define SET_SCHED_PROPS			2
#define SUSPEND				3
#define RESUME				4
#define SET_MULTI_QUEUE_PRIORITY	5
#define OPCODE_MASK	0xf
#define MSG_LOCKED	BIT(8)
#define MSG_HEAD	BIT(9)
@@ -1806,6 +1830,9 @@ static void guc_exec_queue_process_msg(struct xe_sched_msg *msg)
	case RESUME:
		__guc_exec_queue_process_msg_resume(msg);
		break;
	case SET_MULTI_QUEUE_PRIORITY:
		__guc_exec_queue_process_msg_set_multi_queue_priority(msg);
		break;
	default:
		XE_WARN_ON("Unknown message type");
	}
@@ -2022,6 +2049,27 @@ static int guc_exec_queue_set_preempt_timeout(struct xe_exec_queue *q,
	return 0;
}

static int guc_exec_queue_set_multi_queue_priority(struct xe_exec_queue *q,
						   enum xe_multi_queue_priority priority)
{
	struct xe_sched_msg *msg;

	xe_gt_assert(guc_to_gt(exec_queue_to_guc(q)), xe_exec_queue_is_multi_queue(q));

	if (q->multi_queue.priority == priority ||
	    exec_queue_killed_or_banned_or_wedged(q))
		return 0;

	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	q->multi_queue.priority = priority;
	guc_exec_queue_add_msg(q, msg, SET_MULTI_QUEUE_PRIORITY);

	return 0;
}

static int guc_exec_queue_suspend(struct xe_exec_queue *q)
{
	struct xe_gpu_scheduler *sched = &q->guc->sched;
@@ -2113,6 +2161,7 @@ static const struct xe_exec_queue_ops guc_exec_queue_ops = {
	.set_priority = guc_exec_queue_set_priority,
	.set_timeslice = guc_exec_queue_set_timeslice,
	.set_preempt_timeout = guc_exec_queue_set_preempt_timeout,
	.set_multi_queue_priority = guc_exec_queue_set_multi_queue_priority,
	.suspend = guc_exec_queue_suspend,
	.suspend_wait = guc_exec_queue_suspend_wait,
	.resume = guc_exec_queue_resume,