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]);
