AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4)
@ 2026-09-08 18:10 Timur Kristóf
  2026-09-08 18:10 ` [PATCH 1/9] drm/amdgpu/sdma: Remove unimplemented soft_reset() for SDMA and SI DMA Timur Kristóf
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

Improve SDMA queue reset for SDMA v4.4.2, v5.0, v5.2
and also moves some functionality from backend-specific
code to common code in the amdgpu_sdma.c file.

This prepares for implementing SDMA recovery
on more generations, as the same logic can be shared
with all SDMA HW generations that don't use the MES.
The actual recovery implementation for various
older SDMA versions will come in subsequent patch series
after this one is accepted.

Changes in v2:

* Added a fix for an issue in SDMA v4.4.2
* Further simplified some code

Changes in v3:

* Fixed typo (wrong scheduler for page ring)

Changes in v4:

* Added helper function to clear ring contents and pointers

Timur Kristóf (9):
  drm/amdgpu/sdma: Remove unimplemented soft_reset() for SDMA and SI DMA
  drm/amdgpu/sdma: Remove superfluous rlc_resume and rlc_stop functions
  drm/amdgpu/sdma: Fix executing duplicate commands after recovery on
    SDMA v4.4.2
  drm/amdgpu/sdma: Remove unnecessary guilty tracking of SDMA queues
  drm/amdgpu: Add amdgpu_ring_clear_ring_and_ptrs()
  drm/amdgpu/sdma: Clear SDMA rings after reset before starting them
  drm/amdgpu/sdma: Move SDMA v5.x queue reset to common code
  drm/amdgpu/sdma: Always handle kernel queues in
    amdgpu_sdma_reset_engine()
  drm/amdgpu/sdma: Use common SDMA legacy queue reset on SDMA v4.4.2

 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c      |   2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h      |  21 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      | 102 +++++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |  11 +-
 drivers/gpu/drm/amd/amdgpu/cik_sdma.c         |  32 ----
 drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c        |  30 ----
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c        |  38 +----
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c        |  40 +----
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c      | 158 ++----------------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c        |  60 +------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c        |  52 +-----
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c        |  27 ---
 drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c        |  27 ---
 drivers/gpu/drm/amd/amdgpu/si_dma.c           |   7 -
 .../drm/amd/amdkfd/kfd_device_queue_manager.c |   2 +-
 15 files changed, 121 insertions(+), 488 deletions(-)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/9] drm/amdgpu/sdma: Remove unimplemented soft_reset() for SDMA and SI DMA
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 2/9] drm/amdgpu/sdma: Remove superfluous rlc_resume and rlc_stop functions Timur Kristóf
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

These functions are not called from anywhere
and don't do anything. Let's delete them.

Also remove the srbm_soft_reset field from amdgpu_sdma
which is not set anywhere anymore.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h | 1 -
 drivers/gpu/drm/amd/amdgpu/cik_sdma.c    | 2 --
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c   | 8 +++-----
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c   | 8 --------
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 8 --------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c   | 8 --------
 drivers/gpu/drm/amd/amdgpu/si_dma.c      | 7 -------
 7 files changed, 3 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index 671cfbb67b7a..2b4e51c33e6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -108,7 +108,6 @@ struct amdgpu_sdma {
 	    int			num_inst_per_aid;
 	    int			num_inst_per_xcc;
 	};
-	uint32_t                    srbm_soft_reset;
 	bool			has_page_queue;
 	struct ras_common_if	*ras_if;
 	struct amdgpu_sdma_ras	*ras;
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index de2323e23566..511c9dd3778d 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -55,8 +55,6 @@ static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev);
 static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev);
 static int cik_sdma_soft_reset(struct amdgpu_ip_block *ip_block);
 
-u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev);
-
 MODULE_FIRMWARE("amdgpu/bonaire_sdma.bin");
 MODULE_FIRMWARE("amdgpu/bonaire_sdma1.bin");
 MODULE_FIRMWARE("amdgpu/hawaii_sdma.bin");
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 9478dd034aff..63c94fe52b3c 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -1234,13 +1234,11 @@ static int sdma_v3_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
 static int sdma_v3_0_soft_reset(struct amdgpu_ip_block *ip_block)
 {
 	struct amdgpu_device *adev = ip_block->adev;
-	u32 srbm_soft_reset = 0;
+	u32 srbm_soft_reset;
 	u32 tmp;
 
-	if (!adev->sdma.srbm_soft_reset)
-		return 0;
-
-	srbm_soft_reset = adev->sdma.srbm_soft_reset;
+	srbm_soft_reset = SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK |
+			  SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK;
 
 	if (srbm_soft_reset) {
 		tmp = RREG32(mmSRBM_SOFT_RESET);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 9d7d919a5aa1..ded1f8abfb08 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -2051,13 +2051,6 @@ static int sdma_v4_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static int sdma_v4_0_soft_reset(struct amdgpu_ip_block *ip_block)
-{
-	/* todo */
-
-	return 0;
-}
-
 static int sdma_v4_0_set_trap_irq_state(struct amdgpu_device *adev,
 					struct amdgpu_irq_src *source,
 					unsigned type,
@@ -2403,7 +2396,6 @@ const struct amd_ip_funcs sdma_v4_0_ip_funcs = {
 	.suspend = sdma_v4_0_suspend,
 	.resume = sdma_v4_0_resume,
 	.wait_for_idle = sdma_v4_0_wait_for_idle,
-	.soft_reset = sdma_v4_0_soft_reset,
 	.set_clockgating_state = sdma_v4_0_set_clockgating_state,
 	.set_powergating_state = sdma_v4_0_set_powergating_state,
 	.get_clockgating_state = sdma_v4_0_get_clockgating_state,
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 461f8b220a3e..5212ea6c46a2 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -1651,13 +1651,6 @@ static int sdma_v4_4_2_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static int sdma_v4_4_2_soft_reset(struct amdgpu_ip_block *ip_block)
-{
-	/* todo */
-
-	return 0;
-}
-
 static bool sdma_v4_4_2_is_queue_selected(struct amdgpu_device *adev, uint32_t instance_id, bool is_page_queue)
 {
 	uint32_t reg_offset = is_page_queue ? regSDMA_PAGE_CONTEXT_STATUS : regSDMA_GFX_CONTEXT_STATUS;
@@ -2109,7 +2102,6 @@ const struct amd_ip_funcs sdma_v4_4_2_ip_funcs = {
 	.suspend = sdma_v4_4_2_suspend,
 	.resume = sdma_v4_4_2_resume,
 	.wait_for_idle = sdma_v4_4_2_wait_for_idle,
-	.soft_reset = sdma_v4_4_2_soft_reset,
 	.set_clockgating_state = sdma_v4_4_2_set_clockgating_state,
 	.set_powergating_state = sdma_v4_4_2_set_powergating_state,
 	.get_clockgating_state = sdma_v4_4_2_get_clockgating_state,
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index 97fee70dc2f6..a6fcef36c501 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -1522,13 +1522,6 @@ static int sdma_v5_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static int sdma_v5_0_soft_reset(struct amdgpu_ip_block *ip_block)
-{
-	/* todo */
-
-	return 0;
-}
-
 static int sdma_v5_0_reset_queue(struct amdgpu_ring *ring,
 				 unsigned int vmid,
 				 struct amdgpu_fence *timedout_fence)
@@ -1906,7 +1899,6 @@ static const struct amd_ip_funcs sdma_v5_0_ip_funcs = {
 	.suspend = sdma_v5_0_suspend,
 	.resume = sdma_v5_0_resume,
 	.wait_for_idle = sdma_v5_0_wait_for_idle,
-	.soft_reset = sdma_v5_0_soft_reset,
 	.set_clockgating_state = sdma_v5_0_set_clockgating_state,
 	.set_powergating_state = sdma_v5_0_set_powergating_state,
 	.get_clockgating_state = sdma_v5_0_get_clockgating_state,
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
index 3705a963e660..31ab701d45d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
@@ -600,12 +600,6 @@ static int si_dma_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static int si_dma_soft_reset(struct amdgpu_ip_block *ip_block)
-{
-	drm_info(adev_to_drm(ip_block->adev), "si_dma_soft_reset --- not implemented !!!!!!!\n");
-	return 0;
-}
-
 static int si_dma_set_trap_irq_state(struct amdgpu_device *adev,
 					struct amdgpu_irq_src *src,
 					unsigned type,
@@ -732,7 +726,6 @@ static const struct amd_ip_funcs si_dma_ip_funcs = {
 	.suspend = si_dma_suspend,
 	.resume = si_dma_resume,
 	.wait_for_idle = si_dma_wait_for_idle,
-	.soft_reset = si_dma_soft_reset,
 	.set_clockgating_state = si_dma_set_clockgating_state,
 	.set_powergating_state = si_dma_set_powergating_state,
 };
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/9] drm/amdgpu/sdma: Remove superfluous rlc_resume and rlc_stop functions
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
  2026-09-08 18:10 ` [PATCH 1/9] drm/amdgpu/sdma: Remove unimplemented soft_reset() for SDMA and SI DMA Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 3/9] drm/amdgpu/sdma: Fix executing duplicate commands after recovery on SDMA v4.4.2 Timur Kristóf
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

Every SDMA generation has an rlc_resume and rlc_stop function
which are not doing anything.

Starting from CIK, the SDMA engine supports additional queues
which are called "SDMA compute" or "RLC" queues, and these
queues are used by the KFD, and configured using the HWS.
There is nothing for the kernel driver to do for these.

Let's delete the functions that don't do anything.
In case of SDMA v4.0 and v4.4.2 let's move the init_pg()
call to the start() function.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/cik_sdma.c    | 30 --------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c   | 30 --------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c   | 30 --------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c   | 32 +--------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 36 +-----------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c   | 27 ------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c   | 27 ------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c   | 27 ------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c   | 27 ------------------
 9 files changed, 2 insertions(+), 264 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index 511c9dd3778d..f444207fa550 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -316,18 +316,6 @@ static void cik_sdma_gfx_stop(struct amdgpu_device *adev)
 	}
 }
 
-/**
- * cik_sdma_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues (CIK).
- */
-static void cik_sdma_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * cik_ctx_switch_enable - stop the async dma engines context switch
  *
@@ -400,7 +388,6 @@ static void cik_sdma_enable(struct amdgpu_device *adev, bool enable)
 
 	if (!enable) {
 		cik_sdma_gfx_stop(adev);
-		cik_sdma_rlc_stop(adev);
 	}
 
 	for (i = 0; i < adev->sdma.num_instances; i++) {
@@ -501,20 +488,6 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev)
 	return 0;
 }
 
-/**
- * cik_sdma_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them (CIK).
- * Returns 0 for success, error for failure.
- */
-static int cik_sdma_rlc_resume(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-	return 0;
-}
-
 /**
  * cik_sdma_load_microcode - load the sDMA ME ucode
  *
@@ -577,9 +550,6 @@ static int cik_sdma_start(struct amdgpu_device *adev)
 
 	/* start the gfx rings and rlc compute queues */
 	r = cik_sdma_gfx_resume(adev);
-	if (r)
-		return r;
-	r = cik_sdma_rlc_resume(adev);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
index 657ef6c93c61..7c8acdf73d44 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -349,18 +349,6 @@ static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev)
 	}
 }
 
-/**
- * sdma_v2_4_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues (VI).
- */
-static void sdma_v2_4_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v2_4_enable - stop the async dma engines
  *
@@ -376,7 +364,6 @@ static void sdma_v2_4_enable(struct amdgpu_device *adev, bool enable)
 
 	if (!enable) {
 		sdma_v2_4_gfx_stop(adev);
-		sdma_v2_4_rlc_stop(adev);
 	}
 
 	for (i = 0; i < adev->sdma.num_instances; i++) {
@@ -477,20 +464,6 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev)
 	return 0;
 }
 
-/**
- * sdma_v2_4_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them (VI).
- * Returns 0 for success, error for failure.
- */
-static int sdma_v2_4_rlc_resume(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-	return 0;
-}
-
 
 /**
  * sdma_v2_4_start - setup and start the async dma engines
@@ -509,9 +482,6 @@ static int sdma_v2_4_start(struct amdgpu_device *adev)
 
 	/* start the gfx rings and rlc compute queues */
 	r = sdma_v2_4_gfx_resume(adev);
-	if (r)
-		return r;
-	r = sdma_v2_4_rlc_resume(adev);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 63c94fe52b3c..e929d62721b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -526,18 +526,6 @@ static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev)
 	}
 }
 
-/**
- * sdma_v3_0_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues (VI).
- */
-static void sdma_v3_0_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v3_0_ctx_switch_enable - stop the async dma engines context switch
  *
@@ -614,7 +602,6 @@ static void sdma_v3_0_enable(struct amdgpu_device *adev, bool enable)
 
 	if (!enable) {
 		sdma_v3_0_gfx_stop(adev);
-		sdma_v3_0_rlc_stop(adev);
 	}
 
 	for (i = 0; i < adev->sdma.num_instances; i++) {
@@ -752,20 +739,6 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev)
 	return 0;
 }
 
-/**
- * sdma_v3_0_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them (VI).
- * Returns 0 for success, error for failure.
- */
-static int sdma_v3_0_rlc_resume(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-	return 0;
-}
-
 /**
  * sdma_v3_0_start - setup and start the async dma engines
  *
@@ -784,9 +757,6 @@ static int sdma_v3_0_start(struct amdgpu_device *adev)
 
 	/* start the gfx rings and rlc compute queues */
 	r = sdma_v3_0_gfx_resume(adev);
-	if (r)
-		return r;
-	r = sdma_v3_0_rlc_resume(adev);
 	if (r)
 		return r;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index ded1f8abfb08..bdd140887e10 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -933,18 +933,6 @@ static void sdma_v4_0_gfx_enable(struct amdgpu_device *adev, bool enable)
 	}
 }
 
-/**
- * sdma_v4_0_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues (VEGA10).
- */
-static void sdma_v4_0_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v4_0_page_stop - stop the page async dma engines
  *
@@ -1047,7 +1035,6 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable)
 
 	if (!enable) {
 		sdma_v4_0_gfx_enable(adev, enable);
-		sdma_v4_0_rlc_stop(adev);
 		if (adev->sdma.has_page_queue)
 			sdma_v4_0_page_stop(adev);
 	}
@@ -1312,21 +1299,6 @@ static void sdma_v4_0_init_pg(struct amdgpu_device *adev)
 	}
 }
 
-/**
- * sdma_v4_0_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them (VEGA10).
- * Returns 0 for success, error for failure.
- */
-static int sdma_v4_0_rlc_resume(struct amdgpu_device *adev)
-{
-	sdma_v4_0_init_pg(adev);
-
-	return 0;
-}
-
 /**
  * sdma_v4_0_load_microcode - load the sDMA ME ucode
  *
@@ -1426,9 +1398,7 @@ static int sdma_v4_0_start(struct amdgpu_device *adev)
 		sdma_v4_0_ctx_switch_enable(adev, true);
 		sdma_v4_0_enable(adev, true);
 	} else {
-		r = sdma_v4_0_rlc_resume(adev);
-		if (r)
-			return r;
+		sdma_v4_0_init_pg(adev);
 	}
 
 	for (i = 0; i < adev->sdma.num_instances; i++) {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 5212ea6c46a2..7e8d528cf422 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -520,20 +520,6 @@ static void sdma_v4_4_2_inst_gfx_stop(struct amdgpu_device *adev,
 	}
 }
 
-/**
- * sdma_v4_4_2_inst_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- * @inst_mask: mask of dma engine instances to be disabled
- *
- * Stop the compute async dma queues.
- */
-static void sdma_v4_4_2_inst_rlc_stop(struct amdgpu_device *adev,
-				      uint32_t inst_mask)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v4_4_2_inst_page_stop - stop the page async dma engines
  *
@@ -632,7 +618,6 @@ static void sdma_v4_4_2_inst_enable(struct amdgpu_device *adev, bool enable,
 
 	if (!enable) {
 		sdma_v4_4_2_inst_gfx_stop(adev, inst_mask);
-		sdma_v4_4_2_inst_rlc_stop(adev, inst_mask);
 		if (adev->sdma.has_page_queue)
 			sdma_v4_4_2_inst_page_stop(adev, inst_mask);
 
@@ -888,23 +873,6 @@ static void sdma_v4_4_2_init_pg(struct amdgpu_device *adev)
 
 }
 
-/**
- * sdma_v4_4_2_inst_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- * @inst_mask: mask of dma engine instances to be enabled
- *
- * Set up the compute DMA queues and enable them.
- * Returns 0 for success, error for failure.
- */
-static int sdma_v4_4_2_inst_rlc_resume(struct amdgpu_device *adev,
-				       uint32_t inst_mask)
-{
-	sdma_v4_4_2_init_pg(adev);
-
-	return 0;
-}
-
 /**
  * sdma_v4_4_2_inst_load_microcode - load the sDMA ME ucode
  *
@@ -1019,9 +987,7 @@ static int sdma_v4_4_2_inst_start(struct amdgpu_device *adev,
 		sdma_v4_4_2_inst_ctx_switch_enable(adev, true, inst_mask);
 		sdma_v4_4_2_inst_enable(adev, true, inst_mask);
 	} else {
-		r = sdma_v4_4_2_inst_rlc_resume(adev, inst_mask);
-		if (r)
-			return r;
+		sdma_v4_4_2_init_pg(adev);
 	}
 
 	tmp_mask = inst_mask;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index a6fcef36c501..d24659a69382 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -574,18 +574,6 @@ static void sdma_v5_0_gfx_stop(struct amdgpu_device *adev, uint32_t inst_mask)
 	}
 }
 
-/**
- * sdma_v5_0_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues (NAVI10).
- */
-static void sdma_v5_0_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v5_0_ctx_switch_enable - stop the async dma engines context switch
  *
@@ -661,7 +649,6 @@ static void sdma_v5_0_enable(struct amdgpu_device *adev, bool enable)
 	inst_mask = GENMASK(adev->sdma.num_instances - 1, 0);
 	if (!enable) {
 		sdma_v5_0_gfx_stop(adev, 1 << inst_mask);
-		sdma_v5_0_rlc_stop(adev);
 	}
 
 	if (amdgpu_sriov_vf(adev))
@@ -858,19 +845,6 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev)
 	return 0;
 }
 
-/**
- * sdma_v5_0_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them (NAVI10).
- * Returns 0 for success, error for failure.
- */
-static int sdma_v5_0_rlc_resume(struct amdgpu_device *adev)
-{
-	return 0;
-}
-
 /**
  * sdma_v5_0_load_microcode - load the sDMA ME ucode
  *
@@ -951,7 +925,6 @@ static int sdma_v5_0_start(struct amdgpu_device *adev)
 	r = sdma_v5_0_gfx_resume(adev);
 	if (r)
 		return r;
-	r = sdma_v5_0_rlc_resume(adev);
 
 	return r;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index 35cdf6c149f8..76e1f9f39525 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -424,18 +424,6 @@ static void sdma_v5_2_gfx_stop(struct amdgpu_device *adev,  uint32_t inst_mask)
 	}
 }
 
-/**
- * sdma_v5_2_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues.
- */
-static void sdma_v5_2_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v5_2_ctx_switch_enable - stop the async dma engines context switch
  *
@@ -510,7 +498,6 @@ static void sdma_v5_2_enable(struct amdgpu_device *adev, bool enable)
 	inst_mask = GENMASK(adev->sdma.num_instances - 1, 0);
 	if (!enable) {
 		sdma_v5_2_gfx_stop(adev, inst_mask);
-		sdma_v5_2_rlc_stop(adev);
 	}
 
 	if (!amdgpu_sriov_vf(adev)) {
@@ -705,19 +692,6 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev)
 	return 0;
 }
 
-/**
- * sdma_v5_2_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them.
- * Returns 0 for success, error for failure.
- */
-static int sdma_v5_2_rlc_resume(struct amdgpu_device *adev)
-{
-	return 0;
-}
-
 /**
  * sdma_v5_2_load_microcode - load the sDMA ME ucode
  *
@@ -851,7 +825,6 @@ static int sdma_v5_2_start(struct amdgpu_device *adev)
 	r = sdma_v5_2_gfx_resume(adev);
 	if (r)
 		return r;
-	r = sdma_v5_2_rlc_resume(adev);
 
 	return r;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
index 303fd7d1b7c8..52a141d0b356 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
@@ -407,18 +407,6 @@ static void sdma_v6_0_gfx_stop(struct amdgpu_device *adev)
 	}
 }
 
-/**
- * sdma_v6_0_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues.
- */
-static void sdma_v6_0_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v6_0_ctxempty_int_enable - enable or disable context empty interrupts
  *
@@ -457,7 +445,6 @@ static void sdma_v6_0_enable(struct amdgpu_device *adev, bool enable)
 
 	if (!enable) {
 		sdma_v6_0_gfx_stop(adev);
-		sdma_v6_0_rlc_stop(adev);
 	}
 
 	if (amdgpu_sriov_vf(adev))
@@ -642,19 +629,6 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
 	return 0;
 }
 
-/**
- * sdma_v6_0_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them.
- * Returns 0 for success, error for failure.
- */
-static int sdma_v6_0_rlc_resume(struct amdgpu_device *adev)
-{
-	return 0;
-}
-
 /**
  * sdma_v6_0_load_microcode - load the sDMA ME ucode
  *
@@ -832,7 +806,6 @@ static int sdma_v6_0_start(struct amdgpu_device *adev)
 	r = sdma_v6_0_gfx_resume(adev);
 	if (r)
 		return r;
-	r = sdma_v6_0_rlc_resume(adev);
 
 	return r;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
index d5552f206e4d..231bc347df2a 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
@@ -409,18 +409,6 @@ static void sdma_v7_0_gfx_stop(struct amdgpu_device *adev)
 	}
 }
 
-/**
- * sdma_v7_0_rlc_stop - stop the compute async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Stop the compute async dma queues.
- */
-static void sdma_v7_0_rlc_stop(struct amdgpu_device *adev)
-{
-	/* XXX todo */
-}
-
 /**
  * sdma_v7_0_ctx_switch_enable - stop the async dma engines context switch
  *
@@ -448,7 +436,6 @@ static void sdma_v7_0_enable(struct amdgpu_device *adev, bool enable)
 
 	if (!enable) {
 		sdma_v7_0_gfx_stop(adev);
-		sdma_v7_0_rlc_stop(adev);
 	}
 
 	if (amdgpu_sriov_vf(adev))
@@ -643,19 +630,6 @@ static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
 
 }
 
-/**
- * sdma_v7_0_rlc_resume - setup and start the async dma engines
- *
- * @adev: amdgpu_device pointer
- *
- * Set up the compute DMA queues and enable them.
- * Returns 0 for success, error for failure.
- */
-static int sdma_v7_0_rlc_resume(struct amdgpu_device *adev)
-{
-	return 0;
-}
-
 static void sdma_v12_0_free_ucode_buffer(struct amdgpu_device *adev)
 {
 	int i;
@@ -850,7 +824,6 @@ static int sdma_v7_0_start(struct amdgpu_device *adev)
 	r = sdma_v7_0_gfx_resume(adev);
 	if (r)
 		return r;
-	r = sdma_v7_0_rlc_resume(adev);
 
 	return r;
 }
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/9] drm/amdgpu/sdma: Fix executing duplicate commands after recovery on SDMA v4.4.2
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
  2026-09-08 18:10 ` [PATCH 1/9] drm/amdgpu/sdma: Remove unimplemented soft_reset() for SDMA and SI DMA Timur Kristóf
  2026-09-08 18:10 ` [PATCH 2/9] drm/amdgpu/sdma: Remove superfluous rlc_resume and rlc_stop functions Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 4/9] drm/amdgpu/sdma: Remove unnecessary guilty tracking of SDMA queues Timur Kristóf
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

SDMA v4.4.2 had a custom recovery implementation that
tried to keep ring contents and restore the rptr after
an SDMA soft reset. Later it was changed to use the
more common amdgpu_sdma_reset_engine() implementation.

Currently, SDMA v4.4.2 may execute some commands twice
after a recovery:

1. From the old ring buffer contents at the restored rptr
2. From the contents restored by amdgpu_sdma_reset_engine()
   that calls the ring reset helper functions.

Fix that by removing the code that restores rptr.
This is not needed anymore because amdgpu_sdma_reset_engine()
already saves and restores the contents of both the SDMA gfx
and paging rings, so there is no need to do anything extra.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c |  2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h |  2 -
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 76 +++++-------------------
 3 files changed, 14 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 686c92e96025..132ca5ce3a6d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -347,8 +347,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
 	ring->buf_mask = (ring->ring_size / 4) - 1;
 	ring->ptr_mask = ring->funcs->support_64bit_ptrs ?
 		0xffffffffffffffff : ring->buf_mask;
-	/*  Initialize cached_rptr to 0 */
-	ring->cached_rptr = 0;
 
 	if (!ring->ring_backup) {
 		ring->ring_backup = kvzalloc(ring->ring_size, GFP_KERNEL);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 6b6ee4083c8d..61e30de1977b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -423,8 +423,6 @@ struct amdgpu_ring {
 
 	bool            is_sw_ring;
 	unsigned int    entry_index;
-	/* store the cached rptr to restore after reset */
-	uint64_t cached_rptr;
 };
 
 #define amdgpu_ring_parse_cs(r, p, job, ib) ((r)->funcs->parse_cs((p), (job), (ib)))
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 7e8d528cf422..53c816043eb8 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -660,12 +660,11 @@ static uint32_t sdma_v4_4_2_rb_cntl(struct amdgpu_ring *ring, uint32_t rb_cntl)
  *
  * @adev: amdgpu_device pointer
  * @i: instance to resume
- * @restore: used to restore wptr when restart
  *
  * Set up the gfx DMA ring buffers and enable them.
  * Returns 0 for success, error for failure.
  */
-static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i, bool restore)
+static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i)
 {
 	struct amdgpu_ring *ring = &adev->sdma.instance[i].ring;
 	u32 rb_cntl, ib_cntl, wptr_poll_cntl;
@@ -673,7 +672,6 @@ static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i, b
 	u32 doorbell;
 	u32 doorbell_offset;
 	u64 wptr_gpu_addr;
-	u64 rwptr;
 
 	wb_offset = (ring->rptr_offs * 4);
 
@@ -693,32 +691,16 @@ static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i, b
 	WREG32_SDMA(i, regSDMA_GFX_RB_BASE, ring->gpu_addr >> 8);
 	WREG32_SDMA(i, regSDMA_GFX_RB_BASE_HI, ring->gpu_addr >> 40);
 
-	if (!restore)
-		ring->wptr = 0;
+	ring->wptr = 0;
 
 	/* before programing wptr to a less value, need set minor_ptr_update first */
 	WREG32_SDMA(i, regSDMA_GFX_MINOR_PTR_UPDATE, 1);
 
-	/* For the guilty queue, set RPTR to the current wptr to skip bad commands,
-	 * It is not a guilty queue, restore cache_rptr and continue execution.
-	 */
-	if (adev->sdma.instance[i].gfx_guilty)
-		rwptr = ring->wptr;
-	else
-		rwptr = ring->cached_rptr;
-
 	/* Initialize the ring buffer's read and write pointers */
-	if (restore) {
-		WREG32_SDMA(i, regSDMA_GFX_RB_RPTR, lower_32_bits(rwptr << 2));
-		WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_HI, upper_32_bits(rwptr << 2));
-		WREG32_SDMA(i, regSDMA_GFX_RB_WPTR, lower_32_bits(rwptr << 2));
-		WREG32_SDMA(i, regSDMA_GFX_RB_WPTR_HI, upper_32_bits(rwptr << 2));
-	} else {
-		WREG32_SDMA(i, regSDMA_GFX_RB_RPTR, 0);
-		WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_HI, 0);
-		WREG32_SDMA(i, regSDMA_GFX_RB_WPTR, 0);
-		WREG32_SDMA(i, regSDMA_GFX_RB_WPTR_HI, 0);
-	}
+	WREG32_SDMA(i, regSDMA_GFX_RB_RPTR, 0);
+	WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_HI, 0);
+	WREG32_SDMA(i, regSDMA_GFX_RB_WPTR, 0);
+	WREG32_SDMA(i, regSDMA_GFX_RB_WPTR_HI, 0);
 
 	doorbell = RREG32_SDMA(i, regSDMA_GFX_DOORBELL);
 	doorbell_offset = RREG32_SDMA(i, regSDMA_GFX_DOORBELL_OFFSET);
@@ -771,7 +753,7 @@ static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i, b
  * Set up the page DMA ring buffers and enable them.
  * Returns 0 for success, error for failure.
  */
-static void sdma_v4_4_2_page_resume(struct amdgpu_device *adev, unsigned int i, bool restore)
+static void sdma_v4_4_2_page_resume(struct amdgpu_device *adev, unsigned int i)
 {
 	struct amdgpu_ring *ring = &adev->sdma.instance[i].page;
 	u32 rb_cntl, ib_cntl, wptr_poll_cntl;
@@ -779,7 +761,6 @@ static void sdma_v4_4_2_page_resume(struct amdgpu_device *adev, unsigned int i,
 	u32 doorbell;
 	u32 doorbell_offset;
 	u64 wptr_gpu_addr;
-	u64 rwptr;
 
 	wb_offset = (ring->rptr_offs * 4);
 
@@ -787,26 +768,11 @@ static void sdma_v4_4_2_page_resume(struct amdgpu_device *adev, unsigned int i,
 	rb_cntl = sdma_v4_4_2_rb_cntl(ring, rb_cntl);
 	WREG32_SDMA(i, regSDMA_PAGE_RB_CNTL, rb_cntl);
 
-	/* For the guilty queue, set RPTR to the current wptr to skip bad commands,
-	 * It is not a guilty queue, restore cache_rptr and continue execution.
-	 */
-	if (adev->sdma.instance[i].page_guilty)
-		rwptr = ring->wptr;
-	else
-		rwptr = ring->cached_rptr;
-
 	/* Initialize the ring buffer's read and write pointers */
-	if (restore) {
-		WREG32_SDMA(i, regSDMA_PAGE_RB_RPTR, lower_32_bits(rwptr << 2));
-		WREG32_SDMA(i, regSDMA_PAGE_RB_RPTR_HI, upper_32_bits(rwptr << 2));
-		WREG32_SDMA(i, regSDMA_PAGE_RB_WPTR, lower_32_bits(rwptr << 2));
-		WREG32_SDMA(i, regSDMA_PAGE_RB_WPTR_HI, upper_32_bits(rwptr << 2));
-	} else {
-		WREG32_SDMA(i, regSDMA_PAGE_RB_RPTR, 0);
-		WREG32_SDMA(i, regSDMA_PAGE_RB_RPTR_HI, 0);
-		WREG32_SDMA(i, regSDMA_PAGE_RB_WPTR, 0);
-		WREG32_SDMA(i, regSDMA_PAGE_RB_WPTR_HI, 0);
-	}
+	WREG32_SDMA(i, regSDMA_PAGE_RB_RPTR, 0);
+	WREG32_SDMA(i, regSDMA_PAGE_RB_RPTR_HI, 0);
+	WREG32_SDMA(i, regSDMA_PAGE_RB_WPTR, 0);
+	WREG32_SDMA(i, regSDMA_PAGE_RB_WPTR_HI, 0);
 
 	/* set the wb address whether it's enabled or not */
 	WREG32_SDMA(i, regSDMA_PAGE_RB_RPTR_ADDR_HI,
@@ -820,8 +786,7 @@ static void sdma_v4_4_2_page_resume(struct amdgpu_device *adev, unsigned int i,
 	WREG32_SDMA(i, regSDMA_PAGE_RB_BASE, ring->gpu_addr >> 8);
 	WREG32_SDMA(i, regSDMA_PAGE_RB_BASE_HI, ring->gpu_addr >> 40);
 
-	if (!restore)
-		ring->wptr = 0;
+	ring->wptr = 0;
 
 	/* before programing wptr to a less value, need set minor_ptr_update first */
 	WREG32_SDMA(i, regSDMA_PAGE_MINOR_PTR_UPDATE, 1);
@@ -959,9 +924,9 @@ static int sdma_v4_4_2_inst_start(struct amdgpu_device *adev,
 		uint32_t temp;
 
 		WREG32_SDMA(i, regSDMA_SEM_WAIT_FAIL_TIMER_CNTL, 0);
-		sdma_v4_4_2_gfx_resume(adev, i, restore);
+		sdma_v4_4_2_gfx_resume(adev, i);
 		if (adev->sdma.has_page_queue)
-			sdma_v4_4_2_page_resume(adev, i, restore);
+			sdma_v4_4_2_page_resume(adev, i);
 
 		/* set utc l1 enable flag always to 1 */
 		temp = RREG32_SDMA(i, regSDMA_CNTL);
@@ -1645,7 +1610,6 @@ static int sdma_v4_4_2_stop_queue(struct amdgpu_ring *ring)
 	struct amdgpu_device *adev = ring->adev;
 	u32 instance_id = ring->me;
 	u32 inst_mask;
-	uint64_t rptr;
 
 	if (amdgpu_sriov_vf(adev))
 		return -EINVAL;
@@ -1657,18 +1621,6 @@ static int sdma_v4_4_2_stop_queue(struct amdgpu_ring *ring)
 		adev->sdma.instance[instance_id].page_guilty =
 			sdma_v4_4_2_is_queue_selected(adev, instance_id, true);
 
-	/* Cache the rptr before reset, after the reset,
-	* all of the registers will be reset to 0
-	*/
-	rptr = amdgpu_ring_get_rptr(ring);
-	ring->cached_rptr = rptr;
-	/* Cache the rptr for the page queue if it exists */
-	if (adev->sdma.has_page_queue) {
-		struct amdgpu_ring *page_ring = &adev->sdma.instance[instance_id].page;
-		rptr = amdgpu_ring_get_rptr(page_ring);
-		page_ring->cached_rptr = rptr;
-	}
-
 	/* stop queue */
 	inst_mask = 1 << ring->me;
 	sdma_v4_4_2_inst_gfx_stop(adev, inst_mask);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/9] drm/amdgpu/sdma: Remove unnecessary guilty tracking of SDMA queues
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
                   ` (2 preceding siblings ...)
  2026-09-08 18:10 ` [PATCH 3/9] drm/amdgpu/sdma: Fix executing duplicate commands after recovery on SDMA v4.4.2 Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 5/9] drm/amdgpu: Add amdgpu_ring_clear_ring_and_ptrs() Timur Kristóf
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

amdgpu_sdma_reset_engine() saves and restores contents of
both the SDMA gfx queue and the paging queue, so it's
not necessary to track which queue was guilty anymore.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h |  3 ---
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 20 --------------------
 2 files changed, 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index 2b4e51c33e6f..44ba997c8e80 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -79,9 +79,6 @@ struct amdgpu_sdma_instance {
 	uint64_t		sdma_fw_gpu_addr;
 	uint32_t		*sdma_fw_ptr;
 	struct mutex		engine_reset_mutex;
-	/* track guilty state of GFX and PAGE queues */
-	bool			gfx_guilty;
-	bool			page_guilty;
 	const struct amdgpu_sdma_funcs   *funcs;
 };
 
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 53c816043eb8..0ca774959401 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -1409,9 +1409,6 @@ static int sdma_v4_4_2_sw_init(struct amdgpu_ip_block *ip_block)
 
 	for (i = 0; i < adev->sdma.num_instances; i++) {
 		mutex_init(&adev->sdma.instance[i].engine_reset_mutex);
-		/* Initialize guilty flags for GFX and PAGE queues */
-		adev->sdma.instance[i].gfx_guilty = false;
-		adev->sdma.instance[i].page_guilty = false;
 		adev->sdma.instance[i].funcs = &sdma_v4_4_2_sdma_funcs;
 
 		ring = &adev->sdma.instance[i].ring;
@@ -1582,15 +1579,6 @@ static int sdma_v4_4_2_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static bool sdma_v4_4_2_is_queue_selected(struct amdgpu_device *adev, uint32_t instance_id, bool is_page_queue)
-{
-	uint32_t reg_offset = is_page_queue ? regSDMA_PAGE_CONTEXT_STATUS : regSDMA_GFX_CONTEXT_STATUS;
-	uint32_t context_status = RREG32(sdma_v4_4_2_get_reg_offset(adev, instance_id, reg_offset));
-
-	/* Check if the SELECTED bit is set */
-	return (context_status & SDMA_GFX_CONTEXT_STATUS__SELECTED_MASK) != 0;
-}
-
 static int sdma_v4_4_2_reset_queue(struct amdgpu_ring *ring,
 				   unsigned int vmid,
 				   struct amdgpu_fence *timedout_fence)
@@ -1608,19 +1596,11 @@ static int sdma_v4_4_2_reset_queue(struct amdgpu_ring *ring,
 static int sdma_v4_4_2_stop_queue(struct amdgpu_ring *ring)
 {
 	struct amdgpu_device *adev = ring->adev;
-	u32 instance_id = ring->me;
 	u32 inst_mask;
 
 	if (amdgpu_sriov_vf(adev))
 		return -EINVAL;
 
-	/* Check if this queue is the guilty one */
-	adev->sdma.instance[instance_id].gfx_guilty =
-		sdma_v4_4_2_is_queue_selected(adev, instance_id, false);
-	if (adev->sdma.has_page_queue)
-		adev->sdma.instance[instance_id].page_guilty =
-			sdma_v4_4_2_is_queue_selected(adev, instance_id, true);
-
 	/* stop queue */
 	inst_mask = 1 << ring->me;
 	sdma_v4_4_2_inst_gfx_stop(adev, inst_mask);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/9] drm/amdgpu: Add amdgpu_ring_clear_ring_and_ptrs()
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
                   ` (3 preceding siblings ...)
  2026-09-08 18:10 ` [PATCH 4/9] drm/amdgpu/sdma: Remove unnecessary guilty tracking of SDMA queues Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 6/9] drm/amdgpu/sdma: Clear SDMA rings after reset before starting them Timur Kristóf
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

A new helper function which clears the contents of
a ring and the relevant pointers such as rptr/wptr.

Suggested-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 61e30de1977b..49df2c4745a1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -488,6 +488,25 @@ static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
 	memset32(ring->ring, ring->funcs->nop, ring->buf_mask + 1);
 }
 
+static inline void amdgpu_ring_clear_ring_and_ptrs(struct amdgpu_ring *ring)
+{
+	/* Clear the contents of the ring. */
+	amdgpu_ring_clear_ring(ring);
+
+	/* Clear the ring pointers on the CPU. */
+	ring->wptr = 0;
+
+	/*
+	 * Clear the ring pointers allocated in writeback.
+	 *
+	 * Note: we always allocate 64 bits for these pointers,
+	 * but older HW generations only use the lower 32 bits.
+	 * Use 64-bit atomics for simplicity.
+	 */
+	atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0);
+	atomic64_set((atomic64_t *)ring->rptr_cpu_addr, 0);
+}
+
 static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
 {
 	ring->ring[ring->wptr++ & ring->buf_mask] = v;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/9] drm/amdgpu/sdma: Clear SDMA rings after reset before starting them
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
                   ` (4 preceding siblings ...)
  2026-09-08 18:10 ` [PATCH 5/9] drm/amdgpu: Add amdgpu_ring_clear_ring_and_ptrs() Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 7/9] drm/amdgpu/sdma: Move SDMA v5.x queue reset to common code Timur Kristóf
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

The ring contains commands that were emitted before the reset.
These need to be cleared to make sure the HW doesn't execute
them, because they are garbage at this point.

Note that the ring reset helpers will re-emit the commands
that are necessary after the reset.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index fbac732f3e01..3495b7553950 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -593,6 +593,11 @@ int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id,
 		goto exit;
 	}
 
+	amdgpu_ring_clear_ring_and_ptrs(gfx_ring);
+
+	if (adev->sdma.has_page_queue)
+		amdgpu_ring_clear_ring_and_ptrs(page_ring);
+
 	if (sdma_instance->funcs->start_kernel_queue) {
 		sdma_instance->funcs->start_kernel_queue(gfx_ring);
 		if (adev->sdma.has_page_queue)
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/9] drm/amdgpu/sdma: Move SDMA v5.x queue reset to common code
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
                   ` (5 preceding siblings ...)
  2026-09-08 18:10 ` [PATCH 6/9] drm/amdgpu/sdma: Clear SDMA rings after reset before starting them Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 8/9] drm/amdgpu/sdma: Always handle kernel queues in amdgpu_sdma_reset_engine() Timur Kristóf
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

The code was exactly the same between SDMA v5.0 and v5.2
furthermore the exact same implementation can be shared
between all SDMA versions that don't use MES.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 37 ++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h |  4 +++
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c   | 25 +---------------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c   | 25 +---------------
 4 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index 3495b7553950..71a7a70a80c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -628,3 +628,40 @@ int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id,
 
 	return ret;
 }
+
+/**
+ * amdgpu_sdma_reset_queue_legacy() - Reset legacy SDMA queue after timeout (without MES)
+ *
+ * @ring: Pointer to the ring of the SDMA queue
+ * @vmid: VMID of the timed out job
+ * @timedout_fence: Fence of the timed out job
+ *
+ * Common implementation for resetting SDMA queues without MES (legacy).
+ * This relies on the proper amdgpu_sdma_funcs to be set up
+ * for the given ring.
+ *
+ * Applicable to SDMA versions that don't rely on the MES yet,
+ * that is all versions up to SDMA v5.x and older.
+ */
+int amdgpu_sdma_reset_queue_legacy(struct amdgpu_ring *ring,
+				   unsigned int vmid,
+				   struct amdgpu_fence *timedout_fence)
+{
+	struct amdgpu_device *adev = ring->adev;
+	int r;
+
+	if (ring->me >= adev->sdma.num_instances) {
+		dev_err(adev->dev, "sdma instance not found\n");
+		return -EINVAL;
+	}
+
+	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
+
+	amdgpu_amdkfd_suspend(adev, true);
+	r = amdgpu_sdma_reset_engine(adev, ring->me, true);
+	amdgpu_amdkfd_resume(adev, true);
+	if (r)
+		return r;
+
+	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index 44ba997c8e80..fb0316b28f9d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -157,6 +157,10 @@ struct amdgpu_buffer_funcs {
 int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id,
 			     bool caller_handles_kernel_queues);
 
+int amdgpu_sdma_reset_queue_legacy(struct amdgpu_ring *ring,
+				   unsigned int vmid,
+				   struct amdgpu_fence *timedout_fence);
+
 #define amdgpu_emit_copy_buffer(adev, ib, s, d, b, t) (adev)->mman.buffer_funcs->emit_copy_buffer((ib),  (s), (d), (b), (t))
 #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
 
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index d24659a69382..a4d2a107c74f 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -1495,29 +1495,6 @@ static int sdma_v5_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static int sdma_v5_0_reset_queue(struct amdgpu_ring *ring,
-				 unsigned int vmid,
-				 struct amdgpu_fence *timedout_fence)
-{
-	struct amdgpu_device *adev = ring->adev;
-	int r;
-
-	if (ring->me >= adev->sdma.num_instances) {
-		dev_err(adev->dev, "sdma instance not found\n");
-		return -EINVAL;
-	}
-
-	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
-
-	amdgpu_amdkfd_suspend(adev, true);
-	r = amdgpu_sdma_reset_engine(adev, ring->me, true);
-	amdgpu_amdkfd_resume(adev, true);
-	if (r)
-		return r;
-
-	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
-}
-
 static int sdma_v5_0_stop_queue(struct amdgpu_ring *ring)
 {
 	u32 f32_cntl, freeze, cntl, stat1_reg;
@@ -1913,7 +1890,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
 	.emit_reg_write_reg_wait = sdma_v5_0_ring_emit_reg_write_reg_wait,
 	.init_cond_exec = sdma_v5_0_ring_init_cond_exec,
 	.preempt_ib = sdma_v5_0_ring_preempt_ib,
-	.reset = sdma_v5_0_reset_queue,
+	.reset = amdgpu_sdma_reset_queue_legacy,
 };
 
 static void sdma_v5_0_set_ring_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index 76e1f9f39525..e7613e27e774 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -1414,29 +1414,6 @@ static int sdma_v5_2_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static int sdma_v5_2_reset_queue(struct amdgpu_ring *ring,
-				 unsigned int vmid,
-				 struct amdgpu_fence *timedout_fence)
-{
-	struct amdgpu_device *adev = ring->adev;
-	int r;
-
-	if (ring->me >= adev->sdma.num_instances) {
-		dev_err(adev->dev, "sdma instance not found\n");
-		return -EINVAL;
-	}
-
-	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
-
-	amdgpu_amdkfd_suspend(adev, true);
-	r = amdgpu_sdma_reset_engine(adev, ring->me, true);
-	amdgpu_amdkfd_resume(adev, true);
-	if (r)
-		return r;
-
-	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
-}
-
 static int sdma_v5_2_stop_queue(struct amdgpu_ring *ring)
 {
 	u32 f32_cntl, freeze, cntl, stat1_reg;
@@ -1929,7 +1906,7 @@ static const struct amdgpu_ring_funcs sdma_v5_2_ring_funcs = {
 	.emit_reg_write_reg_wait = sdma_v5_2_ring_emit_reg_write_reg_wait,
 	.init_cond_exec = sdma_v5_2_ring_init_cond_exec,
 	.preempt_ib = sdma_v5_2_ring_preempt_ib,
-	.reset = sdma_v5_2_reset_queue,
+	.reset = amdgpu_sdma_reset_queue_legacy,
 };
 
 static void sdma_v5_2_set_ring_funcs(struct amdgpu_device *adev)
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/9] drm/amdgpu/sdma: Always handle kernel queues in amdgpu_sdma_reset_engine()
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
                   ` (6 preceding siblings ...)
  2026-09-08 18:10 ` [PATCH 7/9] drm/amdgpu/sdma: Move SDMA v5.x queue reset to common code Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-08 18:10 ` [PATCH 9/9] drm/amdgpu/sdma: Use common SDMA legacy queue reset on SDMA v4.4.2 Timur Kristóf
  2026-09-11 18:44 ` [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Alex Deucher
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

Remove the caller_handles_kernel_queues argument from
the amdgpu_sdma_reset_engine() function and make it
always handle kernel queues.

Now the SDMA recovery sequence is more consistent
between callers for the KFD as follows.
Before recovery: first the KFD is suspended,
then the SDMA queue contents are backed up.
After recovery: first the SDMA queue contents
are restored, then the KFD is resumed.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      | 68 ++++++++++---------
 drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |  3 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c      |  2 +-
 .../drm/amd/amdkfd/kfd_device_queue_manager.c |  2 +-
 4 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index 71a7a70a80c4..0286e3dd958e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -542,16 +542,14 @@ static int amdgpu_sdma_soft_reset(struct amdgpu_device *adev, u32 instance_id)
 }
 
 /**
- * amdgpu_sdma_reset_engine - Reset a specific SDMA engine
+ * amdgpu_sdma_reset_engine() - Reset a specific SDMA engine instance.
+ *
  * @adev: Pointer to the AMDGPU device
  * @instance_id: Logical ID of the SDMA engine instance to reset
- * @caller_handles_kernel_queues: Skip kernel queue processing. Caller
- * will handle it.
  *
  * Returns: 0 on success, or a negative error code on failure.
  */
-int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id,
-			     bool caller_handles_kernel_queues)
+int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id)
 {
 	struct amdgpu_sdma_instance *sdma_instance = &adev->sdma.instance[instance_id];
 	struct amdgpu_ring *gfx_ring = &sdma_instance->ring;
@@ -564,20 +562,23 @@ int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id,
 
 	mutex_lock(&sdma_instance->engine_reset_mutex);
 
-	if (!caller_handles_kernel_queues) {
-		/* Stop the scheduler's work queue for the GFX and page rings if they are running.
-		 * This ensures that no new tasks are submitted to the queues while
-		 * the reset is in progress.
-		 */
+	/*
+	 * Stop the scheduler's work queue for the GFX and page rings if they are running.
+	 * This ensures that no new tasks are submitted to the queues while
+	 * the reset is in progress.
+	 */
+	if (amdgpu_ring_sched_ready(gfx_ring) && !drm_sched_is_stopped(&gfx_ring->sched))
 		drm_sched_wqueue_stop(&gfx_ring->sched);
-		gfx_fence = amdgpu_ring_find_guilty_fence(gfx_ring);
-		amdgpu_ring_reset_helper_begin(gfx_ring, gfx_fence);
 
-		if (adev->sdma.has_page_queue) {
+	gfx_fence = amdgpu_ring_find_guilty_fence(gfx_ring);
+	amdgpu_ring_reset_helper_begin(gfx_ring, gfx_fence);
+
+	if (adev->sdma.has_page_queue) {
+		if (amdgpu_ring_sched_ready(page_ring) && !drm_sched_is_stopped(&page_ring->sched))
 			drm_sched_wqueue_stop(&page_ring->sched);
-			page_fence = amdgpu_ring_find_guilty_fence(page_ring);
-			amdgpu_ring_reset_helper_begin(page_ring, page_fence);
-		}
+
+		page_fence = amdgpu_ring_find_guilty_fence(page_ring);
+		amdgpu_ring_reset_helper_begin(page_ring, page_fence);
 	}
 
 	if (sdma_instance->funcs->stop_kernel_queue) {
@@ -605,22 +606,25 @@ int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id,
 	}
 
 exit:
-	if (!caller_handles_kernel_queues) {
-		/* Restart the scheduler's work queue for the GFX and page rings
-		 * if they were stopped by this function. This allows new tasks
-		 * to be submitted to the queues after the reset is complete.
-		 */
-		if (!ret) {
-			ret = amdgpu_ring_reset_helper_end(gfx_ring, gfx_fence);
+	/* Restart the scheduler's work queue for the GFX and page rings
+	 * if they were stopped by this function. This allows new tasks
+	 * to be submitted to the queues after the reset is complete.
+	 */
+	if (!ret) {
+		ret = amdgpu_ring_reset_helper_end(gfx_ring, gfx_fence);
+		if (ret)
+			goto unlock;
+
+		if (amdgpu_ring_sched_ready(gfx_ring))
+			drm_sched_wqueue_start(&gfx_ring->sched);
+
+		if (adev->sdma.has_page_queue) {
+			ret = amdgpu_ring_reset_helper_end(page_ring, page_fence);
 			if (ret)
 				goto unlock;
-			drm_sched_wqueue_start(&gfx_ring->sched);
-			if (adev->sdma.has_page_queue) {
-				ret = amdgpu_ring_reset_helper_end(page_ring, page_fence);
-				if (ret)
-					goto unlock;
+
+			if (amdgpu_ring_sched_ready(page_ring))
 				drm_sched_wqueue_start(&page_ring->sched);
-			}
 		}
 	}
 unlock:
@@ -655,13 +659,11 @@ int amdgpu_sdma_reset_queue_legacy(struct amdgpu_ring *ring,
 		return -EINVAL;
 	}
 
-	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
-
 	amdgpu_amdkfd_suspend(adev, true);
-	r = amdgpu_sdma_reset_engine(adev, ring->me, true);
+	r = amdgpu_sdma_reset_engine(adev, ring->me);
 	amdgpu_amdkfd_resume(adev, true);
 	if (r)
 		return r;
 
-	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
+	return 0;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index fb0316b28f9d..8d0fcc7f6cac 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -154,8 +154,7 @@ struct amdgpu_buffer_funcs {
 				 uint32_t byte_count);
 };
 
-int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id,
-			     bool caller_handles_kernel_queues);
+int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id);
 
 int amdgpu_sdma_reset_queue_legacy(struct amdgpu_ring *ring,
 				   unsigned int vmid,
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 0ca774959401..4a1e941cfe2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -1588,7 +1588,7 @@ static int sdma_v4_4_2_reset_queue(struct amdgpu_ring *ring,
 	int r;
 
 	amdgpu_amdkfd_suspend(adev, true);
-	r = amdgpu_sdma_reset_engine(adev, id, false);
+	r = amdgpu_sdma_reset_engine(adev, id);
 	amdgpu_amdkfd_resume(adev, true);
 	return r;
 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 3ec6a73af22e..f02fdb1b7899 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -2661,7 +2661,7 @@ static int reset_hung_queues_sdma(struct device_queue_manager *dqm)
 				continue;
 
 			/* Reset engine and check. */
-			if (amdgpu_sdma_reset_engine(dqm->dev->adev, i, false) ||
+			if (amdgpu_sdma_reset_engine(dqm->dev->adev, i) ||
 			    dqm->dev->kfd2kgd->hqd_sdma_get_doorbell(dqm->dev->adev, i, j) ||
 			    !set_sdma_queue_as_reset(dqm, doorbell_off)) {
 				r = -ENOTRECOVERABLE;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 9/9] drm/amdgpu/sdma: Use common SDMA legacy queue reset on SDMA v4.4.2
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
                   ` (7 preceding siblings ...)
  2026-09-08 18:10 ` [PATCH 8/9] drm/amdgpu/sdma: Always handle kernel queues in amdgpu_sdma_reset_engine() Timur Kristóf
@ 2026-09-08 18:10 ` Timur Kristóf
  2026-09-11 18:44 ` [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Alex Deucher
  9 siblings, 0 replies; 11+ messages in thread
From: Timur Kristóf @ 2026-09-08 18:10 UTC (permalink / raw)
  To: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling
  Cc: Timur Kristóf

Now, sdma_v4_4_2_reset_queue() does basically the same
as amdgpu_sdma_reset_queue_legacy() so let's use that.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index 4a1e941cfe2b..738341e889aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -1579,20 +1579,6 @@ static int sdma_v4_4_2_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
-static int sdma_v4_4_2_reset_queue(struct amdgpu_ring *ring,
-				   unsigned int vmid,
-				   struct amdgpu_fence *timedout_fence)
-{
-	struct amdgpu_device *adev = ring->adev;
-	u32 id = ring->me;
-	int r;
-
-	amdgpu_amdkfd_suspend(adev, true);
-	r = amdgpu_sdma_reset_engine(adev, id);
-	amdgpu_amdkfd_resume(adev, true);
-	return r;
-}
-
 static int sdma_v4_4_2_stop_queue(struct amdgpu_ring *ring)
 {
 	struct amdgpu_device *adev = ring->adev;
@@ -2036,7 +2022,7 @@ static const struct amdgpu_ring_funcs sdma_v4_4_2_ring_funcs = {
 	.emit_wreg = sdma_v4_4_2_ring_emit_wreg,
 	.emit_reg_wait = sdma_v4_4_2_ring_emit_reg_wait,
 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
-	.reset = sdma_v4_4_2_reset_queue,
+	.reset = amdgpu_sdma_reset_queue_legacy,
 };
 
 static const struct amdgpu_ring_funcs sdma_v4_4_2_page_ring_funcs = {
@@ -2068,7 +2054,7 @@ static const struct amdgpu_ring_funcs sdma_v4_4_2_page_ring_funcs = {
 	.emit_wreg = sdma_v4_4_2_ring_emit_wreg,
 	.emit_reg_wait = sdma_v4_4_2_ring_emit_reg_wait,
 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
-	.reset = sdma_v4_4_2_reset_queue,
+	.reset = amdgpu_sdma_reset_queue_legacy,
 };
 
 static void sdma_v4_4_2_set_ring_funcs(struct amdgpu_device *adev)
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4)
  2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
                   ` (8 preceding siblings ...)
  2026-09-08 18:10 ` [PATCH 9/9] drm/amdgpu/sdma: Use common SDMA legacy queue reset on SDMA v4.4.2 Timur Kristóf
@ 2026-09-11 18:44 ` Alex Deucher
  9 siblings, 0 replies; 11+ messages in thread
From: Alex Deucher @ 2026-09-11 18:44 UTC (permalink / raw)
  To: Timur Kristóf
  Cc: amd-gfx, Marek Olšák, Alex Deucher,
	Christian König, Tvrtko Ursulin, pierre-eric.pelloux-prayer,
	Natalie Vock, Lijo Lazar, Felix Kuehling

On Tue, Sep 8, 2026 at 2:35 PM Timur Kristóf <timur.kristof@gmail.com> wrote:
>
> Improve SDMA queue reset for SDMA v4.4.2, v5.0, v5.2
> and also moves some functionality from backend-specific
> code to common code in the amdgpu_sdma.c file.
>
> This prepares for implementing SDMA recovery
> on more generations, as the same logic can be shared
> with all SDMA HW generations that don't use the MES.
> The actual recovery implementation for various
> older SDMA versions will come in subsequent patch series
> after this one is accepted.
>

Applied the series.  Thanks!

Alex

> Changes in v2:
>
> * Added a fix for an issue in SDMA v4.4.2
> * Further simplified some code
>
> Changes in v3:
>
> * Fixed typo (wrong scheduler for page ring)
>
> Changes in v4:
>
> * Added helper function to clear ring contents and pointers
>
> Timur Kristóf (9):
>   drm/amdgpu/sdma: Remove unimplemented soft_reset() for SDMA and SI DMA
>   drm/amdgpu/sdma: Remove superfluous rlc_resume and rlc_stop functions
>   drm/amdgpu/sdma: Fix executing duplicate commands after recovery on
>     SDMA v4.4.2
>   drm/amdgpu/sdma: Remove unnecessary guilty tracking of SDMA queues
>   drm/amdgpu: Add amdgpu_ring_clear_ring_and_ptrs()
>   drm/amdgpu/sdma: Clear SDMA rings after reset before starting them
>   drm/amdgpu/sdma: Move SDMA v5.x queue reset to common code
>   drm/amdgpu/sdma: Always handle kernel queues in
>     amdgpu_sdma_reset_engine()
>   drm/amdgpu/sdma: Use common SDMA legacy queue reset on SDMA v4.4.2
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c      |   2 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h      |  21 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c      | 102 +++++++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h      |  11 +-
>  drivers/gpu/drm/amd/amdgpu/cik_sdma.c         |  32 ----
>  drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c        |  30 ----
>  drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c        |  38 +----
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c        |  40 +----
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c      | 158 ++----------------
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c        |  60 +------
>  drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c        |  52 +-----
>  drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c        |  27 ---
>  drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c        |  27 ---
>  drivers/gpu/drm/amd/amdgpu/si_dma.c           |   7 -
>  .../drm/amd/amdkfd/kfd_device_queue_manager.c |   2 +-
>  15 files changed, 121 insertions(+), 488 deletions(-)
>
> --
> 2.55.0
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-09-11 18:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-08 18:10 [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Timur Kristóf
2026-09-08 18:10 ` [PATCH 1/9] drm/amdgpu/sdma: Remove unimplemented soft_reset() for SDMA and SI DMA Timur Kristóf
2026-09-08 18:10 ` [PATCH 2/9] drm/amdgpu/sdma: Remove superfluous rlc_resume and rlc_stop functions Timur Kristóf
2026-09-08 18:10 ` [PATCH 3/9] drm/amdgpu/sdma: Fix executing duplicate commands after recovery on SDMA v4.4.2 Timur Kristóf
2026-09-08 18:10 ` [PATCH 4/9] drm/amdgpu/sdma: Remove unnecessary guilty tracking of SDMA queues Timur Kristóf
2026-09-08 18:10 ` [PATCH 5/9] drm/amdgpu: Add amdgpu_ring_clear_ring_and_ptrs() Timur Kristóf
2026-09-08 18:10 ` [PATCH 6/9] drm/amdgpu/sdma: Clear SDMA rings after reset before starting them Timur Kristóf
2026-09-08 18:10 ` [PATCH 7/9] drm/amdgpu/sdma: Move SDMA v5.x queue reset to common code Timur Kristóf
2026-09-08 18:10 ` [PATCH 8/9] drm/amdgpu/sdma: Always handle kernel queues in amdgpu_sdma_reset_engine() Timur Kristóf
2026-09-08 18:10 ` [PATCH 9/9] drm/amdgpu/sdma: Use common SDMA legacy queue reset on SDMA v4.4.2 Timur Kristóf
2026-09-11 18:44 ` [PATCH 0/9] drm/amdgpu/sdma: Improve existing SDMA queue resets (v4) Alex Deucher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox