amdgpu_device_ip_soft_reset() allocates an array of AMDGPU_MAX_RINGS
ring pointers on the stack. On 64-bit builds this consumes around 1280
bytes and triggers:

warning: stack frame size (1304) exceeds limit (1024)

Move the temporary ring pointer array to heap allocation to reduce stack
usage.

v2: (Alex)
- Avoid allocating memory in the reset path.
- Use a pre-allocated ring pointer array stored in amdgpu_device.

Fixes: a6319ac34a13 ("drm/amdgpu: Add IP block soft reset as a GPU recovery 
method")
Cc: Alex Deucher <[email protected]>
Cc: Timur Kristóf <[email protected]>
Signed-off-by: Srinivasan Shanmugam <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h    | 2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c | 8 +++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 4c3e933ff6d5..30053ca3b92b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -889,6 +889,8 @@ struct amdgpu_device {
        u64                             fence_context;
        unsigned                        num_rings;
        struct amdgpu_ring              *rings[AMDGPU_MAX_RINGS];
+       /* Temporary ring list used during IP block soft reset. */
+       struct amdgpu_ring              *ip_soft_reset_rings[AMDGPU_MAX_RINGS];
        struct dma_fence __rcu          *gang_submit;
        bool                            ib_pool_ready;
        struct amdgpu_sa_manager        ib_pools[AMDGPU_IB_POOL_MAX];
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c
index 65505bc50399..c8af5a158cea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c
@@ -524,7 +524,7 @@ 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_ring **rings = adev->ip_soft_reset_rings;
        struct amdgpu_ip_block *ip_block;
        enum amd_ip_block_type ip_type;
        u32 num_rings, ring_type_mask;
@@ -546,11 +546,13 @@ int amdgpu_device_ip_soft_reset(struct amdgpu_ring 
*guilty_ring,
        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(rings, num_rings, 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(rings, num_rings, guilty_ring,
+                                              r);
        amdgpu_device_unlock_reset_domain(adev->reset_domain);
 
        if (r) {
-- 
2.34.1

Reply via email to