* [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* 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 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 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
* [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* 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 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
* [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* 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
* [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* 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
* [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* 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
* [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* 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 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
* [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* 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
* [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* 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
* [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