From 070e834f97756f2e592005b51d9a7d6104e3298d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Wed, 24 Jun 2026 09:38:28 +0200 Subject: [PATCH] drm/amdgpu: Simplify filtering rings during IP block soft reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of storing pointers to affected rings in an array, just iterate over all rings of the device and filter the affected rings by type using the type mask. This is done to save memory used by the array of affected rings which was sized AMDGPU_MAX_RINGS. Suggested-by: Srinivasan Shanmugam Signed-off-by: Timur Kristóf Reviewed-by: Tvrtko Ursulin Reviewed-by: Srinivasan Shanmugam # for the series Link: https://patch.msgid.link/20260624073829.40835-1-timur.kristof@gmail.com Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c | 30 ++------------ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 53 ++++++++++++++++-------- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 4 +- 3 files changed, 40 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c index 65505bc50399..99ed0b0d82e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c @@ -481,28 +481,6 @@ static u32 amdgpu_ring_mask_from_ip(const enum amd_ip_block_type ip_type) } } -/** - * amdgpu_filter_rings() - Filter rings according to a mask. - * - * @adev: amdgpu_device pointer - * @ring_type_mask: Mask of ring types you are looking for - * @out_rings: Array of rings which is going to be filled - * @out_num_rings: Number of rings which were filtered - */ -static void amdgpu_filter_rings(struct amdgpu_device *adev, const u32 ring_type_mask, - struct amdgpu_ring **out_rings, u32 *out_num_rings) -{ - u32 num_rings = 0; - int i; - - for (i = 0; i < adev->num_rings; ++i) { - if (BIT(adev->rings[i]->funcs->type) & ring_type_mask) - out_rings[num_rings++] = adev->rings[i]; - } - - *out_num_rings = num_rings; -} - /** * amdgpu_device_ip_soft_reset() - Perform a graceful soft reset on an IP block. * @@ -524,10 +502,9 @@ int amdgpu_device_ip_soft_reset(struct amdgpu_ring *guilty_ring, struct amdgpu_fence *guilty_fence) { struct amdgpu_device *adev = guilty_ring->adev; - struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; struct amdgpu_ip_block *ip_block; enum amd_ip_block_type ip_type; - u32 num_rings, ring_type_mask; + u32 ring_type_mask; int r; ip_type = amdgpu_ip_from_ring(guilty_ring->funcs->type); @@ -543,14 +520,13 @@ int amdgpu_device_ip_soft_reset(struct amdgpu_ring *guilty_ring, ip_block->version->funcs->name); ring_type_mask = amdgpu_ring_mask_from_ip(ip_type); - amdgpu_filter_rings(adev, ring_type_mask, rings, &num_rings); amdgpu_device_lock_reset_domain(adev->reset_domain); - amdgpu_multi_ring_reset_helper_begin(rings, num_rings, guilty_ring, guilty_fence); + amdgpu_multi_ring_reset_helper_begin(ring_type_mask, guilty_ring, guilty_fence); r = ip_block->version->funcs->soft_reset(ip_block); - r = amdgpu_multi_ring_reset_helper_end(rings, num_rings, guilty_ring, r); + r = amdgpu_multi_ring_reset_helper_end(ring_type_mask, guilty_ring, r); amdgpu_device_unlock_reset_domain(adev->reset_domain); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 3f78aa6ed82f..6e6aadba006c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -938,8 +938,7 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, /** * amdgpu_multi_ring_reset_helper_begin() - Prepare multiple rings for a reset. * - * @rings: Pointer to an array of amdgpu rings that are affected. - * @num_rings: Number of rings in the array. + * @ring_type_mask: Bitmask of affected ring types * @guilty_ring: The ring which is guilty of causing a reset. * @guilty_fence: The fence which didn't signal on the guilty ring. * @@ -958,7 +957,7 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, * After the reset is complete, the caller should then call * amdgpu_multi_ring_reset_helper_end() to restore the rings. */ -void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_rings, +void amdgpu_multi_ring_reset_helper_begin(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, struct amdgpu_fence *guilty_fence) { @@ -969,8 +968,11 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri int i; u32 t; - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; /* Don't accept new submissions on the ring. */ if (amdgpu_ring_sched_ready(ring) && !drm_sched_is_stopped(&ring->sched)) @@ -1003,8 +1005,11 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri rings_busy = false; /* Check if any of the non-guilty rings are busy */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; if (ring == guilty_ring) continue; @@ -1020,8 +1025,11 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri mdelay(10); } - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; /* * Find guilty fences, ie. the fences that didn't signal @@ -1045,8 +1053,7 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri /** * amdgpu_multi_ring_reset_helper_end() - Prepare multiple rings for a reset. * - * @rings: Pointer to an array of amdgpu rings that are affected. - * @num_rings: Number of rings in the array. + * @ring_type_mask: Bitmask of affected ring types * @guilty_ring: The ring which is guilty of causing a reset. * @ret: Return code from the reset function. * @@ -1058,7 +1065,7 @@ void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_ri * be called to restore some state, but it won't attempt to * fully restore the ring contents. */ -int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings, +int amdgpu_multi_ring_reset_helper_end(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, int ret) { struct amdgpu_device *adev = guilty_ring->adev; @@ -1066,8 +1073,11 @@ int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings int i, r; /* Set preempt condition, rings are now allowed to execute submissions */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; if (ring->funcs->init_cond_exec) amdgpu_ring_set_preempt_cond_exec(ring, true); @@ -1081,9 +1091,13 @@ int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings return ret; /* Restore contents of all rings */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; + + /* Restore contents of the ring */ r = amdgpu_ring_reset_helper_end(ring, ring->guilty_fence); if (r) { dev_err(adev->dev, @@ -1094,8 +1108,11 @@ int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings } /* Accept submissions on all rings again */ - for (i = 0; i < num_rings; ++i) { - ring = rings[i]; + for (i = 0; i < adev->num_rings; ++i) { + ring = adev->rings[i]; + + if (!(BIT(ring->funcs->type) & ring_type_mask)) + continue; if (!amdgpu_ring_sched_ready(ring)) continue; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index c272e0b028ad..9d3934b4f106 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -595,10 +595,10 @@ 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); -void amdgpu_multi_ring_reset_helper_begin(struct amdgpu_ring **rings, u32 num_rings, +void amdgpu_multi_ring_reset_helper_begin(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, struct amdgpu_fence *guilty_fence); -int amdgpu_multi_ring_reset_helper_end(struct amdgpu_ring **rings, u32 num_rings, +int amdgpu_multi_ring_reset_helper_end(const u32 ring_type_mask, struct amdgpu_ring *guilty_ring, int ret); bool amdgpu_ring_is_reset_type_supported(struct amdgpu_ring *ring, u32 reset_type);