Commit 264eecdb authored by Niranjana Vishwanathapura's avatar Niranjana Vishwanathapura Committed by Matthew Brost
Browse files

drm/xe: Decouple xe_exec_queue and xe_lrc



Decouple xe_lrc from xe_exec_queue and reference count xe_lrc.
Removing hard coupling between xe_exec_queue and xe_lrc allows
flexible design where the user interface xe_exec_queue can be
destroyed independent of the hardware/firmware interface xe_lrc.

v2: Fix lrc indexing in wq_item_append()

Signed-off-by: default avatarNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Reviewed-by: default avatarMatthew Brost <matthew.brost@intel.com>
Signed-off-by: default avatarMatthew Brost <matthew.brost@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240530032211.29299-1-niranjana.vishwanathapura@intel.com
parent 0568a408
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,

	if (extensions) {
		/*
		 * may set q->usm, must come before xe_lrc_init(),
		 * may set q->usm, must come before xe_lrc_create(),
		 * may overwrite q->sched_props, must come before q->ops->init()
		 */
		err = exec_queue_user_extensions(xe, q, extensions, 0);
@@ -104,10 +104,12 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q)
	int i, err;

	for (i = 0; i < q->width; ++i) {
		err = xe_lrc_init(q->lrc + i, q->hwe, q, q->vm, SZ_16K);
		if (err)
		q->lrc[i] = xe_lrc_create(q->hwe, q->vm, SZ_16K);
		if (IS_ERR(q->lrc[i])) {
			err = PTR_ERR(q->lrc[i]);
			goto err_lrc;
		}
	}

	err = q->ops->init(q);
	if (err)
@@ -117,7 +119,7 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q)

err_lrc:
	for (i = i - 1; i >= 0; --i)
		xe_lrc_finish(q->lrc + i);
		xe_lrc_put(q->lrc[i]);
	return err;
}

@@ -198,7 +200,7 @@ void xe_exec_queue_fini(struct xe_exec_queue *q)
	int i;

	for (i = 0; i < q->width; ++i)
		xe_lrc_finish(q->lrc + i);
		xe_lrc_put(q->lrc[i]);
	__xe_exec_queue_free(q);
}

@@ -701,7 +703,7 @@ bool xe_exec_queue_is_lr(struct xe_exec_queue *q)

static s32 xe_exec_queue_num_job_inflight(struct xe_exec_queue *q)
{
	return q->lrc->fence_ctx.next_seqno - xe_lrc_seqno(q->lrc) - 1;
	return q->lrc[0]->fence_ctx.next_seqno - xe_lrc_seqno(q->lrc[0]) - 1;
}

/**
@@ -712,7 +714,7 @@ static s32 xe_exec_queue_num_job_inflight(struct xe_exec_queue *q)
 */
bool xe_exec_queue_ring_full(struct xe_exec_queue *q)
{
	struct xe_lrc *lrc = q->lrc;
	struct xe_lrc *lrc = q->lrc[0];
	s32 max_job = lrc->ring.size / MAX_JOB_SIZE_BYTES;

	return xe_exec_queue_num_job_inflight(q) >= max_job;
@@ -738,16 +740,16 @@ bool xe_exec_queue_is_idle(struct xe_exec_queue *q)
		int i;

		for (i = 0; i < q->width; ++i) {
			if (xe_lrc_seqno(&q->lrc[i]) !=
			    q->lrc[i].fence_ctx.next_seqno - 1)
			if (xe_lrc_seqno(q->lrc[i]) !=
			    q->lrc[i]->fence_ctx.next_seqno - 1)
				return false;
		}

		return true;
	}

	return xe_lrc_seqno(&q->lrc[0]) ==
		q->lrc[0].fence_ctx.next_seqno - 1;
	return xe_lrc_seqno(q->lrc[0]) ==
		q->lrc[0]->fence_ctx.next_seqno - 1;
}

/**
@@ -779,7 +781,7 @@ void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q)
	 * the LRCs and reading them in different time could also introduce
	 * errors.
	 */
	lrc = &q->lrc[0];
	lrc = q->lrc[0];
	new_ts = xe_lrc_update_timestamp(lrc, &old_ts);
	q->run_ticks += (new_ts - old_ts) * q->width;
}
+1 −1
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ struct xe_exec_queue {
	/** @run_ticks: hw engine class run time in ticks for this exec queue */
	u64 run_ticks;
	/** @lrc: logical ring context for this exec queue */
	struct xe_lrc lrc[];
	struct xe_lrc *lrc[];
};

/**
+5 −5
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ static void __xe_execlist_port_start(struct xe_execlist_port *port,
			port->last_ctx_id = 1;
	}

	__start_lrc(port->hwe, exl->q->lrc, port->last_ctx_id);
	__start_lrc(port->hwe, exl->q->lrc[0], port->last_ctx_id);
	port->running_exl = exl;
	exl->has_run = true;
}
@@ -123,14 +123,14 @@ static void __xe_execlist_port_idle(struct xe_execlist_port *port)
	if (!port->running_exl)
		return;

	xe_lrc_write_ring(&port->hwe->kernel_lrc, noop, sizeof(noop));
	__start_lrc(port->hwe, &port->hwe->kernel_lrc, 0);
	xe_lrc_write_ring(port->hwe->kernel_lrc, noop, sizeof(noop));
	__start_lrc(port->hwe, port->hwe->kernel_lrc, 0);
	port->running_exl = NULL;
}

static bool xe_execlist_is_idle(struct xe_execlist_exec_queue *exl)
{
	struct xe_lrc *lrc = exl->q->lrc;
	struct xe_lrc *lrc = exl->q->lrc[0];

	return lrc->ring.tail == lrc->ring.old_tail;
}
@@ -333,7 +333,7 @@ static int execlist_exec_queue_init(struct xe_exec_queue *q)
	exl->q = q;

	err = drm_sched_init(&exl->sched, &drm_sched_ops, NULL, 1,
			     q->lrc[0].ring.size / MAX_JOB_SIZE_BYTES,
			     q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES,
			     XE_SCHED_HANG_LIMIT, XE_SCHED_JOB_TIMEOUT,
			     NULL, NULL, q->hwe->name,
			     gt_to_xe(q->gt)->drm.dev);
+2 −2
Original line number Diff line number Diff line
@@ -297,8 +297,8 @@ int xe_gt_record_default_lrcs(struct xe_gt *gt)
		}

		xe_map_memcpy_from(xe, default_lrc,
				   &q->lrc[0].bo->vmap,
				   xe_lrc_pphwsp_offset(&q->lrc[0]),
				   &q->lrc[0]->bo->vmap,
				   xe_lrc_pphwsp_offset(q->lrc[0]),
				   xe_gt_lrc_size(gt, hwe->class));

		gt->default_lrc[hwe->class] = default_lrc;
+15 −15
Original line number Diff line number Diff line
@@ -490,7 +490,7 @@ static void __register_mlrc_exec_queue(struct xe_guc *guc,
	action[len++] = info->hwlrca_hi;

	for (i = 1; i < q->width; ++i) {
		struct xe_lrc *lrc = q->lrc + i;
		struct xe_lrc *lrc = q->lrc[i];

		action[len++] = lower_32_bits(xe_lrc_descriptor(lrc));
		action[len++] = upper_32_bits(xe_lrc_descriptor(lrc));
@@ -527,7 +527,7 @@ static void register_exec_queue(struct xe_exec_queue *q)
{
	struct xe_guc *guc = exec_queue_to_guc(q);
	struct xe_device *xe = guc_to_xe(guc);
	struct xe_lrc *lrc = q->lrc;
	struct xe_lrc *lrc = q->lrc[0];
	struct guc_ctxt_registration_info info;

	xe_assert(xe, !exec_queue_registered(q));
@@ -586,7 +586,7 @@ static int wq_wait_for_space(struct xe_exec_queue *q, u32 wqi_size)
{
	struct xe_guc *guc = exec_queue_to_guc(q);
	struct xe_device *xe = guc_to_xe(guc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc[0]);
	unsigned int sleep_period_ms = 1;

#define AVAILABLE_SPACE \
@@ -614,7 +614,7 @@ static int wq_noop_append(struct xe_exec_queue *q)
{
	struct xe_guc *guc = exec_queue_to_guc(q);
	struct xe_device *xe = guc_to_xe(guc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc[0]);
	u32 len_dw = wq_space_until_wrap(q) / sizeof(u32) - 1;

	if (wq_wait_for_space(q, wq_space_until_wrap(q)))
@@ -634,7 +634,7 @@ static void wq_item_append(struct xe_exec_queue *q)
{
	struct xe_guc *guc = exec_queue_to_guc(q);
	struct xe_device *xe = guc_to_xe(guc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc[0]);
#define WQ_HEADER_SIZE	4	/* Includes 1 LRC address too */
	u32 wqi[XE_HW_ENGINE_MAX_INSTANCE + (WQ_HEADER_SIZE - 1)];
	u32 wqi_size = (q->width + (WQ_HEADER_SIZE - 1)) * sizeof(u32);
@@ -650,12 +650,12 @@ static void wq_item_append(struct xe_exec_queue *q)

	wqi[i++] = FIELD_PREP(WQ_TYPE_MASK, WQ_TYPE_MULTI_LRC) |
		FIELD_PREP(WQ_LEN_MASK, len_dw);
	wqi[i++] = xe_lrc_descriptor(q->lrc);
	wqi[i++] = xe_lrc_descriptor(q->lrc[0]);
	wqi[i++] = FIELD_PREP(WQ_GUC_ID_MASK, q->guc->id) |
		FIELD_PREP(WQ_RING_TAIL_MASK, q->lrc->ring.tail / sizeof(u64));
		FIELD_PREP(WQ_RING_TAIL_MASK, q->lrc[0]->ring.tail / sizeof(u64));
	wqi[i++] = 0;
	for (j = 1; j < q->width; ++j) {
		struct xe_lrc *lrc = q->lrc + j;
		struct xe_lrc *lrc = q->lrc[j];

		wqi[i++] = lrc->ring.tail / sizeof(u64);
	}
@@ -670,7 +670,7 @@ static void wq_item_append(struct xe_exec_queue *q)

	xe_device_wmb(xe);

	map = xe_lrc_parallel_map(q->lrc);
	map = xe_lrc_parallel_map(q->lrc[0]);
	parallel_write(xe, map, wq_desc.tail, q->guc->wqi_tail);
}

@@ -679,7 +679,7 @@ static void submit_exec_queue(struct xe_exec_queue *q)
{
	struct xe_guc *guc = exec_queue_to_guc(q);
	struct xe_device *xe = guc_to_xe(guc);
	struct xe_lrc *lrc = q->lrc;
	struct xe_lrc *lrc = q->lrc[0];
	u32 action[3];
	u32 g2h_len = 0;
	u32 num_g2h = 0;
@@ -1236,7 +1236,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
		  msecs_to_jiffies(q->sched_props.job_timeout_ms);
	err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops,
			    get_submit_wq(guc),
			    q->lrc[0].ring.size / MAX_JOB_SIZE_BYTES, 64,
			    q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64,
			    timeout, guc_to_gt(guc)->ordered_wq, NULL,
			    q->name, gt_to_xe(q->gt)->drm.dev);
	if (err)
@@ -1464,7 +1464,7 @@ static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q)
				ban = true;
			}
		} else if (xe_exec_queue_is_lr(q) &&
			   (xe_lrc_ring_head(q->lrc) != xe_lrc_ring_tail(q->lrc))) {
			   (xe_lrc_ring_head(q->lrc[0]) != xe_lrc_ring_tail(q->lrc[0]))) {
			ban = true;
		}

@@ -1529,7 +1529,7 @@ static void guc_exec_queue_start(struct xe_exec_queue *q)

		trace_xe_exec_queue_resubmit(q);
		for (i = 0; i < q->width; ++i)
			xe_lrc_set_ring_head(q->lrc + i, q->lrc[i].ring.tail);
			xe_lrc_set_ring_head(q->lrc[i], q->lrc[i]->ring.tail);
		xe_sched_resubmit_jobs(sched);
	}

@@ -1775,7 +1775,7 @@ guc_exec_queue_wq_snapshot_capture(struct xe_exec_queue *q,
{
	struct xe_guc *guc = exec_queue_to_guc(q);
	struct xe_device *xe = guc_to_xe(guc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc);
	struct iosys_map map = xe_lrc_parallel_map(q->lrc[0]);
	int i;

	snapshot->guc.wqi_head = q->guc->wqi_head;
@@ -1855,7 +1855,7 @@ xe_guc_exec_queue_snapshot_capture(struct xe_exec_queue *q)

	if (snapshot->lrc) {
		for (i = 0; i < q->width; ++i) {
			struct xe_lrc *lrc = q->lrc + i;
			struct xe_lrc *lrc = q->lrc[i];

			snapshot->lrc[i] = xe_lrc_snapshot_capture(lrc);
		}
Loading