Commit 96bfe9ff authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-xe-fixes-2026-03-05' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes



Cross-subsystem Changes:
 - mm: Fix a hmm_range_fault() livelock / starvation problem (Thomas)

Core Changes:
 - Revert "drm/pagemap: Disable device-to-device migration" (Thomas)

Driver Changes:
 - Do not preempt fence signaling CS instructions (Brost)
 - Some leak and finalization fixes (Shuicheng, Tomasz, Varun, Zhanjun)
 - Workaround fix (Roper)

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

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patch.msgid.link/aamGvvGRBRtX8-6u@intel.com
parents 43198996 0cfe9c48
Loading
Loading
Loading
Loading
+2 −12
Original line number Diff line number Diff line
@@ -480,18 +480,8 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation,
		.start		= start,
		.end		= end,
		.pgmap_owner	= pagemap->owner,
		/*
		 * FIXME: MIGRATE_VMA_SELECT_DEVICE_PRIVATE intermittently
		 * causes 'xe_exec_system_allocator --r *race*no*' to trigger aa
		 * engine reset and a hard hang due to getting stuck on a folio
		 * lock. This should work and needs to be root-caused. The only
		 * downside of not selecting MIGRATE_VMA_SELECT_DEVICE_PRIVATE
		 * is that device-to-device migrations won’t work; instead,
		 * memory will bounce through system memory. This path should be
		 * rare and only occur when the madvise attributes of memory are
		 * changed or atomics are being used.
		 */
		.flags		= MIGRATE_VMA_SELECT_SYSTEM | MIGRATE_VMA_SELECT_DEVICE_COHERENT,
		.flags		= MIGRATE_VMA_SELECT_SYSTEM | MIGRATE_VMA_SELECT_DEVICE_COHERENT |
		MIGRATE_VMA_SELECT_DEVICE_PRIVATE,
	};
	unsigned long i, npages = npages_in_range(start, end);
	unsigned long own_pages = 0, migrated_pages = 0;
+1 −0
Original line number Diff line number Diff line
@@ -830,6 +830,7 @@ static void xe_config_device_release(struct config_item *item)

	mutex_destroy(&dev->lock);

	kfree(dev->config.ctx_restore_mid_bb[0].cs);
	kfree(dev->config.ctx_restore_post_bb[0].cs);
	kfree(dev);
}
+11 −12
Original line number Diff line number Diff line
@@ -266,6 +266,16 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
	return q;
}

static void __xe_exec_queue_fini(struct xe_exec_queue *q)
{
	int i;

	q->ops->fini(q);

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

static int __xe_exec_queue_init(struct xe_exec_queue *q, u32 exec_queue_flags)
{
	int i, err;
@@ -320,21 +330,10 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q, u32 exec_queue_flags)
	return 0;

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

static void __xe_exec_queue_fini(struct xe_exec_queue *q)
{
	int i;

	q->ops->fini(q);

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

struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *vm,
					   u32 logical_mask, u16 width,
					   struct xe_hw_engine *hwe, u32 flags,
+35 −8
Original line number Diff line number Diff line
@@ -435,15 +435,11 @@ static int proxy_channel_alloc(struct xe_gsc *gsc)
	return 0;
}

static void xe_gsc_proxy_remove(void *arg)
static void xe_gsc_proxy_stop(struct xe_gsc *gsc)
{
	struct xe_gsc *gsc = arg;
	struct xe_gt *gt = gsc_to_gt(gsc);
	struct xe_device *xe = gt_to_xe(gt);

	if (!gsc->proxy.component_added)
		return;

	/* disable HECI2 IRQs */
	scoped_guard(xe_pm_runtime, xe) {
		CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GSC);
@@ -455,6 +451,30 @@ static void xe_gsc_proxy_remove(void *arg)
	}

	xe_gsc_wait_for_worker_completion(gsc);
	gsc->proxy.started = false;
}

static void xe_gsc_proxy_remove(void *arg)
{
	struct xe_gsc *gsc = arg;
	struct xe_gt *gt = gsc_to_gt(gsc);
	struct xe_device *xe = gt_to_xe(gt);

	if (!gsc->proxy.component_added)
		return;

	/*
	 * GSC proxy start is an async process that can be ongoing during
	 * Xe module load/unload. Using devm managed action to register
	 * xe_gsc_proxy_stop could cause issues if Xe module unload has
	 * already started when the action is registered, potentially leading
	 * to the cleanup being called at the wrong time. Therefore, instead
	 * of registering a separate devm action to undo what is done in
	 * proxy start, we call it from here, but only if the start has
	 * completed successfully (tracked with the 'started' flag).
	 */
	if (gsc->proxy.started)
		xe_gsc_proxy_stop(gsc);

	component_del(xe->drm.dev, &xe_gsc_proxy_component_ops);
	gsc->proxy.component_added = false;
@@ -510,6 +530,7 @@ int xe_gsc_proxy_init(struct xe_gsc *gsc)
 */
int xe_gsc_proxy_start(struct xe_gsc *gsc)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	int err;

	/* enable the proxy interrupt in the GSC shim layer */
@@ -521,12 +542,18 @@ int xe_gsc_proxy_start(struct xe_gsc *gsc)
	 */
	err = xe_gsc_proxy_request_handler(gsc);
	if (err)
		return err;
		goto err_irq_disable;

	if (!xe_gsc_proxy_init_done(gsc)) {
		xe_gt_err(gsc_to_gt(gsc), "GSC FW reports proxy init not completed\n");
		return -EIO;
		xe_gt_err(gt, "GSC FW reports proxy init not completed\n");
		err = -EIO;
		goto err_irq_disable;
	}

	gsc->proxy.started = true;
	return 0;

err_irq_disable:
	gsc_proxy_irq_toggle(gsc, false);
	return err;
}
+2 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ struct xe_gsc {
		struct mutex mutex;
		/** @proxy.component_added: whether the component has been added */
		bool component_added;
		/** @proxy.started: whether the proxy has been started */
		bool started;
		/** @proxy.bo: object to store message to and from the GSC */
		struct xe_bo *bo;
		/** @proxy.to_gsc: map of the memory used to send messages to the GSC */
Loading