Commit 86fafc58 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-xe-next-fixes-2025-12-04' of...

Merge tag 'drm-xe-next-fixes-2025-12-04' of https://gitlab.freedesktop.org/drm/xe/kernel

 into drm-next

Driver Changes:
- Fix a memory leak (Mika)
- Fix a 64-bit division (Michal Wajdeczko)
- vf migration fix (Matt Brost)
- LRC pause Fix (Tomasz lis)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Hellstrom <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/aTIGiHJnnMtqbDOO@fedora
parents e73c2262 3f1c07fc
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -54,13 +54,14 @@ static inline void xe_sched_tdr_queue_imm(struct xe_gpu_scheduler *sched)
static inline void xe_sched_resubmit_jobs(struct xe_gpu_scheduler *sched)
{
	struct drm_sched_job *s_job;
	bool restore_replay = false;

	list_for_each_entry(s_job, &sched->base.pending_list, list) {
		struct drm_sched_fence *s_fence = s_job->s_fence;
		struct dma_fence *hw_fence = s_fence->parent;

		if (to_xe_sched_job(s_job)->skip_emit ||
		    (hw_fence && !dma_fence_is_signaled(hw_fence)))
		restore_replay |= to_xe_sched_job(s_job)->restore_replay;
		if (restore_replay || (hw_fence && !dma_fence_is_signaled(hw_fence)))
			sched->base.ops->run_job(s_job);
	}
}
+1 −1
Original line number Diff line number Diff line
@@ -711,7 +711,7 @@ static u64 pf_profile_fair_ggtt(struct xe_gt *gt, unsigned int num_vfs)
	if (num_vfs > 56)
		return SZ_64M - SZ_8M;

	return rounddown_pow_of_two(shareable / num_vfs);
	return rounddown_pow_of_two(div_u64(shareable, num_vfs));
}

/**
+30 −17
Original line number Diff line number Diff line
@@ -822,7 +822,7 @@ static void submit_exec_queue(struct xe_exec_queue *q, struct xe_sched_job *job)

	xe_gt_assert(guc_to_gt(guc), exec_queue_registered(q));

	if (!job->skip_emit || job->last_replay) {
	if (!job->restore_replay || job->last_replay) {
		if (xe_exec_queue_is_parallel(q))
			wq_item_append(q);
		else
@@ -881,10 +881,10 @@ guc_exec_queue_run_job(struct drm_sched_job *drm_job)
	if (!killed_or_banned_or_wedged && !xe_sched_job_is_error(job)) {
		if (!exec_queue_registered(q))
			register_exec_queue(q, GUC_CONTEXT_NORMAL);
		if (!job->skip_emit)
		if (!job->restore_replay)
			q->ring_ops->emit_job(job);
		submit_exec_queue(q, job);
		job->skip_emit = false;
		job->restore_replay = false;
	}

	/*
@@ -2112,6 +2112,18 @@ static void guc_exec_queue_revert_pending_state_change(struct xe_guc *guc,
	q->guc->resume_time = 0;
}

static void lrc_parallel_clear(struct xe_lrc *lrc)
{
	struct xe_device *xe = gt_to_xe(lrc->gt);
	struct iosys_map map = xe_lrc_parallel_map(lrc);
	int i;

	for (i = 0; i < WQ_SIZE / sizeof(u32); ++i)
		parallel_write(xe, map, wq[i],
			       FIELD_PREP(WQ_TYPE_MASK, WQ_TYPE_NOOP) |
			       FIELD_PREP(WQ_LEN_MASK, 0));
}

/*
 * This function is quite complex but only real way to ensure no state is lost
 * during VF resume flows. The function scans the queue state, make adjustments
@@ -2135,8 +2147,8 @@ static void guc_exec_queue_pause(struct xe_guc *guc, struct xe_exec_queue *q)
	guc_exec_queue_revert_pending_state_change(guc, q);

	if (xe_exec_queue_is_parallel(q)) {
		struct xe_device *xe = guc_to_xe(guc);
		struct iosys_map map = xe_lrc_parallel_map(q->lrc[0]);
		/* Pairs with WRITE_ONCE in __xe_exec_queue_init  */
		struct xe_lrc *lrc = READ_ONCE(q->lrc[0]);

		/*
		 * NOP existing WQ commands that may contain stale GGTT
@@ -2144,14 +2156,14 @@ static void guc_exec_queue_pause(struct xe_guc *guc, struct xe_exec_queue *q)
		 * seems to get confused if the WQ head/tail pointers are
		 * adjusted.
		 */
		for (i = 0; i < WQ_SIZE / sizeof(u32); ++i)
			parallel_write(xe, map, wq[i],
				       FIELD_PREP(WQ_TYPE_MASK, WQ_TYPE_NOOP) |
				       FIELD_PREP(WQ_LEN_MASK, 0));
		if (lrc)
			lrc_parallel_clear(lrc);
	}

	job = xe_sched_first_pending_job(sched);
	if (job) {
		job->restore_replay = true;

		/*
		 * Adjust software tail so jobs submitted overwrite previous
		 * position in ring buffer with new GGTT addresses.
@@ -2241,17 +2253,18 @@ static void guc_exec_queue_unpause_prepare(struct xe_guc *guc,
					   struct xe_exec_queue *q)
{
	struct xe_gpu_scheduler *sched = &q->guc->sched;
	struct drm_sched_job *s_job;
	struct xe_sched_job *job = NULL;
	bool restore_replay = false;

	list_for_each_entry(s_job, &sched->base.pending_list, list) {
		job = to_xe_sched_job(s_job);

	list_for_each_entry(job, &sched->base.pending_list, drm.list) {
		restore_replay |= job->restore_replay;
		if (restore_replay) {
			xe_gt_dbg(guc_to_gt(guc), "Replay JOB - guc_id=%d, seqno=%d",
				  q->guc->id, xe_sched_job_seqno(job));

			q->ring_ops->emit_job(job);
		job->skip_emit = true;
			job->restore_replay = true;
		}
	}

	if (job)
+0 −1
Original line number Diff line number Diff line
@@ -102,7 +102,6 @@ static int xe_pagefault_handle_vma(struct xe_gt *gt, struct xe_vma *vma,

	/* Lock VM and BOs dma-resv */
	xe_validation_ctx_init(&ctx, &vm->xe->val, &exec, (struct xe_val_flags) {});
	drm_exec_init(&exec, 0, 0);
	drm_exec_until_all_locked(&exec) {
		err = xe_pagefault_begin(&exec, vma, tile->mem.vram,
					 needs_vram == 1);
+2 −2
Original line number Diff line number Diff line
@@ -63,8 +63,8 @@ struct xe_sched_job {
	bool ring_ops_flush_tlb;
	/** @ggtt: mapped in ggtt. */
	bool ggtt;
	/** @skip_emit: skip emitting the job */
	bool skip_emit;
	/** @restore_replay: job being replayed for restore */
	bool restore_replay;
	/** @last_replay: last job being replayed */
	bool last_replay;
	/** @ptrs: per instance pointers. */