* [PATCH V15 00/33] Reset improvements
@ 2025-07-11 22:39 Alex Deucher
2025-07-11 22:39 ` [PATCH 01/33] drm/amdgpu: clean up sdma reset functions Alex Deucher
` (32 more replies)
0 siblings, 33 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher
This set improves per queue reset support for a number of IPs.
When we reset the queue, the queue is lost so we need
to re-emit the unprocessed state from subsequent submissions.
This is handled in gfx/compute queues via switch buffer and
pipeline sync packets. However, you can still end up with
parallel execution across queues. For correctness in that
cause, enforce isolation needs to be enabled. That can
impact certain use cases however and in most cases, the
guilty job is correctly identified even without enforce isolation.
Tested on GC 10 and 11 chips with a game running and
then running hang tests. The game pauses when the
hang happens, then continues after the queue reset.
The same approach is extended to SDMA and VCN.
They don't need enforce isolation because those engines
are single threaded so they always operate serially.
Rework re-emit to signal the seq number of the bad job and
verify that to verify that the reset worked, then re-emit the
rest of the non-guilty state. This way we are not waiting on
the rest of the state to complete, and if the subsequent state
also contains a bad job, we'll end up in queue reset again rather
than adapter reset.
Tested with HangTestSuite and IGT reset/deadlock tests.
Patches apply to the amd-staging-drm-next or drm-next branches in my
git tree.
Git tree:
https://gitlab.freedesktop.org/agd5f/linux/-/commits/kq_resets?ref_type=heads
The IGT deadlock tests need the following fixes to properly handle -ETIME fences:
https://patchwork.freedesktop.org/series/150724/
v4: Drop explicit padding patches
Drop new timeout macro
Rework re-emit sequence
v5: Add a helper for reemit
Convert VCN, JPEG, SDMA to use new helpers
v6: Update SDMA 4.4.2 to use new helpers
Move ptr tracking to amdgpu_fence
Skip all jobs from the bad context on the ring
v7: Rework the backup logic
Move and clean up the guilty logic for engine resets
Integrate suggestions from Christian
Add JPEG 4.0.5 support
v8: Add non-guilty ring backup handling
Clean up new function signatures
Reorder some bug fixes to the start of the series
v9: Clean up fence_emit
SDMA 5.x fixes
Add new reset helpers
sched wqueue stop/start cleanup
Add support for VCNs without unified queues
v10: Drop enforce isolation default change
Add more documentation
Clean up ring backup logic
v11: SDMA6/7 fixes
v12: Ring backup and reemit fixes
SDMA cleanups
SDMA5.x reemit support
GFX10 KGQ reset fix
v13: drop SDMA cleaups, they caused regressions in some IGT tests
v14: Split out reset fixes as separate patches
Add additional error handling for VCN and JPEG
Update commit messages per feedback
v15: clean up and unify SDMA, GC, JPEG, VCN reset handling using
reset flags.
Alex Deucher (33):
drm/amdgpu: clean up sdma reset functions
drm/amdgpu/jpeg2: add additional ring reset error checking
drm/amdgpu/jpeg3: add additional ring reset error checking
drm/amdgpu/jpeg4: add additional ring reset error checking
drm/amdgpu/vcn: don't enable per queue resets on SR-IOV
drm/amdgpu: clean up jpeg reset functions
drm/amdgpu: clean up GC reset functions
drm/amdgpu: track ring state associated with a fence
drm/amdgpu/gfx9: re-emit unprocessed state on kcq reset
drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
drm/amdgpu/gfx10: re-emit unprocessed state on ring reset
drm/amdgpu/gfx11: re-emit unprocessed state on ring reset
drm/amdgpu/gfx12: re-emit unprocessed state on ring reset
drm/amdgpu/sdma5: re-emit unprocessed state on ring reset
drm/amdgpu/sdma5.2: re-emit unprocessed state on ring reset
drm/amdgpu/sdma6: re-emit unprocessed state on ring reset
drm/amdgpu/sdma7: re-emit unprocessed state on ring reset
drm/amdgpu/jpeg2: re-emit unprocessed state on ring reset
drm/amdgpu/jpeg2.5: re-emit unprocessed state on ring reset
drm/amdgpu/jpeg3: re-emit unprocessed state on ring reset
drm/amdgpu/jpeg4: re-emit unprocessed state on ring reset
drm/amdgpu/jpeg4.0.3: re-emit unprocessed state on ring reset
drm/amdgpu/jpeg4.0.5: add queue reset
drm/amdgpu/jpeg5: add queue reset
drm/amdgpu/jpeg5.0.1: re-emit unprocessed state on ring reset
drm/amdgpu/vcn4: re-emit unprocessed state on ring reset
drm/amdgpu/vcn4.0.3: re-emit unprocessed state on ring reset
drm/amdgpu/vcn4.0.5: re-emit unprocessed state on ring reset
drm/amdgpu/vcn5: re-emit unprocessed state on ring reset
drm/amdgpu/vcn: add a helper framework for engine resets
drm/amdgpu/vcn2: implement ring reset
drm/amdgpu/vcn2.5: implement ring reset
drm/amdgpu/vcn3: implement ring reset
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 90 +++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 15 +++-
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 67 +++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 18 +++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 79 ++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 6 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 +
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 49 ++++--------
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 54 ++++----------
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 53 ++++---------
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 16 ++--
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 23 +++---
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 19 +++--
drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 15 ++--
drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 19 +++--
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 20 ++---
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 11 +--
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c | 23 +++++-
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c | 23 +++++-
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c | 11 +--
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 20 ++++-
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 23 ++++--
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/vcn_v2_0.c | 26 +++++++
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 25 +++++++
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 27 +++++++
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 13 +---
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 10 +--
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 13 +---
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 13 +---
32 files changed, 575 insertions(+), 268 deletions(-)
--
2.50.0
^ permalink raw reply [flat|nested] 48+ messages in thread
* [PATCH 01/33] drm/amdgpu: clean up sdma reset functions
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-14 13:27 ` Christian König
2025-07-14 14:00 ` Lazar, Lijo
2025-07-11 22:39 ` [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking Alex Deucher
` (31 subsequent siblings)
32 siblings, 2 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher
Make them consistent and drop unneeded extra variables.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 14 +++++++++++---
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 17 +++++++++++++----
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 20 ++++++++------------
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 20 ++++++++------------
4 files changed, 40 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index 5a1098bdd8256..999705e7b2641 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -1428,7 +1428,8 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(5, 0, 0):
case IP_VERSION(5, 0, 2):
case IP_VERSION(5, 0, 5):
- if (adev->sdma.instance[0].fw_version >= 35)
+ if ((adev->sdma.instance[0].fw_version >= 35) &&
+ !amdgpu_sriov_vf(adev))
adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
break;
default:
@@ -1544,11 +1545,18 @@ static int sdma_v5_0_reset_queue(struct amdgpu_ring *ring,
struct amdgpu_fence *timedout_fence)
{
struct amdgpu_device *adev = ring->adev;
- u32 inst_id = ring->me;
int r;
+ if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
+ if (ring->me >= adev->sdma.num_instances) {
+ dev_err(adev->dev, "sdma instance not found\n");
+ return -EINVAL;
+ }
+
amdgpu_amdkfd_suspend(adev, true);
- r = amdgpu_sdma_reset_engine(adev, inst_id, false);
+ r = amdgpu_sdma_reset_engine(adev, ring->me, false);
amdgpu_amdkfd_resume(adev, true);
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 6843c2c3d71f5..e542195972dd4 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -1347,11 +1347,13 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(5, 2, 2):
case IP_VERSION(5, 2, 3):
case IP_VERSION(5, 2, 4):
- if (adev->sdma.instance[0].fw_version >= 76)
+ if ((adev->sdma.instance[0].fw_version >= 76) &&
+ !amdgpu_sriov_vf(adev))
adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
break;
case IP_VERSION(5, 2, 5):
- if (adev->sdma.instance[0].fw_version >= 34)
+ if ((adev->sdma.instance[0].fw_version >= 34) &&
+ !amdgpu_sriov_vf(adev))
adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
break;
default:
@@ -1457,11 +1459,18 @@ static int sdma_v5_2_reset_queue(struct amdgpu_ring *ring,
struct amdgpu_fence *timedout_fence)
{
struct amdgpu_device *adev = ring->adev;
- u32 inst_id = ring->me;
int r;
+ if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
+ if (ring->me >= adev->sdma.num_instances) {
+ dev_err(adev->dev, "sdma instance not found\n");
+ return -EINVAL;
+ }
+
amdgpu_amdkfd_suspend(adev, true);
- r = amdgpu_sdma_reset_engine(adev, inst_id, false);
+ r = amdgpu_sdma_reset_engine(adev, ring->me, false);
amdgpu_amdkfd_resume(adev, true);
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 d2effa5318176..c08e9a6cf6827 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
@@ -1355,7 +1355,8 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
- if (adev->sdma.instance[0].fw_version >= 21)
+ if ((adev->sdma.instance[0].fw_version >= 21) &&
+ !amdgpu_sriov_vf(adev))
adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
break;
default:
@@ -1575,18 +1576,13 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
struct amdgpu_fence *timedout_fence)
{
struct amdgpu_device *adev = ring->adev;
- int i, r;
-
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ int r;
- for (i = 0; i < adev->sdma.num_instances; i++) {
- if (ring == &adev->sdma.instance[i].ring)
- break;
- }
+ if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
- if (i == adev->sdma.num_instances) {
- DRM_ERROR("sdma instance not found\n");
+ if (ring->me >= adev->sdma.num_instances) {
+ dev_err(adev->dev, "sdma instance not found\n");
return -EINVAL;
}
@@ -1596,7 +1592,7 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
if (r)
return r;
- r = sdma_v6_0_gfx_resume_instance(adev, i, true);
+ r = sdma_v6_0_gfx_resume_instance(adev, ring->me, true);
if (r)
return r;
amdgpu_fence_driver_force_completion(ring);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
index 99a080bad2a3d..ba1f3e3b6eb61 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
@@ -807,18 +807,13 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
struct amdgpu_fence *timedout_fence)
{
struct amdgpu_device *adev = ring->adev;
- int i, r;
-
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ int r;
- for (i = 0; i < adev->sdma.num_instances; i++) {
- if (ring == &adev->sdma.instance[i].ring)
- break;
- }
+ if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
- if (i == adev->sdma.num_instances) {
- DRM_ERROR("sdma instance not found\n");
+ if (ring->me >= adev->sdma.num_instances) {
+ dev_err(adev->dev, "sdma instance not found\n");
return -EINVAL;
}
@@ -828,7 +823,7 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
if (r)
return r;
- r = sdma_v7_0_gfx_resume_instance(adev, i, true);
+ r = sdma_v7_0_gfx_resume_instance(adev, ring->me, true);
if (r)
return r;
amdgpu_fence_driver_force_completion(ring);
@@ -1346,7 +1341,8 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
adev->sdma.supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_sdma_sysfs_reset_mask_init(adev);
if (r)
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
2025-07-11 22:39 ` [PATCH 01/33] drm/amdgpu: clean up sdma reset functions Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-14 2:58 ` Sundararaju, Sathishkumar
2025-07-14 13:29 ` Christian König
2025-07-11 22:39 ` [PATCH 03/33] drm/amdgpu/jpeg3: " Alex Deucher
` (30 subsequent siblings)
32 siblings, 2 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Start and stop can fail, so add checks.
Fixes: 500c04d2a708 ("drm/amdgpu: Add ring reset callback for JPEG2_0_0")
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: Sathishkumar S <sathishkumar.sundararaju@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
index 781a5a8a83614..5ba1c5ad9a5e1 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
@@ -771,8 +771,12 @@ static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring,
int r;
drm_sched_wqueue_stop(&ring->sched);
- jpeg_v2_0_stop(ring->adev);
- jpeg_v2_0_start(ring->adev);
+ r = jpeg_v2_0_stop(ring->adev);
+ if (r)
+ return r;
+ r = jpeg_v2_0_start(ring->adev);
+ if (r)
+ return r;
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 03/33] drm/amdgpu/jpeg3: add additional ring reset error checking
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
2025-07-11 22:39 ` [PATCH 01/33] drm/amdgpu: clean up sdma reset functions Alex Deucher
2025-07-11 22:39 ` [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-14 3:00 ` Sundararaju, Sathishkumar
2025-07-11 22:39 ` [PATCH 04/33] drm/amdgpu/jpeg4: " Alex Deucher
` (29 subsequent siblings)
32 siblings, 1 reply; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Start and stop can fail, so add checks.
Fixes: 03399d0bff25 ("drm/amdgpu: Add ring reset callback for JPEG3_0_0")
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: Sathishkumar S <sathishkumar.sundararaju@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
index a24bd833d6442..5428930eafa3e 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
@@ -562,8 +562,12 @@ static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring,
int r;
drm_sched_wqueue_stop(&ring->sched);
- jpeg_v3_0_stop(ring->adev);
- jpeg_v3_0_start(ring->adev);
+ r = jpeg_v3_0_stop(ring->adev);
+ if (r)
+ return r;
+ r = jpeg_v3_0_start(ring->adev);
+ if (r)
+ return r;
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 04/33] drm/amdgpu/jpeg4: add additional ring reset error checking
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (2 preceding siblings ...)
2025-07-11 22:39 ` [PATCH 03/33] drm/amdgpu/jpeg3: " Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-14 3:02 ` Sundararaju, Sathishkumar
2025-07-11 22:39 ` [PATCH 05/33] drm/amdgpu/vcn: don't enable per queue resets on SR-IOV Alex Deucher
` (28 subsequent siblings)
32 siblings, 1 reply; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Start and stop can fail, so add checks.
Fixes: 74894ffc7d0c ("drm/amdgpu: Add ring reset callback for JPEG4_0_0")
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: Sathishkumar S <sathishkumar.sundararaju@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
index 1d4edd77837d0..78fe1924f3cb7 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
@@ -730,8 +730,12 @@ static int jpeg_v4_0_ring_reset(struct amdgpu_ring *ring,
return -EINVAL;
drm_sched_wqueue_stop(&ring->sched);
- jpeg_v4_0_stop(ring->adev);
- jpeg_v4_0_start(ring->adev);
+ r = jpeg_v4_0_stop(ring->adev);
+ if (r)
+ return r;
+ r = jpeg_v4_0_start(ring->adev);
+ if (r)
+ return r;
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 05/33] drm/amdgpu/vcn: don't enable per queue resets on SR-IOV
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (3 preceding siblings ...)
2025-07-11 22:39 ` [PATCH 04/33] drm/amdgpu/jpeg4: " Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-14 13:30 ` Christian König
2025-07-11 22:39 ` [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions Alex Deucher
` (27 subsequent siblings)
32 siblings, 1 reply; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher
Power control is only available in bare metal. SR-IOV
will need a different method.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 3 ++-
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 3 ++-
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
index 5bbce8544fef0..e6613246d8b8d 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
@@ -241,7 +241,8 @@ static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
adev->vcn.supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
- adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
if (amdgpu_sriov_vf(adev)) {
r = amdgpu_virt_alloc_mm_table(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
index 6000c528ad6ae..732e9a9293d26 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
@@ -220,7 +220,8 @@ static int vcn_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block)
}
adev->vcn.supported_reset = amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
- adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_vcn_sysfs_reset_mask_init(adev);
if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
index 3d3b4254bd729..a137bef918ed5 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
@@ -198,7 +198,8 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block)
adev->vcn.supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
- adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
vcn_v5_0_0_alloc_ip_dump(adev);
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (4 preceding siblings ...)
2025-07-11 22:39 ` [PATCH 05/33] drm/amdgpu/vcn: don't enable per queue resets on SR-IOV Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-14 3:24 ` Sundararaju, Sathishkumar
2025-07-14 13:36 ` Christian König
2025-07-11 22:39 ` [PATCH 07/33] drm/amdgpu: clean up GC " Alex Deucher
` (26 subsequent siblings)
32 siblings, 2 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher
Make them consistent and use the reset flags.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 6 +++++-
drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 6 +++++-
drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 6 +++++-
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 7 ++++---
4 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
index 5ba1c5ad9a5e1..0b56cb67e8f1d 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
@@ -118,7 +118,8 @@ static int jpeg_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
- adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
return r;
@@ -770,6 +771,9 @@ static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring,
{
int r;
+ if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
drm_sched_wqueue_stop(&ring->sched);
r = jpeg_v2_0_stop(ring->adev);
if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
index 5be9cdcae32c1..3d0e61f9f2854 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
@@ -167,7 +167,8 @@ static int jpeg_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
- adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
return r;
@@ -649,6 +650,9 @@ static int jpeg_v2_5_ring_reset(struct amdgpu_ring *ring,
{
int r;
+ if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
drm_sched_wqueue_stop(&ring->sched);
jpeg_v2_5_stop_inst(ring->adev, ring->me);
jpeg_v2_5_start_inst(ring->adev, ring->me);
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
index 5428930eafa3e..5d54c882d889c 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
@@ -132,7 +132,8 @@ static int jpeg_v3_0_sw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
- adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
return r;
@@ -561,6 +562,9 @@ static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring,
{
int r;
+ if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
drm_sched_wqueue_stop(&ring->sched);
r = jpeg_v3_0_stop(ring->adev);
if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
index 78fe1924f3cb7..5485e983a089f 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
@@ -143,7 +143,8 @@ static int jpeg_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
- adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
+ if (!amdgpu_sriov_vf(adev))
+ adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
return r;
@@ -726,8 +727,8 @@ static int jpeg_v4_0_ring_reset(struct amdgpu_ring *ring,
{
int r;
- if (amdgpu_sriov_vf(ring->adev))
- return -EINVAL;
+ if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
drm_sched_wqueue_stop(&ring->sched);
r = jpeg_v4_0_stop(ring->adev);
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 07/33] drm/amdgpu: clean up GC reset functions
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (5 preceding siblings ...)
2025-07-11 22:39 ` [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-11 22:39 ` [PATCH 08/33] drm/amdgpu: track ring state associated with a fence Alex Deucher
` (25 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher
Make them consistent and use the reset flags.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 14 +++++++++-----
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 19 ++++++++++++-------
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 18 +++++++++++-------
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 6 ++++--
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 14 +++++++++-----
5 files changed, 45 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index d739bfb20383e..506454ed27bde 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -4952,11 +4952,15 @@ static int gfx_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
}
}
}
- /* TODO: Add queue reset mask when FW fully supports it */
+
adev->gfx.gfx_supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
adev->gfx.compute_supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
+ if (!amdgpu_sriov_vf(adev)) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ }
r = amdgpu_gfx_kiq_init(adev, GFX10_MEC_HPD_SIZE, 0);
if (r) {
@@ -9534,8 +9538,8 @@ static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring,
u64 addr;
int r;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.gfx_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
@@ -9607,8 +9611,8 @@ static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
unsigned long flags;
int i, r;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 37dcec2d07841..372dceceff359 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -1806,12 +1806,17 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
if ((adev->gfx.me_fw_version >= 2280) &&
- (adev->gfx.mec_fw_version >= 2410)) {
- adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
- adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ (adev->gfx.mec_fw_version >= 2410) &&
+ !amdgpu_sriov_vf(adev)) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
}
break;
default:
+ if (!amdgpu_sriov_vf(adev)) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ }
break;
}
@@ -6818,8 +6823,8 @@ static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring,
struct amdgpu_device *adev = ring->adev;
int r;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.gfx_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
drm_sched_wqueue_stop(&ring->sched);
@@ -6989,8 +6994,8 @@ static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring,
struct amdgpu_device *adev = ring->adev;
int r = 0;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
drm_sched_wqueue_stop(&ring->sched);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index e4fc42470cf3e..7220ed2fa2a33 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -1542,10 +1542,14 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
if ((adev->gfx.me_fw_version >= 2660) &&
- (adev->gfx.mec_fw_version >= 2920)) {
- adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
- adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ (adev->gfx.mec_fw_version >= 2920) &&
+ !amdgpu_sriov_vf(adev)) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
}
+ break;
+ default:
+ break;
}
if (!adev->enable_mes_kiq) {
@@ -5314,8 +5318,8 @@ static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring,
struct amdgpu_device *adev = ring->adev;
int r;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.gfx_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
drm_sched_wqueue_stop(&ring->sched);
@@ -5437,8 +5441,8 @@ static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring,
struct amdgpu_device *adev = ring->adev;
int r;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
drm_sched_wqueue_stop(&ring->sched);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 4c61157405b07..ac058697054f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -2410,6 +2410,8 @@ static int gfx_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
adev->gfx.compute_supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
+ if (!amdgpu_sriov_vf(adev))
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_gfx_kiq_init(adev, GFX9_MEC_HPD_SIZE, 0);
if (r) {
@@ -7181,8 +7183,8 @@ static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
unsigned long flags;
int i, r;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
index 5f92975cc3058..e2ff4b373a319 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -1148,13 +1148,15 @@ static int gfx_v9_4_3_sw_init(struct amdgpu_ip_block *ip_block)
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
case IP_VERSION(9, 4, 3):
case IP_VERSION(9, 4, 4):
- if (adev->gfx.mec_fw_version >= 155) {
+ if ((adev->gfx.mec_fw_version >= 155) &&
+ !amdgpu_sriov_vf(adev)) {
adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE;
}
break;
case IP_VERSION(9, 5, 0):
- if (adev->gfx.mec_fw_version >= 21) {
+ if ((adev->gfx.mec_fw_version >= 21) &&
+ !amdgpu_sriov_vf(adev)){
adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE;
}
@@ -3561,8 +3563,8 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
unsigned long flags;
int r;
- if (amdgpu_sriov_vf(adev))
- return -EINVAL;
+ if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
@@ -3594,7 +3596,9 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
dev_err(adev->dev, "fail to wait on hqd deactive and will try pipe reset\n");
pipe_reset:
- if(r) {
+ if (r) {
+ if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_PIPE))
+ return -EOPNOTSUPP;
r = gfx_v9_4_3_reset_hw_pipe(ring);
dev_info(adev->dev, "ring: %s pipe reset :%s\n", ring->name,
r ? "failed" : "successfully");
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 08/33] drm/amdgpu: track ring state associated with a fence
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (6 preceding siblings ...)
2025-07-11 22:39 ` [PATCH 07/33] drm/amdgpu: clean up GC " Alex Deucher
@ 2025-07-11 22:39 ` Alex Deucher
2025-07-14 14:02 ` Christian König
2025-07-11 22:40 ` [PATCH 09/33] drm/amdgpu/gfx9: re-emit unprocessed state on kcq reset Alex Deucher
` (24 subsequent siblings)
32 siblings, 1 reply; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:39 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher
We need to know the wptr and sequence number associated
with a fence so that we can re-emit the unprocessed state
after a ring reset. Pre-allocate storage space for
the ring buffer contents and add helpers to save off
and re-emit the unprocessed state so that it can be
re-emitted after the queue is reset.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 90 +++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 15 +++-
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 67 +++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 18 +++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 +
6 files changed, 195 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2d6b2b486baf7..3f2080aecd5a3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -120,6 +120,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
am_fence = kzalloc(sizeof(*am_fence), GFP_KERNEL);
if (!am_fence)
return -ENOMEM;
+ am_fence->context = 0;
} else {
am_fence = af;
}
@@ -127,6 +128,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
am_fence->ring = ring;
seq = ++ring->fence_drv.sync_seq;
+ am_fence->seq = seq;
if (af) {
dma_fence_init(fence, &amdgpu_job_fence_ops,
&ring->fence_drv.lock,
@@ -141,6 +143,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
seq, flags | AMDGPU_FENCE_FLAG_INT);
+ amdgpu_fence_save_wptr(fence);
pm_runtime_get_noresume(adev_to_drm(adev)->dev);
ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
if (unlikely(rcu_dereference_protected(*ptr, 1))) {
@@ -253,6 +256,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
do {
struct dma_fence *fence, **ptr;
+ struct amdgpu_fence *am_fence;
++last_seq;
last_seq &= drv->num_fences_mask;
@@ -265,6 +269,12 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
if (!fence)
continue;
+ /* Save the wptr in the fence driver so we know what the last processed
+ * wptr was. This is required for re-emitting the ring state for
+ * queues that are reset but are not guilty and thus have no guilty fence.
+ */
+ am_fence = container_of(fence, struct amdgpu_fence, base);
+ drv->signalled_wptr = am_fence->wptr;
dma_fence_signal(fence);
dma_fence_put(fence);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
@@ -727,6 +737,86 @@ void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring)
amdgpu_fence_process(ring);
}
+
+/**
+ * Kernel queue reset handling
+ *
+ * The driver can reset individual queues for most engines, but those queues
+ * may contain work from multiple contexts. Resetting the queue will reset
+ * lose all of that state. In order to minimize the collateral damage, the
+ * driver will save the ring contents which are not associated with the guilty
+ * context prior to resetting the queue. After resetting the queue the queue
+ * contents from the other contexts is re-emitted to the rings so that it can
+ * be processed by the engine. To handle this, we save the queue's write
+ * pointer (wptr) in the fences associated with each context. If we get a
+ * queue timeout, we can then use the wptrs from the fences to determine
+ * which data needs to be saved out of the queue's ring buffer.
+ */
+
+/**
+ * amdgpu_fence_driver_guilty_force_completion - force signal of specified sequence
+ *
+ * @fence: fence of the ring to signal
+ *
+ */
+void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence)
+{
+ dma_fence_set_error(&fence->base, -ETIME);
+ amdgpu_fence_write(fence->ring, fence->seq);
+ amdgpu_fence_process(fence->ring);
+}
+
+void amdgpu_fence_save_wptr(struct dma_fence *fence)
+{
+ struct amdgpu_fence *am_fence = container_of(fence, struct amdgpu_fence, base);
+
+ am_fence->wptr = am_fence->ring->wptr;
+}
+
+static void amdgpu_ring_backup_unprocessed_command(struct amdgpu_ring *ring,
+ u64 start_wptr, u32 end_wptr)
+{
+ unsigned int first_idx = start_wptr & ring->buf_mask;
+ unsigned int last_idx = end_wptr & ring->buf_mask;
+ unsigned int i;
+
+ /* Backup the contents of the ring buffer. */
+ for (i = first_idx; i != last_idx; ++i, i &= ring->buf_mask)
+ ring->ring_backup[ring->ring_backup_entries_to_copy++] = ring->ring[i];
+}
+
+void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
+ struct amdgpu_fence *guilty_fence)
+{
+ struct dma_fence *unprocessed;
+ struct dma_fence __rcu **ptr;
+ struct amdgpu_fence *fence;
+ u64 wptr, i, seqno;
+
+ seqno = amdgpu_fence_read(ring);
+ wptr = ring->fence_drv.signalled_wptr;
+ ring->ring_backup_entries_to_copy = 0;
+
+ for (i = seqno + 1; i <= ring->fence_drv.sync_seq; ++i) {
+ ptr = &ring->fence_drv.fences[i & ring->fence_drv.num_fences_mask];
+ rcu_read_lock();
+ unprocessed = rcu_dereference(*ptr);
+
+ if (unprocessed && !dma_fence_is_signaled(unprocessed)) {
+ fence = container_of(unprocessed, struct amdgpu_fence, base);
+
+ /* save everything if the ring is not guilty, otherwise
+ * just save the content from other contexts.
+ */
+ if (!guilty_fence || (fence->context != guilty_fence->context))
+ amdgpu_ring_backup_unprocessed_command(ring, wptr,
+ fence->wptr);
+ wptr = fence->wptr;
+ }
+ rcu_read_unlock();
+ }
+}
+
/*
* Common fence implementation
*/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index 206b70acb29a0..7d9bcb72e8dd3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -139,7 +139,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
int vmid = AMDGPU_JOB_GET_VMID(job);
bool need_pipe_sync = false;
unsigned int cond_exec;
-
unsigned int i;
int r = 0;
@@ -156,6 +155,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
gds_va = job->gds_va;
init_shadow = job->init_shadow;
af = &job->hw_fence;
+ /* Save the context of the job for reset handling.
+ * The driver needs this so it can skip the ring
+ * contents for guilty contexts.
+ */
+ af->context = job->base.s_fence ? job->base.s_fence->finished.context : 0;
} else {
vm = NULL;
fence_ctx = 0;
@@ -307,8 +311,17 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
ring->funcs->emit_wave_limit(ring, false);
+ /* Save the wptr associated with this fence.
+ * This must be last for resets to work properly
+ * as we need to save the wptr associated with this
+ * fence so we know what rings contents to backup
+ * after we reset the queue.
+ */
+ amdgpu_fence_save_wptr(*f);
+
amdgpu_ring_ib_end(ring);
amdgpu_ring_commit(ring);
+
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index f0b7080dccb8d..45febdc2f3493 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -89,8 +89,8 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
{
struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched);
struct amdgpu_job *job = to_amdgpu_job(s_job);
- struct amdgpu_task_info *ti;
struct amdgpu_device *adev = ring->adev;
+ struct amdgpu_task_info *ti;
int idx, r;
if (!drm_dev_enter(adev_to_drm(adev), &idx)) {
@@ -135,7 +135,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
} else if (amdgpu_gpu_recovery && ring->funcs->reset) {
dev_err(adev->dev, "Starting %s ring reset\n",
s_job->sched->name);
- r = amdgpu_ring_reset(ring, job->vmid, NULL);
+ r = amdgpu_ring_reset(ring, job->vmid, &job->hw_fence);
if (!r) {
atomic_inc(&ring->adev->gpu_reset_counter);
dev_err(adev->dev, "Ring %s reset succeeded\n",
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 426834806fbf2..09d7681b7a754 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -99,6 +99,29 @@ int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned int ndw)
return 0;
}
+/**
+ * amdgpu_ring_alloc_reemit - allocate space on the ring buffer for reemit
+ *
+ * @ring: amdgpu_ring structure holding ring information
+ * @ndw: number of dwords to allocate in the ring buffer
+ *
+ * Allocate @ndw dwords in the ring buffer (all asics).
+ * doesn't check the max_dw limit as we may be reemitting
+ * several submissions.
+ */
+static void amdgpu_ring_alloc_reemit(struct amdgpu_ring *ring, unsigned int ndw)
+{
+ /* Align requested size with padding so unlock_commit can
+ * pad safely */
+ ndw = (ndw + ring->funcs->align_mask) & ~ring->funcs->align_mask;
+
+ ring->count_dw = ndw;
+ ring->wptr_old = ring->wptr;
+
+ if (ring->funcs->begin_use)
+ ring->funcs->begin_use(ring);
+}
+
/** amdgpu_ring_insert_nop - insert NOP packets
*
* @ring: amdgpu_ring structure holding ring information
@@ -333,6 +356,12 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
/* Initialize cached_rptr to 0 */
ring->cached_rptr = 0;
+ if (!ring->ring_backup) {
+ ring->ring_backup = kvzalloc(ring->ring_size, GFP_KERNEL);
+ if (!ring->ring_backup)
+ return -ENOMEM;
+ }
+
/* Allocate ring buffer */
if (ring->ring_obj == NULL) {
r = amdgpu_bo_create_kernel(adev, ring->ring_size + ring->funcs->extra_dw, PAGE_SIZE,
@@ -342,6 +371,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
(void **)&ring->ring);
if (r) {
dev_err(adev->dev, "(%d) ring create failed\n", r);
+ kvfree(ring->ring_backup);
return r;
}
amdgpu_ring_clear_ring(ring);
@@ -385,6 +415,8 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
amdgpu_bo_free_kernel(&ring->ring_obj,
&ring->gpu_addr,
(void **)&ring->ring);
+ kvfree(ring->ring_backup);
+ ring->ring_backup = NULL;
dma_fence_put(ring->vmid_wait);
ring->vmid_wait = NULL;
@@ -753,3 +785,38 @@ bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring)
return true;
}
+
+void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring,
+ struct amdgpu_fence *guilty_fence)
+{
+ /* Stop the scheduler to prevent anybody else from touching the ring buffer. */
+ drm_sched_wqueue_stop(&ring->sched);
+ /* back up the non-guilty commands */
+ amdgpu_ring_backup_unprocessed_commands(ring, guilty_fence);
+}
+
+int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,
+ struct amdgpu_fence *guilty_fence)
+{
+ unsigned int i;
+ int r;
+
+ /* verify that the ring is functional */
+ r = amdgpu_ring_test_ring(ring);
+ if (r)
+ return r;
+
+ /* signal the fence of the bad job */
+ if (guilty_fence)
+ amdgpu_fence_driver_guilty_force_completion(guilty_fence);
+ /* Re-emit the non-guilty commands */
+ if (ring->ring_backup_entries_to_copy) {
+ amdgpu_ring_alloc_reemit(ring, ring->ring_backup_entries_to_copy);
+ for (i = 0; i < ring->ring_backup_entries_to_copy; i++)
+ amdgpu_ring_write(ring, ring->ring_backup[i]);
+ amdgpu_ring_commit(ring);
+ }
+ /* Start the scheduler again */
+ drm_sched_wqueue_start(&ring->sched);
+ return 0;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 784ba2ec354c7..309e7bb6001bd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -118,6 +118,7 @@ struct amdgpu_fence_driver {
/* sync_seq is protected by ring emission lock */
uint32_t sync_seq;
atomic_t last_seq;
+ u64 signalled_wptr;
bool initialized;
struct amdgpu_irq_src *irq_src;
unsigned irq_type;
@@ -141,6 +142,12 @@ struct amdgpu_fence {
/* RB, DMA, etc. */
struct amdgpu_ring *ring;
ktime_t start_timestamp;
+
+ /* wptr for the fence for resets */
+ u64 wptr;
+ /* fence context for resets */
+ u64 context;
+ uint32_t seq;
};
extern const struct drm_sched_backend_ops amdgpu_sched_ops;
@@ -148,6 +155,8 @@ extern const struct drm_sched_backend_ops amdgpu_sched_ops;
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
+void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence);
+void amdgpu_fence_save_wptr(struct dma_fence *fence);
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
@@ -284,6 +293,9 @@ struct amdgpu_ring {
struct amdgpu_bo *ring_obj;
uint32_t *ring;
+ /* backups for resets */
+ uint32_t *ring_backup;
+ unsigned int ring_backup_entries_to_copy;
unsigned rptr_offs;
u64 rptr_gpu_addr;
volatile u32 *rptr_cpu_addr;
@@ -550,4 +562,10 @@ int amdgpu_ib_pool_init(struct amdgpu_device *adev);
void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring);
+void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
+ struct amdgpu_fence *guilty_fence);
+void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring,
+ struct amdgpu_fence *guilty_fence);
+int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,
+ struct amdgpu_fence *guilty_fence);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index f042372d9f2e6..ea9b0f050f799 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -765,6 +765,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
bool cleaner_shader_needed = false;
bool pasid_mapping_needed = false;
struct dma_fence *fence = NULL;
+ struct amdgpu_fence *af;
unsigned int patch;
int r;
@@ -830,6 +831,9 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
r = amdgpu_fence_emit(ring, &fence, NULL, 0);
if (r)
return r;
+ /* this is part of the job's context */
+ af = container_of(fence, struct amdgpu_fence, base);
+ af->context = job->base.s_fence ? job->base.s_fence->finished.context : 0;
}
if (vm_flush_needed) {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 09/33] drm/amdgpu/gfx9: re-emit unprocessed state on kcq reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (7 preceding siblings ...)
2025-07-11 22:39 ` [PATCH 08/33] drm/amdgpu: track ring state associated with a fence Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 10/33] drm/amdgpu/gfx9.4.3: " Alex Deucher
` (23 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index ac058697054f9..9c0cdf4dde714 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -7189,7 +7189,7 @@ static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
spin_lock_irqsave(&kiq->ring_lock, flags);
@@ -7246,13 +7246,7 @@ static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
DRM_ERROR("fail to remap queue\n");
return r;
}
-
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static void gfx_v9_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 10/33] drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (8 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 09/33] drm/amdgpu/gfx9: re-emit unprocessed state on kcq reset Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-15 16:12 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 11/33] drm/amdgpu/gfx10: re-emit unprocessed state on ring reset Alex Deucher
` (22 subsequent siblings)
32 siblings, 1 reply; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher
Re-emit the unprocessed state after resetting the queue.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
index e2ff4b373a319..d80f1fb261d1e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -3569,7 +3569,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
spin_lock_irqsave(&kiq->ring_lock, flags);
@@ -3626,12 +3626,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
return r;
}
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
enum amdgpu_gfx_cp_ras_mem_id {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 11/33] drm/amdgpu/gfx10: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (9 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 10/33] drm/amdgpu/gfx9.4.3: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 12/33] drm/amdgpu/gfx11: " Alex Deucher
` (21 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Drop the soft_recovery callbacks as the queue reset replaces
it.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 35 +++-----------------------
1 file changed, 4 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 506454ed27bde..744f51a6f522d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -9050,21 +9050,6 @@ static void gfx_v10_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
ref, mask);
}
-static void gfx_v10_0_ring_soft_recovery(struct amdgpu_ring *ring,
- unsigned int vmid)
-{
- struct amdgpu_device *adev = ring->adev;
- uint32_t value = 0;
-
- value = REG_SET_FIELD(value, SQ_CMD, CMD, 0x03);
- value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
- value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
- value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
- amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
- WREG32_SOC15(GC, 0, mmSQ_CMD, value);
- amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
-}
-
static void
gfx_v10_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
uint32_t me, uint32_t pipe,
@@ -9544,7 +9529,7 @@ static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring,
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
spin_lock_irqsave(&kiq->ring_lock, flags);
@@ -9593,12 +9578,7 @@ static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring,
if (r)
return r;
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
@@ -9617,7 +9597,7 @@ static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
return -EINVAL;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
spin_lock_irqsave(&kiq->ring_lock, flags);
@@ -9671,12 +9651,7 @@ static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
if (r)
return r;
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static void gfx_v10_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
@@ -9911,7 +9886,6 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
.emit_wreg = gfx_v10_0_ring_emit_wreg,
.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
- .soft_recovery = gfx_v10_0_ring_soft_recovery,
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
.reset = gfx_v10_0_reset_kgq,
.emit_cleaner_shader = gfx_v10_0_ring_emit_cleaner_shader,
@@ -9952,7 +9926,6 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
.emit_wreg = gfx_v10_0_ring_emit_wreg,
.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
- .soft_recovery = gfx_v10_0_ring_soft_recovery,
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
.reset = gfx_v10_0_reset_kcq,
.emit_cleaner_shader = gfx_v10_0_ring_emit_cleaner_shader,
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 12/33] drm/amdgpu/gfx11: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (10 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 11/33] drm/amdgpu/gfx10: re-emit unprocessed state on ring reset Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 13/33] drm/amdgpu/gfx12: " Alex Deucher
` (20 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Drop the soft_recovery callbacks as the queue reset replaces
it.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 35 +++-----------------------
1 file changed, 4 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 372dceceff359..465fcd6503735 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -6288,21 +6288,6 @@ static void gfx_v11_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
ref, mask, 0x20);
}
-static void gfx_v11_0_ring_soft_recovery(struct amdgpu_ring *ring,
- unsigned vmid)
-{
- struct amdgpu_device *adev = ring->adev;
- uint32_t value = 0;
-
- value = REG_SET_FIELD(value, SQ_CMD, CMD, 0x03);
- value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
- value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
- value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
- amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
- WREG32_SOC15(GC, 0, regSQ_CMD, value);
- amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
-}
-
static void
gfx_v11_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
uint32_t me, uint32_t pipe,
@@ -6826,7 +6811,7 @@ static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring,
if (!(adev->gfx.gfx_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false);
if (r) {
@@ -6849,12 +6834,7 @@ static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring,
return r;
}
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static int gfx_v11_0_reset_compute_pipe(struct amdgpu_ring *ring)
@@ -6997,7 +6977,7 @@ static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring,
if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, true);
if (r) {
@@ -7018,12 +6998,7 @@ static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring,
return r;
}
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static void gfx_v11_ip_print(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
@@ -7259,7 +7234,6 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
.emit_wreg = gfx_v11_0_ring_emit_wreg,
.emit_reg_wait = gfx_v11_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v11_0_ring_emit_reg_write_reg_wait,
- .soft_recovery = gfx_v11_0_ring_soft_recovery,
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
.reset = gfx_v11_0_reset_kgq,
.emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader,
@@ -7301,7 +7275,6 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
.emit_wreg = gfx_v11_0_ring_emit_wreg,
.emit_reg_wait = gfx_v11_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v11_0_ring_emit_reg_write_reg_wait,
- .soft_recovery = gfx_v11_0_ring_soft_recovery,
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
.reset = gfx_v11_0_reset_kcq,
.emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader,
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 13/33] drm/amdgpu/gfx12: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (11 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 12/33] drm/amdgpu/gfx11: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 14/33] drm/amdgpu/sdma5: " Alex Deucher
` (19 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Drop the soft_recovery callbacks as the queue reset replaces
it.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 35 +++-----------------------
1 file changed, 4 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index 7220ed2fa2a33..5d32ae4b1a4c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -4694,21 +4694,6 @@ static void gfx_v12_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
ref, mask, 0x20);
}
-static void gfx_v12_0_ring_soft_recovery(struct amdgpu_ring *ring,
- unsigned vmid)
-{
- struct amdgpu_device *adev = ring->adev;
- uint32_t value = 0;
-
- value = REG_SET_FIELD(value, SQ_CMD, CMD, 0x03);
- value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
- value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
- value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
- amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
- WREG32_SOC15(GC, 0, regSQ_CMD, value);
- amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
-}
-
static void
gfx_v12_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
uint32_t me, uint32_t pipe,
@@ -5321,7 +5306,7 @@ static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring,
if (!(adev->gfx.gfx_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false);
if (r) {
@@ -5343,12 +5328,7 @@ static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring,
return r;
}
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static int gfx_v12_0_reset_compute_pipe(struct amdgpu_ring *ring)
@@ -5444,7 +5424,7 @@ static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring,
if (!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, true);
if (r) {
@@ -5465,12 +5445,7 @@ static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring,
return r;
}
- r = amdgpu_ring_test_ring(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static void gfx_v12_0_ring_begin_use(struct amdgpu_ring *ring)
@@ -5548,7 +5523,6 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_gfx = {
.emit_wreg = gfx_v12_0_ring_emit_wreg,
.emit_reg_wait = gfx_v12_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v12_0_ring_emit_reg_write_reg_wait,
- .soft_recovery = gfx_v12_0_ring_soft_recovery,
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
.reset = gfx_v12_0_reset_kgq,
.emit_cleaner_shader = gfx_v12_0_ring_emit_cleaner_shader,
@@ -5587,7 +5561,6 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
.emit_wreg = gfx_v12_0_ring_emit_wreg,
.emit_reg_wait = gfx_v12_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v12_0_ring_emit_reg_write_reg_wait,
- .soft_recovery = gfx_v12_0_ring_soft_recovery,
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
.reset = gfx_v12_0_reset_kcq,
.emit_cleaner_shader = gfx_v12_0_ring_emit_cleaner_shader,
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 14/33] drm/amdgpu/sdma5: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (12 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 13/33] drm/amdgpu/gfx12: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 15/33] drm/amdgpu/sdma5.2: " Alex Deucher
` (18 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index 999705e7b2641..d8c19601dd2e6 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -1555,11 +1555,15 @@ static int sdma_v5_0_reset_queue(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, false);
+ r = amdgpu_sdma_reset_engine(adev, ring->me, true);
amdgpu_amdkfd_resume(adev, true);
+ if (r)
+ return r;
- return r;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static int sdma_v5_0_stop_queue(struct amdgpu_ring *ring)
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 15/33] drm/amdgpu/sdma5.2: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (13 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 14/33] drm/amdgpu/sdma5: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 16/33] drm/amdgpu/sdma6: " Alex Deucher
` (17 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index e542195972dd4..5d56029e88a62 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -1469,11 +1469,15 @@ static int sdma_v5_2_reset_queue(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, false);
+ r = amdgpu_sdma_reset_engine(adev, ring->me, true);
amdgpu_amdkfd_resume(adev, true);
+ if (r)
+ return r;
- return r;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static int sdma_v5_2_stop_queue(struct amdgpu_ring *ring)
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 16/33] drm/amdgpu/sdma6: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (14 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 15/33] drm/amdgpu/sdma5.2: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 17/33] drm/amdgpu/sdma7: " Alex Deucher
` (16 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
index c08e9a6cf6827..5d31f318cb3c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
@@ -1586,7 +1586,7 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
return -EINVAL;
}
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(adev, ring, vmid, true);
if (r)
@@ -1595,9 +1595,8 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
r = sdma_v6_0_gfx_resume_instance(adev, ring->me, true);
if (r)
return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static int sdma_v6_0_set_trap_irq_state(struct amdgpu_device *adev,
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 17/33] drm/amdgpu/sdma7: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (15 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 16/33] drm/amdgpu/sdma6: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 18/33] drm/amdgpu/jpeg2: " Alex Deucher
` (15 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Jesse Zhang
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
index ba1f3e3b6eb61..13abc0c46eab0 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
@@ -817,7 +817,7 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
return -EINVAL;
}
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = amdgpu_mes_reset_legacy_queue(adev, ring, vmid, true);
if (r)
@@ -826,9 +826,8 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
r = sdma_v7_0_gfx_resume_instance(adev, ring->me, true);
if (r)
return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
/**
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 18/33] drm/amdgpu/jpeg2: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (16 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 17/33] drm/amdgpu/sdma7: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 19/33] drm/amdgpu/jpeg2.5: " Alex Deucher
` (14 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
index 0b56cb67e8f1d..554af4b9930e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
@@ -774,19 +774,14 @@ static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring,
if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = jpeg_v2_0_stop(ring->adev);
if (r)
return r;
r = jpeg_v2_0_start(ring->adev);
if (r)
return r;
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 19/33] drm/amdgpu/jpeg2.5: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (17 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 18/33] drm/amdgpu/jpeg2: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 20/33] drm/amdgpu/jpeg3: " Alex Deucher
` (13 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
index 3d0e61f9f2854..4e489a7e21157 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
@@ -648,20 +648,13 @@ static int jpeg_v2_5_ring_reset(struct amdgpu_ring *ring,
unsigned int vmid,
struct amdgpu_fence *timedout_fence)
{
- int r;
-
if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
jpeg_v2_5_stop_inst(ring->adev, ring->me);
jpeg_v2_5_start_inst(ring->adev, ring->me);
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 20/33] drm/amdgpu/jpeg3: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (18 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 19/33] drm/amdgpu/jpeg2.5: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 21/33] drm/amdgpu/jpeg4: " Alex Deucher
` (12 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
index 5d54c882d889c..d4bc4fca460c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
@@ -565,19 +565,14 @@ static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring,
if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = jpeg_v3_0_stop(ring->adev);
if (r)
return r;
r = jpeg_v3_0_start(ring->adev);
if (r)
return r;
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 21/33] drm/amdgpu/jpeg4: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (19 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 20/33] drm/amdgpu/jpeg3: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 22/33] drm/amdgpu/jpeg4.0.3: " Alex Deucher
` (11 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
index 5485e983a089f..ca3debe371c5a 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
@@ -730,19 +730,14 @@ static int jpeg_v4_0_ring_reset(struct amdgpu_ring *ring,
if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = jpeg_v4_0_stop(ring->adev);
if (r)
return r;
r = jpeg_v4_0_start(ring->adev);
if (r)
return r;
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 22/33] drm/amdgpu/jpeg4.0.3: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (20 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 21/33] drm/amdgpu/jpeg4: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 23/33] drm/amdgpu/jpeg4.0.5: add queue reset Alex Deucher
` (10 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
index 78441f8fce972..c3f73a2a911b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
@@ -1147,20 +1147,13 @@ static int jpeg_v4_0_3_ring_reset(struct amdgpu_ring *ring,
unsigned int vmid,
struct amdgpu_fence *timedout_fence)
{
- int r;
-
if (amdgpu_sriov_vf(ring->adev))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
jpeg_v4_0_3_core_stall_reset(ring);
jpeg_v4_0_3_start_jrbc(ring);
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amd_ip_funcs jpeg_v4_0_3_ip_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 23/33] drm/amdgpu/jpeg4.0.5: add queue reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (21 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 22/33] drm/amdgpu/jpeg4.0.3: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 24/33] drm/amdgpu/jpeg5: " Alex Deucher
` (9 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Add queue reset support for jpeg 4.0.5.
Use the new helpers to re-emit the unprocessed state
after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
index 974030a5c03c9..5a69a44e0f855 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
@@ -174,9 +174,10 @@ static int jpeg_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
- /* TODO: Add queue reset mask when FW fully supports it */
adev->jpeg.supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
+ if (!amdgpu_sriov_vf(adev))
+ adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
if (r)
return r;
@@ -767,6 +768,25 @@ static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev,
return 0;
}
+static int jpeg_v4_0_5_ring_reset(struct amdgpu_ring *ring,
+ unsigned int vmid,
+ struct amdgpu_fence *timedout_fence)
+{
+ int r;
+
+ if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
+ r = jpeg_v4_0_5_stop(ring->adev);
+ if (r)
+ return r;
+ r = jpeg_v4_0_5_start(ring->adev);
+ if (r)
+ return r;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
+}
+
static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = {
.name = "jpeg_v4_0_5",
.early_init = jpeg_v4_0_5_early_init,
@@ -812,6 +832,7 @@ static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = {
.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = jpeg_v4_0_5_ring_reset,
};
static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev)
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 24/33] drm/amdgpu/jpeg5: add queue reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (22 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 23/33] drm/amdgpu/jpeg4.0.5: add queue reset Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 25/33] drm/amdgpu/jpeg5.0.1: re-emit unprocessed state on ring reset Alex Deucher
` (8 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Add queue reset support for jpeg 5.0.0.
Use the new helpers to re-emit the unprocessed state
after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
index 31d213ccbe0a8..d6b565c29b4b2 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
@@ -120,9 +120,10 @@ static int jpeg_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
- /* TODO: Add queue reset mask when FW fully supports it */
adev->jpeg.supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
+ if (!amdgpu_sriov_vf(adev))
+ adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
if (r)
return r;
@@ -644,6 +645,25 @@ static int jpeg_v5_0_0_process_interrupt(struct amdgpu_device *adev,
return 0;
}
+static int jpeg_v5_0_0_ring_reset(struct amdgpu_ring *ring,
+ unsigned int vmid,
+ struct amdgpu_fence *timedout_fence)
+{
+ int r;
+
+ if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
+ r = jpeg_v5_0_0_stop(ring->adev);
+ if (r)
+ return r;
+ r = jpeg_v5_0_0_start(ring->adev);
+ if (r)
+ return r;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
+}
+
static const struct amd_ip_funcs jpeg_v5_0_0_ip_funcs = {
.name = "jpeg_v5_0_0",
.early_init = jpeg_v5_0_0_early_init,
@@ -689,6 +709,7 @@ static const struct amdgpu_ring_funcs jpeg_v5_0_0_dec_ring_vm_funcs = {
.emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
.emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = jpeg_v5_0_0_ring_reset,
};
static void jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device *adev)
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 25/33] drm/amdgpu/jpeg5.0.1: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (23 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 24/33] drm/amdgpu/jpeg5: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 26/33] drm/amdgpu/vcn4: " Alex Deucher
` (7 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
index 6f8a16da9d608..5473cbaa5c0e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
@@ -838,20 +838,13 @@ static int jpeg_v5_0_1_ring_reset(struct amdgpu_ring *ring,
unsigned int vmid,
struct amdgpu_fence *timedout_fence)
{
- int r;
-
if (amdgpu_sriov_vf(ring->adev))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
jpeg_v5_0_1_core_stall_reset(ring);
jpeg_v5_0_1_init_jrbc(ring);
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 26/33] drm/amdgpu/vcn4: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (24 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 25/33] drm/amdgpu/jpeg5.0.1: re-emit unprocessed state on ring reset Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 27/33] drm/amdgpu/vcn4.0.3: " Alex Deucher
` (6 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
index e6613246d8b8d..f642a06a77b56 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
@@ -1979,20 +1979,14 @@ static int vcn_v4_0_ring_reset(struct amdgpu_ring *ring,
if (!(adev->vcn.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = vcn_v4_0_stop(vinst);
if (r)
return r;
r = vcn_v4_0_start(vinst);
if (r)
return r;
-
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static struct amdgpu_ring_funcs vcn_v4_0_unified_ring_vm_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 27/33] drm/amdgpu/vcn4.0.3: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (25 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 26/33] drm/amdgpu/vcn4: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 28/33] drm/amdgpu/vcn4.0.5: " Alex Deucher
` (5 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
index d8fd32c1e38ec..3bda19b92cde7 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
@@ -1609,7 +1609,7 @@ static int vcn_v4_0_3_ring_reset(struct amdgpu_ring *ring,
if (!(adev->vcn.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
vcn_inst = GET_INST(VCN, ring->me);
r = amdgpu_dpm_reset_vcn(adev, 1 << vcn_inst);
@@ -1624,12 +1624,8 @@ static int vcn_v4_0_3_ring_reset(struct amdgpu_ring *ring,
adev->vcn.caps |= AMDGPU_VCN_CAPS(RRMT_ENABLED);
vcn_v4_0_3_hw_init_inst(vinst);
vcn_v4_0_3_start_dpg_mode(vinst, adev->vcn.inst[ring->me].indirect_sram);
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amdgpu_ring_funcs vcn_v4_0_3_unified_ring_vm_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 28/33] drm/amdgpu/vcn4.0.5: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (26 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 27/33] drm/amdgpu/vcn4.0.3: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 29/33] drm/amdgpu/vcn5: " Alex Deucher
` (4 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
index 732e9a9293d26..039989ab452ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
@@ -1477,20 +1477,14 @@ static int vcn_v4_0_5_ring_reset(struct amdgpu_ring *ring,
if (!(adev->vcn.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = vcn_v4_0_5_stop(vinst);
if (r)
return r;
r = vcn_v4_0_5_start(vinst);
if (r)
return r;
-
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static struct amdgpu_ring_funcs vcn_v4_0_5_unified_ring_vm_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 29/33] drm/amdgpu/vcn5: re-emit unprocessed state on ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (27 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 28/33] drm/amdgpu/vcn4.0.5: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 30/33] drm/amdgpu/vcn: add a helper framework for engine resets Alex Deucher
` (3 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Re-emit the unprocessed state after resetting the queue.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
index a137bef918ed5..ec0268b5666cc 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
@@ -1204,20 +1204,14 @@ static int vcn_v5_0_0_ring_reset(struct amdgpu_ring *ring,
if (!(adev->vcn.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
- drm_sched_wqueue_stop(&ring->sched);
+ amdgpu_ring_reset_helper_begin(ring, timedout_fence);
r = vcn_v5_0_0_stop(vinst);
if (r)
return r;
r = vcn_v5_0_0_start(vinst);
if (r)
return r;
-
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- amdgpu_fence_driver_force_completion(ring);
- drm_sched_wqueue_start(&ring->sched);
- return 0;
+ return amdgpu_ring_reset_helper_end(ring, timedout_fence);
}
static const struct amdgpu_ring_funcs vcn_v5_0_0_unified_ring_vm_funcs = {
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 30/33] drm/amdgpu/vcn: add a helper framework for engine resets
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (28 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 29/33] drm/amdgpu/vcn5: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 31/33] drm/amdgpu/vcn2: implement ring reset Alex Deucher
` (2 subsequent siblings)
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
With engine resets we reset all queues on the engine rather
than just a single queue. Add a framework to handle this
similar to SDMA.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 79 +++++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 6 +-
2 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index c8885c3d54b33..d799bc74936c0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -134,6 +134,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev, int i)
mutex_init(&adev->vcn.inst[i].vcn1_jpeg1_workaround);
mutex_init(&adev->vcn.inst[i].vcn_pg_lock);
+ mutex_init(&adev->vcn.inst[i].engine_reset_mutex);
atomic_set(&adev->vcn.inst[i].total_submission_cnt, 0);
INIT_DELAYED_WORK(&adev->vcn.inst[i].idle_work, amdgpu_vcn_idle_work_handler);
atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0);
@@ -1451,3 +1452,81 @@ int vcn_set_powergating_state(struct amdgpu_ip_block *ip_block,
return ret;
}
+
+/**
+ * amdgpu_vcn_reset_engine - Reset a specific VCN engine
+ * @adev: Pointer to the AMDGPU device
+ * @instance_id: VCN engine instance to reset
+ *
+ * Returns: 0 on success, or a negative error code on failure.
+ */
+static int amdgpu_vcn_reset_engine(struct amdgpu_device *adev,
+ uint32_t instance_id)
+{
+ struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[instance_id];
+ int r, i;
+
+ mutex_lock(&vinst->engine_reset_mutex);
+ /* Stop the scheduler's work queue for the dec and enc rings if they are running.
+ * This ensures that no new tasks are submitted to the queues while
+ * the reset is in progress.
+ */
+ drm_sched_wqueue_stop(&vinst->ring_dec.sched);
+ for (i = 0; i < vinst->num_enc_rings; i++)
+ drm_sched_wqueue_stop(&vinst->ring_enc[i].sched);
+
+ /* Perform the VCN reset for the specified instance */
+ r = vinst->reset(vinst);
+ if (r)
+ goto unlock;
+ r = amdgpu_ring_test_ring(&vinst->ring_dec);
+ if (r)
+ goto unlock;
+ for (i = 0; i < vinst->num_enc_rings; i++) {
+ r = amdgpu_ring_test_ring(&vinst->ring_enc[i]);
+ if (r)
+ goto unlock;
+ }
+ amdgpu_fence_driver_force_completion(&vinst->ring_dec);
+ for (i = 0; i < vinst->num_enc_rings; i++)
+ amdgpu_fence_driver_force_completion(&vinst->ring_enc[i]);
+
+ /* Restart the scheduler's work queue for the dec and enc rings
+ * if they were stopped by this function. This allows new tasks
+ * to be submitted to the queues after the reset is complete.
+ */
+ drm_sched_wqueue_start(&vinst->ring_dec.sched);
+ for (i = 0; i < vinst->num_enc_rings; i++)
+ drm_sched_wqueue_start(&vinst->ring_enc[i].sched);
+
+unlock:
+ mutex_unlock(&vinst->engine_reset_mutex);
+
+ return r;
+}
+
+/**
+ * amdgpu_vcn_ring_reset - Reset a VCN ring
+ * @ring: ring to reset
+ * @vmid: vmid of guilty job
+ * @timedout_fence: fence of timed out job
+ *
+ * This helper is for VCN blocks without unified queues because
+ * resetting the engine resets all queues in that case. With
+ * unified queues we have one queue per engine.
+ * Returns: 0 on success, or a negative error code on failure.
+ */
+int amdgpu_vcn_ring_reset(struct amdgpu_ring *ring,
+ unsigned int vmid,
+ struct amdgpu_fence *timedout_fence)
+{
+ struct amdgpu_device *adev = ring->adev;
+
+ if (!(adev->vcn.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
+ return -EOPNOTSUPP;
+
+ if (adev->vcn.inst[ring->me].using_unified_queue)
+ return -EINVAL;
+
+ return amdgpu_vcn_reset_engine(adev, ring->me);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
index 83adf81defc71..0bc0a94d7cf0f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
@@ -330,7 +330,9 @@ struct amdgpu_vcn_inst {
struct dpg_pause_state *new_state);
int (*set_pg_state)(struct amdgpu_vcn_inst *vinst,
enum amd_powergating_state state);
+ int (*reset)(struct amdgpu_vcn_inst *vinst);
bool using_unified_queue;
+ struct mutex engine_reset_mutex;
};
struct amdgpu_vcn_ras {
@@ -552,5 +554,7 @@ void amdgpu_debugfs_vcn_sched_mask_init(struct amdgpu_device *adev);
int vcn_set_powergating_state(struct amdgpu_ip_block *ip_block,
enum amd_powergating_state state);
-
+int amdgpu_vcn_ring_reset(struct amdgpu_ring *ring,
+ unsigned int vmid,
+ struct amdgpu_fence *guilty_fence);
#endif
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 31/33] drm/amdgpu/vcn2: implement ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (29 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 30/33] drm/amdgpu/vcn: add a helper framework for engine resets Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 32/33] drm/amdgpu/vcn2.5: " Alex Deucher
2025-07-11 22:40 ` [PATCH 33/33] drm/amdgpu/vcn3: " Alex Deucher
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Use the new helpers to handle engine resets for VCN.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
index 148b651be7ca7..68b4371df0f1b 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
@@ -98,6 +98,8 @@ static int vcn_v2_0_set_pg_state(struct amdgpu_vcn_inst *vinst,
static int vcn_v2_0_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
struct dpg_pause_state *new_state);
static int vcn_v2_0_start_sriov(struct amdgpu_device *adev);
+static int vcn_v2_0_reset(struct amdgpu_vcn_inst *vinst);
+
/**
* vcn_v2_0_early_init - set function pointers and load microcode
*
@@ -213,6 +215,12 @@ static int vcn_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
}
adev->vcn.inst[0].pause_dpg_mode = vcn_v2_0_pause_dpg_mode;
+ adev->vcn.inst[0].reset = vcn_v2_0_reset;
+
+ adev->vcn.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
+ if (!amdgpu_sriov_vf(adev))
+ adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_virt_alloc_mm_table(adev);
if (r)
@@ -233,6 +241,10 @@ static int vcn_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
adev->vcn.ip_dump = ptr;
}
+ r = amdgpu_vcn_sysfs_reset_mask_init(adev);
+ if (r)
+ return r;
+
return 0;
}
@@ -260,6 +272,8 @@ static int vcn_v2_0_sw_fini(struct amdgpu_ip_block *ip_block)
if (r)
return r;
+ amdgpu_vcn_sysfs_reset_mask_fini(adev);
+
r = amdgpu_vcn_sw_fini(adev, 0);
kfree(adev->vcn.ip_dump);
@@ -1355,6 +1369,16 @@ static int vcn_v2_0_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
return 0;
}
+static int vcn_v2_0_reset(struct amdgpu_vcn_inst *vinst)
+{
+ int r;
+
+ r = vcn_v2_0_stop(vinst);
+ if (r)
+ return r;
+ return vcn_v2_0_start(vinst);
+}
+
static bool vcn_v2_0_is_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
@@ -2176,6 +2200,7 @@ static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = {
.emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
.emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = amdgpu_vcn_ring_reset,
};
static const struct amdgpu_ring_funcs vcn_v2_0_enc_ring_vm_funcs = {
@@ -2205,6 +2230,7 @@ static const struct amdgpu_ring_funcs vcn_v2_0_enc_ring_vm_funcs = {
.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = amdgpu_vcn_ring_reset,
};
static void vcn_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev)
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 32/33] drm/amdgpu/vcn2.5: implement ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (30 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 31/33] drm/amdgpu/vcn2: implement ring reset Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
2025-07-11 22:40 ` [PATCH 33/33] drm/amdgpu/vcn3: " Alex Deucher
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Use the new helpers to handle engine resets for VCN.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
index 58b527a6b795f..bc30a5326866c 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
@@ -102,6 +102,7 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
struct dpg_pause_state *new_state);
static int vcn_v2_5_sriov_start(struct amdgpu_device *adev);
static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev);
+static int vcn_v2_5_reset(struct amdgpu_vcn_inst *vinst);
static int amdgpu_ih_clientid_vcns[] = {
SOC15_IH_CLIENTID_VCN,
@@ -404,8 +405,14 @@ static int vcn_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
adev->vcn.inst[j].pause_dpg_mode = vcn_v2_5_pause_dpg_mode;
+ adev->vcn.inst[j].reset = vcn_v2_5_reset;
}
+ adev->vcn.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
+ if (!amdgpu_sriov_vf(adev))
+ adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
if (amdgpu_sriov_vf(adev)) {
r = amdgpu_virt_alloc_mm_table(adev);
if (r)
@@ -425,6 +432,10 @@ static int vcn_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
adev->vcn.ip_dump = ptr;
}
+ r = amdgpu_vcn_sysfs_reset_mask_init(adev);
+ if (r)
+ return r;
+
return 0;
}
@@ -455,6 +466,8 @@ static int vcn_v2_5_sw_fini(struct amdgpu_ip_block *ip_block)
if (amdgpu_sriov_vf(adev))
amdgpu_virt_free_mm_table(adev);
+ amdgpu_vcn_sysfs_reset_mask_fini(adev);
+
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
r = amdgpu_vcn_suspend(adev, i);
if (r)
@@ -1816,6 +1829,7 @@ static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
.emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
.emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = amdgpu_vcn_ring_reset,
};
/**
@@ -1914,6 +1928,7 @@ static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = amdgpu_vcn_ring_reset,
};
static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
@@ -1942,6 +1957,16 @@ static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
}
}
+static int vcn_v2_5_reset(struct amdgpu_vcn_inst *vinst)
+{
+ int r;
+
+ r = vcn_v2_5_stop(vinst);
+ if (r)
+ return r;
+ return vcn_v2_5_start(vinst);
+}
+
static bool vcn_v2_5_is_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* [PATCH 33/33] drm/amdgpu/vcn3: implement ring reset
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
` (31 preceding siblings ...)
2025-07-11 22:40 ` [PATCH 32/33] drm/amdgpu/vcn2.5: " Alex Deucher
@ 2025-07-11 22:40 ` Alex Deucher
32 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-11 22:40 UTC (permalink / raw)
To: amd-gfx, christian.koenig, sasundar; +Cc: Alex Deucher, Sathishkumar S
Use the new helpers to handle engine resets for VCN.
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Tested-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
index 9fb0d53805892..4b8f4407047fc 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
@@ -110,6 +110,7 @@ static int vcn_v3_0_set_pg_state(struct amdgpu_vcn_inst *vinst,
enum amd_powergating_state state);
static int vcn_v3_0_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
struct dpg_pause_state *new_state);
+static int vcn_v3_0_reset(struct amdgpu_vcn_inst *vinst);
static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring);
static void vcn_v3_0_enc_ring_set_wptr(struct amdgpu_ring *ring);
@@ -289,8 +290,14 @@ static int vcn_v3_0_sw_init(struct amdgpu_ip_block *ip_block)
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
adev->vcn.inst[i].pause_dpg_mode = vcn_v3_0_pause_dpg_mode;
+ adev->vcn.inst[i].reset = vcn_v3_0_reset;
}
+ adev->vcn.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
+ if (!amdgpu_sriov_vf(adev))
+ adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
if (amdgpu_sriov_vf(adev)) {
r = amdgpu_virt_alloc_mm_table(adev);
if (r)
@@ -306,6 +313,10 @@ static int vcn_v3_0_sw_init(struct amdgpu_ip_block *ip_block)
adev->vcn.ip_dump = ptr;
}
+ r = amdgpu_vcn_sysfs_reset_mask_init(adev);
+ if (r)
+ return r;
+
return 0;
}
@@ -338,6 +349,8 @@ static int vcn_v3_0_sw_fini(struct amdgpu_ip_block *ip_block)
if (amdgpu_sriov_vf(adev))
amdgpu_virt_free_mm_table(adev);
+ amdgpu_vcn_sysfs_reset_mask_fini(adev);
+
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
r = amdgpu_vcn_suspend(adev, i);
if (r)
@@ -2033,6 +2046,7 @@ static const struct amdgpu_ring_funcs vcn_v3_0_dec_ring_vm_funcs = {
.emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
.emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = amdgpu_vcn_ring_reset,
};
/**
@@ -2131,6 +2145,7 @@ static const struct amdgpu_ring_funcs vcn_v3_0_enc_ring_vm_funcs = {
.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
+ .reset = amdgpu_vcn_ring_reset,
};
static void vcn_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev)
@@ -2164,6 +2179,18 @@ static void vcn_v3_0_set_enc_ring_funcs(struct amdgpu_device *adev)
}
}
+static int vcn_v3_0_reset(struct amdgpu_vcn_inst *vinst)
+{
+ int r;
+
+ r = vcn_v3_0_stop(vinst);
+ if (r)
+ return r;
+ vcn_v3_0_enable_clock_gating(vinst);
+ vcn_v3_0_enable_static_power_gating(vinst);
+ return vcn_v3_0_start(vinst);
+}
+
static bool vcn_v3_0_is_idle(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
--
2.50.0
^ permalink raw reply related [flat|nested] 48+ messages in thread
* Re: [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking
2025-07-11 22:39 ` [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking Alex Deucher
@ 2025-07-14 2:58 ` Sundararaju, Sathishkumar
2025-07-14 13:29 ` Christian König
1 sibling, 0 replies; 48+ messages in thread
From: Sundararaju, Sathishkumar @ 2025-07-14 2:58 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, christian.koenig, sasundar
This patch is :-
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
On 7/12/2025 4:09 AM, Alex Deucher wrote:
> Start and stop can fail, so add checks.
>
> Fixes: 500c04d2a708 ("drm/amdgpu: Add ring reset callback for JPEG2_0_0")
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: Sathishkumar S <sathishkumar.sundararaju@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> index 781a5a8a83614..5ba1c5ad9a5e1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> @@ -771,8 +771,12 @@ static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring,
> int r;
>
> drm_sched_wqueue_stop(&ring->sched);
> - jpeg_v2_0_stop(ring->adev);
> - jpeg_v2_0_start(ring->adev);
> + r = jpeg_v2_0_stop(ring->adev);
> + if (r)
> + return r;
> + r = jpeg_v2_0_start(ring->adev);
> + if (r)
> + return r;
> r = amdgpu_ring_test_helper(ring);
> if (r)
> return r;
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 03/33] drm/amdgpu/jpeg3: add additional ring reset error checking
2025-07-11 22:39 ` [PATCH 03/33] drm/amdgpu/jpeg3: " Alex Deucher
@ 2025-07-14 3:00 ` Sundararaju, Sathishkumar
0 siblings, 0 replies; 48+ messages in thread
From: Sundararaju, Sathishkumar @ 2025-07-14 3:00 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, christian.koenig, sasundar
This patch is :-
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
On 7/12/2025 4:09 AM, Alex Deucher wrote:
> Start and stop can fail, so add checks.
>
> Fixes: 03399d0bff25 ("drm/amdgpu: Add ring reset callback for JPEG3_0_0")
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: Sathishkumar S <sathishkumar.sundararaju@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> index a24bd833d6442..5428930eafa3e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> @@ -562,8 +562,12 @@ static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring,
> int r;
>
> drm_sched_wqueue_stop(&ring->sched);
> - jpeg_v3_0_stop(ring->adev);
> - jpeg_v3_0_start(ring->adev);
> + r = jpeg_v3_0_stop(ring->adev);
> + if (r)
> + return r;
> + r = jpeg_v3_0_start(ring->adev);
> + if (r)
> + return r;
> r = amdgpu_ring_test_helper(ring);
> if (r)
> return r;
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 04/33] drm/amdgpu/jpeg4: add additional ring reset error checking
2025-07-11 22:39 ` [PATCH 04/33] drm/amdgpu/jpeg4: " Alex Deucher
@ 2025-07-14 3:02 ` Sundararaju, Sathishkumar
0 siblings, 0 replies; 48+ messages in thread
From: Sundararaju, Sathishkumar @ 2025-07-14 3:02 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, christian.koenig, sasundar
This patch is :-
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
On 7/12/2025 4:09 AM, Alex Deucher wrote:
> Start and stop can fail, so add checks.
>
> Fixes: 74894ffc7d0c ("drm/amdgpu: Add ring reset callback for JPEG4_0_0")
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: Sathishkumar S <sathishkumar.sundararaju@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> index 1d4edd77837d0..78fe1924f3cb7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> @@ -730,8 +730,12 @@ static int jpeg_v4_0_ring_reset(struct amdgpu_ring *ring,
> return -EINVAL;
>
> drm_sched_wqueue_stop(&ring->sched);
> - jpeg_v4_0_stop(ring->adev);
> - jpeg_v4_0_start(ring->adev);
> + r = jpeg_v4_0_stop(ring->adev);
> + if (r)
> + return r;
> + r = jpeg_v4_0_start(ring->adev);
> + if (r)
> + return r;
> r = amdgpu_ring_test_helper(ring);
> if (r)
> return r;
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions
2025-07-11 22:39 ` [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions Alex Deucher
@ 2025-07-14 3:24 ` Sundararaju, Sathishkumar
2025-07-14 13:36 ` Christian König
1 sibling, 0 replies; 48+ messages in thread
From: Sundararaju, Sathishkumar @ 2025-07-14 3:24 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, christian.koenig, sasundar
This patch is :-
Reviewed-by: Sathishkumar S <sathishkumar.sundararaju@amd.com>
On 7/12/2025 4:09 AM, Alex Deucher wrote:
> Make them consistent and use the reset flags.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 6 +++++-
> drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 6 +++++-
> drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 6 +++++-
> drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 7 ++++---
> 4 files changed, 19 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> index 5ba1c5ad9a5e1..0b56cb67e8f1d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> @@ -118,7 +118,8 @@ static int jpeg_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -770,6 +771,9 @@ static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> drm_sched_wqueue_stop(&ring->sched);
> r = jpeg_v2_0_stop(ring->adev);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> index 5be9cdcae32c1..3d0e61f9f2854 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> @@ -167,7 +167,8 @@ static int jpeg_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -649,6 +650,9 @@ static int jpeg_v2_5_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> drm_sched_wqueue_stop(&ring->sched);
> jpeg_v2_5_stop_inst(ring->adev, ring->me);
> jpeg_v2_5_start_inst(ring->adev, ring->me);
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> index 5428930eafa3e..5d54c882d889c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> @@ -132,7 +132,8 @@ static int jpeg_v3_0_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -561,6 +562,9 @@ static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> drm_sched_wqueue_stop(&ring->sched);
> r = jpeg_v3_0_stop(ring->adev);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> index 78fe1924f3cb7..5485e983a089f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> @@ -143,7 +143,8 @@ static int jpeg_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -726,8 +727,8 @@ static int jpeg_v4_0_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> - if (amdgpu_sriov_vf(ring->adev))
> - return -EINVAL;
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
>
> drm_sched_wqueue_stop(&ring->sched);
> r = jpeg_v4_0_stop(ring->adev);
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 01/33] drm/amdgpu: clean up sdma reset functions
2025-07-11 22:39 ` [PATCH 01/33] drm/amdgpu: clean up sdma reset functions Alex Deucher
@ 2025-07-14 13:27 ` Christian König
2025-07-14 14:00 ` Lazar, Lijo
1 sibling, 0 replies; 48+ messages in thread
From: Christian König @ 2025-07-14 13:27 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, sasundar
On 12.07.25 00:39, Alex Deucher wrote:
> Make them consistent and drop unneeded extra variables.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 14 +++++++++++---
> drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 17 +++++++++++++----
> drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 20 ++++++++------------
> drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 20 ++++++++------------
> 4 files changed, 40 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> index 5a1098bdd8256..999705e7b2641 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> @@ -1428,7 +1428,8 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block)
> case IP_VERSION(5, 0, 0):
> case IP_VERSION(5, 0, 2):
> case IP_VERSION(5, 0, 5):
> - if (adev->sdma.instance[0].fw_version >= 35)
> + if ((adev->sdma.instance[0].fw_version >= 35) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> default:
> @@ -1544,11 +1545,18 @@ static int sdma_v5_0_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - u32 inst_id = ring->me;
> int r;
>
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> + return -EINVAL;
> + }
> +
> amdgpu_amdkfd_suspend(adev, true);
> - r = amdgpu_sdma_reset_engine(adev, inst_id, false);
> + r = amdgpu_sdma_reset_engine(adev, ring->me, false);
> amdgpu_amdkfd_resume(adev, true);
>
> 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 6843c2c3d71f5..e542195972dd4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> @@ -1347,11 +1347,13 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block)
> case IP_VERSION(5, 2, 2):
> case IP_VERSION(5, 2, 3):
> case IP_VERSION(5, 2, 4):
> - if (adev->sdma.instance[0].fw_version >= 76)
> + if ((adev->sdma.instance[0].fw_version >= 76) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> case IP_VERSION(5, 2, 5):
> - if (adev->sdma.instance[0].fw_version >= 34)
> + if ((adev->sdma.instance[0].fw_version >= 34) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> default:
> @@ -1457,11 +1459,18 @@ static int sdma_v5_2_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - u32 inst_id = ring->me;
> int r;
>
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> + return -EINVAL;
> + }
> +
> amdgpu_amdkfd_suspend(adev, true);
> - r = amdgpu_sdma_reset_engine(adev, inst_id, false);
> + r = amdgpu_sdma_reset_engine(adev, ring->me, false);
> amdgpu_amdkfd_resume(adev, true);
>
> 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 d2effa5318176..c08e9a6cf6827 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> @@ -1355,7 +1355,8 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
> case IP_VERSION(6, 0, 0):
> case IP_VERSION(6, 0, 2):
> case IP_VERSION(6, 0, 3):
> - if (adev->sdma.instance[0].fw_version >= 21)
> + if ((adev->sdma.instance[0].fw_version >= 21) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> default:
> @@ -1575,18 +1576,13 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - int i, r;
> -
> - if (amdgpu_sriov_vf(adev))
> - return -EINVAL;
> + int r;
>
> - for (i = 0; i < adev->sdma.num_instances; i++) {
> - if (ring == &adev->sdma.instance[i].ring)
> - break;
> - }
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
>
> - if (i == adev->sdma.num_instances) {
> - DRM_ERROR("sdma instance not found\n");
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> return -EINVAL;
> }
>
> @@ -1596,7 +1592,7 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
> if (r)
> return r;
>
> - r = sdma_v6_0_gfx_resume_instance(adev, i, true);
> + r = sdma_v6_0_gfx_resume_instance(adev, ring->me, true);
> if (r)
> return r;
> amdgpu_fence_driver_force_completion(ring);
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> index 99a080bad2a3d..ba1f3e3b6eb61 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> @@ -807,18 +807,13 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - int i, r;
> -
> - if (amdgpu_sriov_vf(adev))
> - return -EINVAL;
> + int r;
>
> - for (i = 0; i < adev->sdma.num_instances; i++) {
> - if (ring == &adev->sdma.instance[i].ring)
> - break;
> - }
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
>
> - if (i == adev->sdma.num_instances) {
> - DRM_ERROR("sdma instance not found\n");
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> return -EINVAL;
> }
>
> @@ -828,7 +823,7 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
> if (r)
> return r;
>
> - r = sdma_v7_0_gfx_resume_instance(adev, i, true);
> + r = sdma_v7_0_gfx_resume_instance(adev, ring->me, true);
> if (r)
> return r;
> amdgpu_fence_driver_force_completion(ring);
> @@ -1346,7 +1341,8 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
>
> adev->sdma.supported_reset =
> amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
> - adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
>
> r = amdgpu_sdma_sysfs_reset_mask_init(adev);
> if (r)
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking
2025-07-11 22:39 ` [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking Alex Deucher
2025-07-14 2:58 ` Sundararaju, Sathishkumar
@ 2025-07-14 13:29 ` Christian König
1 sibling, 0 replies; 48+ messages in thread
From: Christian König @ 2025-07-14 13:29 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, sasundar; +Cc: Sathishkumar S
On 12.07.25 00:39, Alex Deucher wrote:
> Start and stop can fail, so add checks.
>
> Fixes: 500c04d2a708 ("drm/amdgpu: Add ring reset callback for JPEG2_0_0")
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: Sathishkumar S <sathishkumar.sundararaju@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com> for patches #2-#4.
> ---
> drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> index 781a5a8a83614..5ba1c5ad9a5e1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> @@ -771,8 +771,12 @@ static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring,
> int r;
>
> drm_sched_wqueue_stop(&ring->sched);
> - jpeg_v2_0_stop(ring->adev);
> - jpeg_v2_0_start(ring->adev);
> + r = jpeg_v2_0_stop(ring->adev);
> + if (r)
> + return r;
> + r = jpeg_v2_0_start(ring->adev);
> + if (r)
> + return r;
> r = amdgpu_ring_test_helper(ring);
> if (r)
> return r;
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 05/33] drm/amdgpu/vcn: don't enable per queue resets on SR-IOV
2025-07-11 22:39 ` [PATCH 05/33] drm/amdgpu/vcn: don't enable per queue resets on SR-IOV Alex Deucher
@ 2025-07-14 13:30 ` Christian König
0 siblings, 0 replies; 48+ messages in thread
From: Christian König @ 2025-07-14 13:30 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, sasundar
On 12.07.25 00:39, Alex Deucher wrote:
> Power control is only available in bare metal. SR-IOV
> will need a different method.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 3 ++-
> drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 3 ++-
> drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 3 ++-
> 3 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> index 5bbce8544fef0..e6613246d8b8d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> @@ -241,7 +241,8 @@ static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
>
> adev->vcn.supported_reset =
> amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
> - adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
>
> if (amdgpu_sriov_vf(adev)) {
> r = amdgpu_virt_alloc_mm_table(adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> index 6000c528ad6ae..732e9a9293d26 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> @@ -220,7 +220,8 @@ static int vcn_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block)
> }
>
> adev->vcn.supported_reset = amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
> - adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
>
> r = amdgpu_vcn_sysfs_reset_mask_init(adev);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> index 3d3b4254bd729..a137bef918ed5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> @@ -198,7 +198,8 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block)
>
> adev->vcn.supported_reset =
> amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
> - adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
>
> vcn_v5_0_0_alloc_ip_dump(adev);
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions
2025-07-11 22:39 ` [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions Alex Deucher
2025-07-14 3:24 ` Sundararaju, Sathishkumar
@ 2025-07-14 13:36 ` Christian König
1 sibling, 0 replies; 48+ messages in thread
From: Christian König @ 2025-07-14 13:36 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, sasundar
On 12.07.25 00:39, Alex Deucher wrote:
> Make them consistent and use the reset flags.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
I'm not very keen on spreading amdgpu_sriov_vf() around everywere.
But for now Acked-by: Christian König <christian.koenig@amd.com> for patches #6 and #7.
> ---
> drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 6 +++++-
> drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 6 +++++-
> drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 6 +++++-
> drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 7 ++++---
> 4 files changed, 19 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> index 5ba1c5ad9a5e1..0b56cb67e8f1d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
> @@ -118,7 +118,8 @@ static int jpeg_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -770,6 +771,9 @@ static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> drm_sched_wqueue_stop(&ring->sched);
> r = jpeg_v2_0_stop(ring->adev);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> index 5be9cdcae32c1..3d0e61f9f2854 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
> @@ -167,7 +167,8 @@ static int jpeg_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -649,6 +650,9 @@ static int jpeg_v2_5_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> drm_sched_wqueue_stop(&ring->sched);
> jpeg_v2_5_stop_inst(ring->adev, ring->me);
> jpeg_v2_5_start_inst(ring->adev, ring->me);
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> index 5428930eafa3e..5d54c882d889c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
> @@ -132,7 +132,8 @@ static int jpeg_v3_0_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -561,6 +562,9 @@ static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> drm_sched_wqueue_stop(&ring->sched);
> r = jpeg_v3_0_stop(ring->adev);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> index 78fe1924f3cb7..5485e983a089f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
> @@ -143,7 +143,8 @@ static int jpeg_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
> if (r)
> return r;
>
> - adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
> r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
>
> return r;
> @@ -726,8 +727,8 @@ static int jpeg_v4_0_ring_reset(struct amdgpu_ring *ring,
> {
> int r;
>
> - if (amdgpu_sriov_vf(ring->adev))
> - return -EINVAL;
> + if (!(ring->adev->jpeg.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
>
> drm_sched_wqueue_stop(&ring->sched);
> r = jpeg_v4_0_stop(ring->adev);
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 01/33] drm/amdgpu: clean up sdma reset functions
2025-07-11 22:39 ` [PATCH 01/33] drm/amdgpu: clean up sdma reset functions Alex Deucher
2025-07-14 13:27 ` Christian König
@ 2025-07-14 14:00 ` Lazar, Lijo
2025-07-15 13:33 ` Alex Deucher
1 sibling, 1 reply; 48+ messages in thread
From: Lazar, Lijo @ 2025-07-14 14:00 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, christian.koenig, sasundar
Since the series has supported_reset across different ip blocks, isn't
it better to move this to amdgpu_ip_block? Or, if this needs to be
specific to be different type of rings within an IP block, keep a
supported_reset flag per ring to do something like -
amdgpu_ring_is_reset_supported(ring, reset_type) and call
amdgpu_ring_reset()?
Thanks,
Lijo
On 7/12/2025 4:09 AM, Alex Deucher wrote:
> Make them consistent and drop unneeded extra variables.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 14 +++++++++++---
> drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 17 +++++++++++++----
> drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 20 ++++++++------------
> drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 20 ++++++++------------
> 4 files changed, 40 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> index 5a1098bdd8256..999705e7b2641 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> @@ -1428,7 +1428,8 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block)
> case IP_VERSION(5, 0, 0):
> case IP_VERSION(5, 0, 2):
> case IP_VERSION(5, 0, 5):
> - if (adev->sdma.instance[0].fw_version >= 35)
> + if ((adev->sdma.instance[0].fw_version >= 35) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> default:
> @@ -1544,11 +1545,18 @@ static int sdma_v5_0_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - u32 inst_id = ring->me;
> int r;
>
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> + return -EINVAL;
> + }
> +
> amdgpu_amdkfd_suspend(adev, true);
> - r = amdgpu_sdma_reset_engine(adev, inst_id, false);
> + r = amdgpu_sdma_reset_engine(adev, ring->me, false);
> amdgpu_amdkfd_resume(adev, true);
>
> 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 6843c2c3d71f5..e542195972dd4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> @@ -1347,11 +1347,13 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block)
> case IP_VERSION(5, 2, 2):
> case IP_VERSION(5, 2, 3):
> case IP_VERSION(5, 2, 4):
> - if (adev->sdma.instance[0].fw_version >= 76)
> + if ((adev->sdma.instance[0].fw_version >= 76) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> case IP_VERSION(5, 2, 5):
> - if (adev->sdma.instance[0].fw_version >= 34)
> + if ((adev->sdma.instance[0].fw_version >= 34) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> default:
> @@ -1457,11 +1459,18 @@ static int sdma_v5_2_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - u32 inst_id = ring->me;
> int r;
>
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
> +
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> + return -EINVAL;
> + }
> +
> amdgpu_amdkfd_suspend(adev, true);
> - r = amdgpu_sdma_reset_engine(adev, inst_id, false);
> + r = amdgpu_sdma_reset_engine(adev, ring->me, false);
> amdgpu_amdkfd_resume(adev, true);
>
> 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 d2effa5318176..c08e9a6cf6827 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> @@ -1355,7 +1355,8 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
> case IP_VERSION(6, 0, 0):
> case IP_VERSION(6, 0, 2):
> case IP_VERSION(6, 0, 3):
> - if (adev->sdma.instance[0].fw_version >= 21)
> + if ((adev->sdma.instance[0].fw_version >= 21) &&
> + !amdgpu_sriov_vf(adev))
> adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> break;
> default:
> @@ -1575,18 +1576,13 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - int i, r;
> -
> - if (amdgpu_sriov_vf(adev))
> - return -EINVAL;
> + int r;
>
> - for (i = 0; i < adev->sdma.num_instances; i++) {
> - if (ring == &adev->sdma.instance[i].ring)
> - break;
> - }
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
>
> - if (i == adev->sdma.num_instances) {
> - DRM_ERROR("sdma instance not found\n");
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> return -EINVAL;
> }
>
> @@ -1596,7 +1592,7 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
> if (r)
> return r;
>
> - r = sdma_v6_0_gfx_resume_instance(adev, i, true);
> + r = sdma_v6_0_gfx_resume_instance(adev, ring->me, true);
> if (r)
> return r;
> amdgpu_fence_driver_force_completion(ring);
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> index 99a080bad2a3d..ba1f3e3b6eb61 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> @@ -807,18 +807,13 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
> struct amdgpu_fence *timedout_fence)
> {
> struct amdgpu_device *adev = ring->adev;
> - int i, r;
> -
> - if (amdgpu_sriov_vf(adev))
> - return -EINVAL;
> + int r;
>
> - for (i = 0; i < adev->sdma.num_instances; i++) {
> - if (ring == &adev->sdma.instance[i].ring)
> - break;
> - }
> + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> + return -EOPNOTSUPP;
>
> - if (i == adev->sdma.num_instances) {
> - DRM_ERROR("sdma instance not found\n");
> + if (ring->me >= adev->sdma.num_instances) {
> + dev_err(adev->dev, "sdma instance not found\n");
> return -EINVAL;
> }
>
> @@ -828,7 +823,7 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
> if (r)
> return r;
>
> - r = sdma_v7_0_gfx_resume_instance(adev, i, true);
> + r = sdma_v7_0_gfx_resume_instance(adev, ring->me, true);
> if (r)
> return r;
> amdgpu_fence_driver_force_completion(ring);
> @@ -1346,7 +1341,8 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
>
> adev->sdma.supported_reset =
> amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
> - adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> + if (!amdgpu_sriov_vf(adev))
> + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
>
> r = amdgpu_sdma_sysfs_reset_mask_init(adev);
> if (r)
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 08/33] drm/amdgpu: track ring state associated with a fence
2025-07-11 22:39 ` [PATCH 08/33] drm/amdgpu: track ring state associated with a fence Alex Deucher
@ 2025-07-14 14:02 ` Christian König
0 siblings, 0 replies; 48+ messages in thread
From: Christian König @ 2025-07-14 14:02 UTC (permalink / raw)
To: Alex Deucher, amd-gfx, sasundar
On 12.07.25 00:39, Alex Deucher wrote:
> We need to know the wptr and sequence number associated
> with a fence so that we can re-emit the unprocessed state
> after a ring reset. Pre-allocate storage space for
> the ring buffer contents and add helpers to save off
> and re-emit the unprocessed state so that it can be
> re-emitted after the queue is reset.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This clearly needs a follow up cleanup, but Reviewed-by: Christian König <christian.koenig@amd.com> for now.
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 90 +++++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 15 +++-
> drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 67 +++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 18 +++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 +
> 6 files changed, 195 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> index 2d6b2b486baf7..3f2080aecd5a3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> @@ -120,6 +120,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
> am_fence = kzalloc(sizeof(*am_fence), GFP_KERNEL);
> if (!am_fence)
> return -ENOMEM;
> + am_fence->context = 0;
> } else {
> am_fence = af;
> }
> @@ -127,6 +128,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
> am_fence->ring = ring;
>
> seq = ++ring->fence_drv.sync_seq;
> + am_fence->seq = seq;
> if (af) {
> dma_fence_init(fence, &amdgpu_job_fence_ops,
> &ring->fence_drv.lock,
> @@ -141,6 +143,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
>
> amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
> seq, flags | AMDGPU_FENCE_FLAG_INT);
> + amdgpu_fence_save_wptr(fence);
> pm_runtime_get_noresume(adev_to_drm(adev)->dev);
> ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
> if (unlikely(rcu_dereference_protected(*ptr, 1))) {
> @@ -253,6 +256,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
>
> do {
> struct dma_fence *fence, **ptr;
> + struct amdgpu_fence *am_fence;
>
> ++last_seq;
> last_seq &= drv->num_fences_mask;
> @@ -265,6 +269,12 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
> if (!fence)
> continue;
>
> + /* Save the wptr in the fence driver so we know what the last processed
> + * wptr was. This is required for re-emitting the ring state for
> + * queues that are reset but are not guilty and thus have no guilty fence.
> + */
> + am_fence = container_of(fence, struct amdgpu_fence, base);
> + drv->signalled_wptr = am_fence->wptr;
> dma_fence_signal(fence);
> dma_fence_put(fence);
> pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
> @@ -727,6 +737,86 @@ void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring)
> amdgpu_fence_process(ring);
> }
>
> +
> +/**
> + * Kernel queue reset handling
> + *
> + * The driver can reset individual queues for most engines, but those queues
> + * may contain work from multiple contexts. Resetting the queue will reset
> + * lose all of that state. In order to minimize the collateral damage, the
> + * driver will save the ring contents which are not associated with the guilty
> + * context prior to resetting the queue. After resetting the queue the queue
> + * contents from the other contexts is re-emitted to the rings so that it can
> + * be processed by the engine. To handle this, we save the queue's write
> + * pointer (wptr) in the fences associated with each context. If we get a
> + * queue timeout, we can then use the wptrs from the fences to determine
> + * which data needs to be saved out of the queue's ring buffer.
> + */
> +
> +/**
> + * amdgpu_fence_driver_guilty_force_completion - force signal of specified sequence
> + *
> + * @fence: fence of the ring to signal
> + *
> + */
> +void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence)
> +{
> + dma_fence_set_error(&fence->base, -ETIME);
> + amdgpu_fence_write(fence->ring, fence->seq);
> + amdgpu_fence_process(fence->ring);
> +}
> +
> +void amdgpu_fence_save_wptr(struct dma_fence *fence)
> +{
> + struct amdgpu_fence *am_fence = container_of(fence, struct amdgpu_fence, base);
> +
> + am_fence->wptr = am_fence->ring->wptr;
> +}
> +
> +static void amdgpu_ring_backup_unprocessed_command(struct amdgpu_ring *ring,
> + u64 start_wptr, u32 end_wptr)
> +{
> + unsigned int first_idx = start_wptr & ring->buf_mask;
> + unsigned int last_idx = end_wptr & ring->buf_mask;
> + unsigned int i;
> +
> + /* Backup the contents of the ring buffer. */
> + for (i = first_idx; i != last_idx; ++i, i &= ring->buf_mask)
> + ring->ring_backup[ring->ring_backup_entries_to_copy++] = ring->ring[i];
> +}
> +
> +void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
> + struct amdgpu_fence *guilty_fence)
> +{
> + struct dma_fence *unprocessed;
> + struct dma_fence __rcu **ptr;
> + struct amdgpu_fence *fence;
> + u64 wptr, i, seqno;
> +
> + seqno = amdgpu_fence_read(ring);
> + wptr = ring->fence_drv.signalled_wptr;
> + ring->ring_backup_entries_to_copy = 0;
> +
> + for (i = seqno + 1; i <= ring->fence_drv.sync_seq; ++i) {
> + ptr = &ring->fence_drv.fences[i & ring->fence_drv.num_fences_mask];
> + rcu_read_lock();
> + unprocessed = rcu_dereference(*ptr);
> +
> + if (unprocessed && !dma_fence_is_signaled(unprocessed)) {
> + fence = container_of(unprocessed, struct amdgpu_fence, base);
> +
> + /* save everything if the ring is not guilty, otherwise
> + * just save the content from other contexts.
> + */
> + if (!guilty_fence || (fence->context != guilty_fence->context))
> + amdgpu_ring_backup_unprocessed_command(ring, wptr,
> + fence->wptr);
> + wptr = fence->wptr;
> + }
> + rcu_read_unlock();
> + }
> +}
> +
> /*
> * Common fence implementation
> */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> index 206b70acb29a0..7d9bcb72e8dd3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> @@ -139,7 +139,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> int vmid = AMDGPU_JOB_GET_VMID(job);
> bool need_pipe_sync = false;
> unsigned int cond_exec;
> -
> unsigned int i;
> int r = 0;
>
> @@ -156,6 +155,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> gds_va = job->gds_va;
> init_shadow = job->init_shadow;
> af = &job->hw_fence;
> + /* Save the context of the job for reset handling.
> + * The driver needs this so it can skip the ring
> + * contents for guilty contexts.
> + */
> + af->context = job->base.s_fence ? job->base.s_fence->finished.context : 0;
> } else {
> vm = NULL;
> fence_ctx = 0;
> @@ -307,8 +311,17 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
> ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
> ring->funcs->emit_wave_limit(ring, false);
>
> + /* Save the wptr associated with this fence.
> + * This must be last for resets to work properly
> + * as we need to save the wptr associated with this
> + * fence so we know what rings contents to backup
> + * after we reset the queue.
> + */
> + amdgpu_fence_save_wptr(*f);
> +
> amdgpu_ring_ib_end(ring);
> amdgpu_ring_commit(ring);
> +
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> index f0b7080dccb8d..45febdc2f3493 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> @@ -89,8 +89,8 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
> {
> struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched);
> struct amdgpu_job *job = to_amdgpu_job(s_job);
> - struct amdgpu_task_info *ti;
> struct amdgpu_device *adev = ring->adev;
> + struct amdgpu_task_info *ti;
> int idx, r;
>
> if (!drm_dev_enter(adev_to_drm(adev), &idx)) {
> @@ -135,7 +135,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
> } else if (amdgpu_gpu_recovery && ring->funcs->reset) {
> dev_err(adev->dev, "Starting %s ring reset\n",
> s_job->sched->name);
> - r = amdgpu_ring_reset(ring, job->vmid, NULL);
> + r = amdgpu_ring_reset(ring, job->vmid, &job->hw_fence);
> if (!r) {
> atomic_inc(&ring->adev->gpu_reset_counter);
> dev_err(adev->dev, "Ring %s reset succeeded\n",
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
> index 426834806fbf2..09d7681b7a754 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
> @@ -99,6 +99,29 @@ int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned int ndw)
> return 0;
> }
>
> +/**
> + * amdgpu_ring_alloc_reemit - allocate space on the ring buffer for reemit
> + *
> + * @ring: amdgpu_ring structure holding ring information
> + * @ndw: number of dwords to allocate in the ring buffer
> + *
> + * Allocate @ndw dwords in the ring buffer (all asics).
> + * doesn't check the max_dw limit as we may be reemitting
> + * several submissions.
> + */
> +static void amdgpu_ring_alloc_reemit(struct amdgpu_ring *ring, unsigned int ndw)
> +{
> + /* Align requested size with padding so unlock_commit can
> + * pad safely */
> + ndw = (ndw + ring->funcs->align_mask) & ~ring->funcs->align_mask;
> +
> + ring->count_dw = ndw;
> + ring->wptr_old = ring->wptr;
> +
> + if (ring->funcs->begin_use)
> + ring->funcs->begin_use(ring);
> +}
> +
> /** amdgpu_ring_insert_nop - insert NOP packets
> *
> * @ring: amdgpu_ring structure holding ring information
> @@ -333,6 +356,12 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
> /* Initialize cached_rptr to 0 */
> ring->cached_rptr = 0;
>
> + if (!ring->ring_backup) {
> + ring->ring_backup = kvzalloc(ring->ring_size, GFP_KERNEL);
> + if (!ring->ring_backup)
> + return -ENOMEM;
> + }
> +
> /* Allocate ring buffer */
> if (ring->ring_obj == NULL) {
> r = amdgpu_bo_create_kernel(adev, ring->ring_size + ring->funcs->extra_dw, PAGE_SIZE,
> @@ -342,6 +371,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
> (void **)&ring->ring);
> if (r) {
> dev_err(adev->dev, "(%d) ring create failed\n", r);
> + kvfree(ring->ring_backup);
> return r;
> }
> amdgpu_ring_clear_ring(ring);
> @@ -385,6 +415,8 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
> amdgpu_bo_free_kernel(&ring->ring_obj,
> &ring->gpu_addr,
> (void **)&ring->ring);
> + kvfree(ring->ring_backup);
> + ring->ring_backup = NULL;
>
> dma_fence_put(ring->vmid_wait);
> ring->vmid_wait = NULL;
> @@ -753,3 +785,38 @@ bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring)
>
> return true;
> }
> +
> +void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring,
> + struct amdgpu_fence *guilty_fence)
> +{
> + /* Stop the scheduler to prevent anybody else from touching the ring buffer. */
> + drm_sched_wqueue_stop(&ring->sched);
> + /* back up the non-guilty commands */
> + amdgpu_ring_backup_unprocessed_commands(ring, guilty_fence);
> +}
> +
> +int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,
> + struct amdgpu_fence *guilty_fence)
> +{
> + unsigned int i;
> + int r;
> +
> + /* verify that the ring is functional */
> + r = amdgpu_ring_test_ring(ring);
> + if (r)
> + return r;
> +
> + /* signal the fence of the bad job */
> + if (guilty_fence)
> + amdgpu_fence_driver_guilty_force_completion(guilty_fence);
> + /* Re-emit the non-guilty commands */
> + if (ring->ring_backup_entries_to_copy) {
> + amdgpu_ring_alloc_reemit(ring, ring->ring_backup_entries_to_copy);
> + for (i = 0; i < ring->ring_backup_entries_to_copy; i++)
> + amdgpu_ring_write(ring, ring->ring_backup[i]);
> + amdgpu_ring_commit(ring);
> + }
> + /* Start the scheduler again */
> + drm_sched_wqueue_start(&ring->sched);
> + return 0;
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> index 784ba2ec354c7..309e7bb6001bd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
> @@ -118,6 +118,7 @@ struct amdgpu_fence_driver {
> /* sync_seq is protected by ring emission lock */
> uint32_t sync_seq;
> atomic_t last_seq;
> + u64 signalled_wptr;
> bool initialized;
> struct amdgpu_irq_src *irq_src;
> unsigned irq_type;
> @@ -141,6 +142,12 @@ struct amdgpu_fence {
> /* RB, DMA, etc. */
> struct amdgpu_ring *ring;
> ktime_t start_timestamp;
> +
> + /* wptr for the fence for resets */
> + u64 wptr;
> + /* fence context for resets */
> + u64 context;
> + uint32_t seq;
> };
>
> extern const struct drm_sched_backend_ops amdgpu_sched_ops;
> @@ -148,6 +155,8 @@ extern const struct drm_sched_backend_ops amdgpu_sched_ops;
> void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
> void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
> void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
> +void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence);
> +void amdgpu_fence_save_wptr(struct dma_fence *fence);
>
> int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
> int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
> @@ -284,6 +293,9 @@ struct amdgpu_ring {
>
> struct amdgpu_bo *ring_obj;
> uint32_t *ring;
> + /* backups for resets */
> + uint32_t *ring_backup;
> + unsigned int ring_backup_entries_to_copy;
> unsigned rptr_offs;
> u64 rptr_gpu_addr;
> volatile u32 *rptr_cpu_addr;
> @@ -550,4 +562,10 @@ int amdgpu_ib_pool_init(struct amdgpu_device *adev);
> void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
> int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
> bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring);
> +void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
> + struct amdgpu_fence *guilty_fence);
> +void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring,
> + struct amdgpu_fence *guilty_fence);
> +int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,
> + struct amdgpu_fence *guilty_fence);
> #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index f042372d9f2e6..ea9b0f050f799 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -765,6 +765,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
> bool cleaner_shader_needed = false;
> bool pasid_mapping_needed = false;
> struct dma_fence *fence = NULL;
> + struct amdgpu_fence *af;
> unsigned int patch;
> int r;
>
> @@ -830,6 +831,9 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
> r = amdgpu_fence_emit(ring, &fence, NULL, 0);
> if (r)
> return r;
> + /* this is part of the job's context */
> + af = container_of(fence, struct amdgpu_fence, base);
> + af->context = job->base.s_fence ? job->base.s_fence->finished.context : 0;
> }
>
> if (vm_flush_needed) {
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 01/33] drm/amdgpu: clean up sdma reset functions
2025-07-14 14:00 ` Lazar, Lijo
@ 2025-07-15 13:33 ` Alex Deucher
0 siblings, 0 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-15 13:33 UTC (permalink / raw)
To: Lazar, Lijo; +Cc: Alex Deucher, amd-gfx, christian.koenig, sasundar
On Mon, Jul 14, 2025 at 10:00 AM Lazar, Lijo <lijo.lazar@amd.com> wrote:
>
> Since the series has supported_reset across different ip blocks, isn't
> it better to move this to amdgpu_ip_block? Or, if this needs to be
> specific to be different type of rings within an IP block, keep a
> supported_reset flag per ring to do something like -
>
> amdgpu_ring_is_reset_supported(ring, reset_type) and call
> amdgpu_ring_reset()?
Yeah, I was thinking about that as a further cleanup once this lands.
Alex
>
> Thanks,
> Lijo
>
>
> On 7/12/2025 4:09 AM, Alex Deucher wrote:
> > Make them consistent and drop unneeded extra variables.
> >
> > Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> > ---
> > drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 14 +++++++++++---
> > drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 17 +++++++++++++----
> > drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 20 ++++++++------------
> > drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 20 ++++++++------------
> > 4 files changed, 40 insertions(+), 31 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> > index 5a1098bdd8256..999705e7b2641 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
> > @@ -1428,7 +1428,8 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block)
> > case IP_VERSION(5, 0, 0):
> > case IP_VERSION(5, 0, 2):
> > case IP_VERSION(5, 0, 5):
> > - if (adev->sdma.instance[0].fw_version >= 35)
> > + if ((adev->sdma.instance[0].fw_version >= 35) &&
> > + !amdgpu_sriov_vf(adev))
> > adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> > break;
> > default:
> > @@ -1544,11 +1545,18 @@ static int sdma_v5_0_reset_queue(struct amdgpu_ring *ring,
> > struct amdgpu_fence *timedout_fence)
> > {
> > struct amdgpu_device *adev = ring->adev;
> > - u32 inst_id = ring->me;
> > int r;
> >
> > + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> > + return -EOPNOTSUPP;
> > +
> > + if (ring->me >= adev->sdma.num_instances) {
> > + dev_err(adev->dev, "sdma instance not found\n");
> > + return -EINVAL;
> > + }
> > +
> > amdgpu_amdkfd_suspend(adev, true);
> > - r = amdgpu_sdma_reset_engine(adev, inst_id, false);
> > + r = amdgpu_sdma_reset_engine(adev, ring->me, false);
> > amdgpu_amdkfd_resume(adev, true);
> >
> > 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 6843c2c3d71f5..e542195972dd4 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
> > @@ -1347,11 +1347,13 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block)
> > case IP_VERSION(5, 2, 2):
> > case IP_VERSION(5, 2, 3):
> > case IP_VERSION(5, 2, 4):
> > - if (adev->sdma.instance[0].fw_version >= 76)
> > + if ((adev->sdma.instance[0].fw_version >= 76) &&
> > + !amdgpu_sriov_vf(adev))
> > adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> > break;
> > case IP_VERSION(5, 2, 5):
> > - if (adev->sdma.instance[0].fw_version >= 34)
> > + if ((adev->sdma.instance[0].fw_version >= 34) &&
> > + !amdgpu_sriov_vf(adev))
> > adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> > break;
> > default:
> > @@ -1457,11 +1459,18 @@ static int sdma_v5_2_reset_queue(struct amdgpu_ring *ring,
> > struct amdgpu_fence *timedout_fence)
> > {
> > struct amdgpu_device *adev = ring->adev;
> > - u32 inst_id = ring->me;
> > int r;
> >
> > + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> > + return -EOPNOTSUPP;
> > +
> > + if (ring->me >= adev->sdma.num_instances) {
> > + dev_err(adev->dev, "sdma instance not found\n");
> > + return -EINVAL;
> > + }
> > +
> > amdgpu_amdkfd_suspend(adev, true);
> > - r = amdgpu_sdma_reset_engine(adev, inst_id, false);
> > + r = amdgpu_sdma_reset_engine(adev, ring->me, false);
> > amdgpu_amdkfd_resume(adev, true);
> >
> > 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 d2effa5318176..c08e9a6cf6827 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
> > @@ -1355,7 +1355,8 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
> > case IP_VERSION(6, 0, 0):
> > case IP_VERSION(6, 0, 2):
> > case IP_VERSION(6, 0, 3):
> > - if (adev->sdma.instance[0].fw_version >= 21)
> > + if ((adev->sdma.instance[0].fw_version >= 21) &&
> > + !amdgpu_sriov_vf(adev))
> > adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> > break;
> > default:
> > @@ -1575,18 +1576,13 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
> > struct amdgpu_fence *timedout_fence)
> > {
> > struct amdgpu_device *adev = ring->adev;
> > - int i, r;
> > -
> > - if (amdgpu_sriov_vf(adev))
> > - return -EINVAL;
> > + int r;
> >
> > - for (i = 0; i < adev->sdma.num_instances; i++) {
> > - if (ring == &adev->sdma.instance[i].ring)
> > - break;
> > - }
> > + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> > + return -EOPNOTSUPP;
> >
> > - if (i == adev->sdma.num_instances) {
> > - DRM_ERROR("sdma instance not found\n");
> > + if (ring->me >= adev->sdma.num_instances) {
> > + dev_err(adev->dev, "sdma instance not found\n");
> > return -EINVAL;
> > }
> >
> > @@ -1596,7 +1592,7 @@ static int sdma_v6_0_reset_queue(struct amdgpu_ring *ring,
> > if (r)
> > return r;
> >
> > - r = sdma_v6_0_gfx_resume_instance(adev, i, true);
> > + r = sdma_v6_0_gfx_resume_instance(adev, ring->me, true);
> > if (r)
> > return r;
> > amdgpu_fence_driver_force_completion(ring);
> > diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> > index 99a080bad2a3d..ba1f3e3b6eb61 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
> > @@ -807,18 +807,13 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
> > struct amdgpu_fence *timedout_fence)
> > {
> > struct amdgpu_device *adev = ring->adev;
> > - int i, r;
> > -
> > - if (amdgpu_sriov_vf(adev))
> > - return -EINVAL;
> > + int r;
> >
> > - for (i = 0; i < adev->sdma.num_instances; i++) {
> > - if (ring == &adev->sdma.instance[i].ring)
> > - break;
> > - }
> > + if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
> > + return -EOPNOTSUPP;
> >
> > - if (i == adev->sdma.num_instances) {
> > - DRM_ERROR("sdma instance not found\n");
> > + if (ring->me >= adev->sdma.num_instances) {
> > + dev_err(adev->dev, "sdma instance not found\n");
> > return -EINVAL;
> > }
> >
> > @@ -828,7 +823,7 @@ static int sdma_v7_0_reset_queue(struct amdgpu_ring *ring,
> > if (r)
> > return r;
> >
> > - r = sdma_v7_0_gfx_resume_instance(adev, i, true);
> > + r = sdma_v7_0_gfx_resume_instance(adev, ring->me, true);
> > if (r)
> > return r;
> > amdgpu_fence_driver_force_completion(ring);
> > @@ -1346,7 +1341,8 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
> >
> > adev->sdma.supported_reset =
> > amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
> > - adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> > + if (!amdgpu_sriov_vf(adev))
> > + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
> >
> > r = amdgpu_sdma_sysfs_reset_mask_init(adev);
> > if (r)
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 10/33] drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
2025-07-11 22:40 ` [PATCH 10/33] drm/amdgpu/gfx9.4.3: " Alex Deucher
@ 2025-07-15 16:12 ` Alex Deucher
2025-07-16 2:46 ` Zhang, Jesse(Jie)
2025-07-16 8:44 ` Christian König
0 siblings, 2 replies; 48+ messages in thread
From: Alex Deucher @ 2025-07-15 16:12 UTC (permalink / raw)
To: Alex Deucher; +Cc: amd-gfx, christian.koenig, sasundar
Ping?
Alex
On Fri, Jul 11, 2025 at 6:48 PM Alex Deucher <alexander.deucher@amd.com> wrote:
>
> Re-emit the unprocessed state after resetting the queue.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 9 ++-------
> 1 file changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> index e2ff4b373a319..d80f1fb261d1e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> @@ -3569,7 +3569,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
> if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
> return -EINVAL;
>
> - drm_sched_wqueue_stop(&ring->sched);
> + amdgpu_ring_reset_helper_begin(ring, timedout_fence);
>
> spin_lock_irqsave(&kiq->ring_lock, flags);
>
> @@ -3626,12 +3626,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
> return r;
> }
>
> - r = amdgpu_ring_test_ring(ring);
> - if (r)
> - return r;
> - amdgpu_fence_driver_force_completion(ring);
> - drm_sched_wqueue_start(&ring->sched);
> - return 0;
> + return amdgpu_ring_reset_helper_end(ring, timedout_fence);
> }
>
> enum amdgpu_gfx_cp_ras_mem_id {
> --
> 2.50.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* RE: [PATCH 10/33] drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
2025-07-15 16:12 ` Alex Deucher
@ 2025-07-16 2:46 ` Zhang, Jesse(Jie)
2025-07-16 8:44 ` Christian König
1 sibling, 0 replies; 48+ messages in thread
From: Zhang, Jesse(Jie) @ 2025-07-16 2:46 UTC (permalink / raw)
To: Alex Deucher, Deucher, Alexander
Cc: amd-gfx@lists.freedesktop.org, Koenig, Christian,
Sundararaju, Sathishkumar
[AMD Official Use Only - AMD Internal Distribution Only]
this patch is Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
Sent: Wednesday, July 16, 2025 12:12 AM
To: Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: amd-gfx@lists.freedesktop.org; Koenig, Christian <Christian.Koenig@amd.com>; Sundararaju, Sathishkumar <Sathishkumar.Sundararaju@amd.com>
Subject: Re: [PATCH 10/33] drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
Ping?
Alex
On Fri, Jul 11, 2025 at 6:48 PM Alex Deucher <alexander.deucher@amd.com> wrote:
>
> Re-emit the unprocessed state after resetting the queue.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 9 ++-------
> 1 file changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> index e2ff4b373a319..d80f1fb261d1e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> @@ -3569,7 +3569,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
> if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
> return -EINVAL;
>
> - drm_sched_wqueue_stop(&ring->sched);
> + amdgpu_ring_reset_helper_begin(ring, timedout_fence);
>
> spin_lock_irqsave(&kiq->ring_lock, flags);
>
> @@ -3626,12 +3626,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
> return r;
> }
>
> - r = amdgpu_ring_test_ring(ring);
> - if (r)
> - return r;
> - amdgpu_fence_driver_force_completion(ring);
> - drm_sched_wqueue_start(&ring->sched);
> - return 0;
> + return amdgpu_ring_reset_helper_end(ring, timedout_fence);
> }
>
> enum amdgpu_gfx_cp_ras_mem_id {
> --
> 2.50.0
>
^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: [PATCH 10/33] drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
2025-07-15 16:12 ` Alex Deucher
2025-07-16 2:46 ` Zhang, Jesse(Jie)
@ 2025-07-16 8:44 ` Christian König
1 sibling, 0 replies; 48+ messages in thread
From: Christian König @ 2025-07-16 8:44 UTC (permalink / raw)
To: Alex Deucher, Alex Deucher; +Cc: amd-gfx, sasundar
Patches #9-#22 Reviewed-by: Christian König <christian.koenig@amd.com>
On 15.07.25 18:12, Alex Deucher wrote:
> Ping?
>
> Alex
>
> On Fri, Jul 11, 2025 at 6:48 PM Alex Deucher <alexander.deucher@amd.com> wrote:
>>
>> Re-emit the unprocessed state after resetting the queue.
>>
>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>> ---
>> drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 9 ++-------
>> 1 file changed, 2 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
>> index e2ff4b373a319..d80f1fb261d1e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
>> @@ -3569,7 +3569,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
>> if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
>> return -EINVAL;
>>
>> - drm_sched_wqueue_stop(&ring->sched);
>> + amdgpu_ring_reset_helper_begin(ring, timedout_fence);
>>
>> spin_lock_irqsave(&kiq->ring_lock, flags);
>>
>> @@ -3626,12 +3626,7 @@ static int gfx_v9_4_3_reset_kcq(struct amdgpu_ring *ring,
>> return r;
>> }
>>
>> - r = amdgpu_ring_test_ring(ring);
>> - if (r)
>> - return r;
>> - amdgpu_fence_driver_force_completion(ring);
>> - drm_sched_wqueue_start(&ring->sched);
>> - return 0;
>> + return amdgpu_ring_reset_helper_end(ring, timedout_fence);
>> }
>>
>> enum amdgpu_gfx_cp_ras_mem_id {
>> --
>> 2.50.0
>>
^ permalink raw reply [flat|nested] 48+ messages in thread
end of thread, other threads:[~2025-07-16 8:44 UTC | newest]
Thread overview: 48+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-11 22:39 [PATCH V15 00/33] Reset improvements Alex Deucher
2025-07-11 22:39 ` [PATCH 01/33] drm/amdgpu: clean up sdma reset functions Alex Deucher
2025-07-14 13:27 ` Christian König
2025-07-14 14:00 ` Lazar, Lijo
2025-07-15 13:33 ` Alex Deucher
2025-07-11 22:39 ` [PATCH 02/33] drm/amdgpu/jpeg2: add additional ring reset error checking Alex Deucher
2025-07-14 2:58 ` Sundararaju, Sathishkumar
2025-07-14 13:29 ` Christian König
2025-07-11 22:39 ` [PATCH 03/33] drm/amdgpu/jpeg3: " Alex Deucher
2025-07-14 3:00 ` Sundararaju, Sathishkumar
2025-07-11 22:39 ` [PATCH 04/33] drm/amdgpu/jpeg4: " Alex Deucher
2025-07-14 3:02 ` Sundararaju, Sathishkumar
2025-07-11 22:39 ` [PATCH 05/33] drm/amdgpu/vcn: don't enable per queue resets on SR-IOV Alex Deucher
2025-07-14 13:30 ` Christian König
2025-07-11 22:39 ` [PATCH 06/33] drm/amdgpu: clean up jpeg reset functions Alex Deucher
2025-07-14 3:24 ` Sundararaju, Sathishkumar
2025-07-14 13:36 ` Christian König
2025-07-11 22:39 ` [PATCH 07/33] drm/amdgpu: clean up GC " Alex Deucher
2025-07-11 22:39 ` [PATCH 08/33] drm/amdgpu: track ring state associated with a fence Alex Deucher
2025-07-14 14:02 ` Christian König
2025-07-11 22:40 ` [PATCH 09/33] drm/amdgpu/gfx9: re-emit unprocessed state on kcq reset Alex Deucher
2025-07-11 22:40 ` [PATCH 10/33] drm/amdgpu/gfx9.4.3: " Alex Deucher
2025-07-15 16:12 ` Alex Deucher
2025-07-16 2:46 ` Zhang, Jesse(Jie)
2025-07-16 8:44 ` Christian König
2025-07-11 22:40 ` [PATCH 11/33] drm/amdgpu/gfx10: re-emit unprocessed state on ring reset Alex Deucher
2025-07-11 22:40 ` [PATCH 12/33] drm/amdgpu/gfx11: " Alex Deucher
2025-07-11 22:40 ` [PATCH 13/33] drm/amdgpu/gfx12: " Alex Deucher
2025-07-11 22:40 ` [PATCH 14/33] drm/amdgpu/sdma5: " Alex Deucher
2025-07-11 22:40 ` [PATCH 15/33] drm/amdgpu/sdma5.2: " Alex Deucher
2025-07-11 22:40 ` [PATCH 16/33] drm/amdgpu/sdma6: " Alex Deucher
2025-07-11 22:40 ` [PATCH 17/33] drm/amdgpu/sdma7: " Alex Deucher
2025-07-11 22:40 ` [PATCH 18/33] drm/amdgpu/jpeg2: " Alex Deucher
2025-07-11 22:40 ` [PATCH 19/33] drm/amdgpu/jpeg2.5: " Alex Deucher
2025-07-11 22:40 ` [PATCH 20/33] drm/amdgpu/jpeg3: " Alex Deucher
2025-07-11 22:40 ` [PATCH 21/33] drm/amdgpu/jpeg4: " Alex Deucher
2025-07-11 22:40 ` [PATCH 22/33] drm/amdgpu/jpeg4.0.3: " Alex Deucher
2025-07-11 22:40 ` [PATCH 23/33] drm/amdgpu/jpeg4.0.5: add queue reset Alex Deucher
2025-07-11 22:40 ` [PATCH 24/33] drm/amdgpu/jpeg5: " Alex Deucher
2025-07-11 22:40 ` [PATCH 25/33] drm/amdgpu/jpeg5.0.1: re-emit unprocessed state on ring reset Alex Deucher
2025-07-11 22:40 ` [PATCH 26/33] drm/amdgpu/vcn4: " Alex Deucher
2025-07-11 22:40 ` [PATCH 27/33] drm/amdgpu/vcn4.0.3: " Alex Deucher
2025-07-11 22:40 ` [PATCH 28/33] drm/amdgpu/vcn4.0.5: " Alex Deucher
2025-07-11 22:40 ` [PATCH 29/33] drm/amdgpu/vcn5: " Alex Deucher
2025-07-11 22:40 ` [PATCH 30/33] drm/amdgpu/vcn: add a helper framework for engine resets Alex Deucher
2025-07-11 22:40 ` [PATCH 31/33] drm/amdgpu/vcn2: implement ring reset Alex Deucher
2025-07-11 22:40 ` [PATCH 32/33] drm/amdgpu/vcn2.5: " Alex Deucher
2025-07-11 22:40 ` [PATCH 33/33] drm/amdgpu/vcn3: " Alex Deucher
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.