On 12/5/25 13:14, Srinivasan Shanmugam wrote:
> Checked all the local variables in the function. Most of them are small
> numbers or pointers and use very little stack space. The only large item
> stored on the stack is struct drm_exec, and this is what pushes the
> stack size over the limit.
> 
> To fix this, struct drm_exec is now allocated with kmalloc() instead of
> being placed on the stack. All call sites were updated to use a pointer,
> and all cleanup paths now call drm_exec_fini() and kfree() to release
> the memory safely.
> 
> This reduces stack usage, fixes the below:
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c:642:5: warning: stack frame 
> size (1176) exceeds limit (1024) in 'amdgpu_userq_wait_ioctl' 
> [-Wframe-larger-than]

Mhm, I'm really wondering how that happens? The drm_exec object is 
intentionally so small that it can be allocated on the stack.

What's going on here?

Regards,
Christian.

> 
> Cc: Alex Deucher <[email protected]>
> Cc: Christian König <[email protected]>
> Signed-off-by: Srinivasan Shanmugam <[email protected]>
> ---
>  .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c   | 40 +++++++++++--------
>  1 file changed, 23 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> index 25f178536469..b5839acde14a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> @@ -654,7 +654,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void 
> *data,
>       struct dma_fence **fences = NULL;
>       u16 num_points, num_fences = 0;
>       int r, i, rentry, wentry, cnt;
> -     struct drm_exec exec;
> +     struct drm_exec *exec = NULL;
>  
>       num_read_bo_handles = wait_info->num_bo_read_handles;
>       bo_handles_read = 
> memdup_user(u64_to_user_ptr(wait_info->bo_read_handles),
> @@ -721,24 +721,26 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, 
> void *data,
>               }
>       }
>  
> -     drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
> +     exec = kmalloc(sizeof(*exec), GFP_KERNEL);
> +     if (!exec) {
> +             r = -ENOMEM;
> +             goto put_gobj_write;
> +     }
> +
> +     drm_exec_init(exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
>                     (num_read_bo_handles + num_write_bo_handles));
>  
>       /* Lock all BOs with retry handling */
> -     drm_exec_until_all_locked(&exec) {
> -             r = drm_exec_prepare_array(&exec, gobj_read, 
> num_read_bo_handles, 1);
> -             drm_exec_retry_on_contention(&exec);
> -             if (r) {
> -                     drm_exec_fini(&exec);
> -                     goto put_gobj_write;
> -             }
> +     drm_exec_until_all_locked(exec) {
> +             r = drm_exec_prepare_array(exec, gobj_read, 
> num_read_bo_handles, 1);
> +             drm_exec_retry_on_contention(exec);
> +             if (r)
> +                     goto exec_fini;
>  
> -             r = drm_exec_prepare_array(&exec, gobj_write, 
> num_write_bo_handles, 1);
> -             drm_exec_retry_on_contention(&exec);
> -             if (r) {
> -                     drm_exec_fini(&exec);
> -                     goto put_gobj_write;
> -             }
> +             r = drm_exec_prepare_array(exec, gobj_write, 
> num_write_bo_handles, 1);
> +             drm_exec_retry_on_contention(exec);
> +             if (r)
> +                     goto exec_fini;
>       }
>  
>       if (!wait_info->num_fences) {
> @@ -966,7 +968,8 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void 
> *data,
>               kfree(fence_info);
>       }
>  
> -     drm_exec_fini(&exec);
> +     drm_exec_fini(exec);
> +     kfree(exec);
>       for (i = 0; i < num_read_bo_handles; i++)
>               drm_gem_object_put(gobj_read[i]);
>       kfree(gobj_read);
> @@ -990,7 +993,10 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void 
> *data,
>  free_fence_info:
>       kfree(fence_info);
>  exec_fini:
> -     drm_exec_fini(&exec);
> +     if (exec) {
> +             drm_exec_fini(exec);
> +             kfree(exec);
> +     }
>  put_gobj_write:
>       while (wentry-- > 0)
>               drm_gem_object_put(gobj_write[wentry]);

Reply via email to