On Tue, Aug 5, 2025 at 3:56 PM Sasha Levin <sas...@kernel.org> wrote: > > Restructure submit_lock_objects() to use a single loop with break > statements to fix objtool warning: > > drivers/gpu/drm/msm/msm.o: warning: objtool: submit_lock_objects+0x451: > sibling call from callable instruction with modified stack frame > > The drm_exec_until_all_locked() macro uses computed gotos internally > for its retry loop. Having return statements inside this macro, or > immediately after it in certain code paths, confuses objtool's static > analysis of stack frames, causing it to incorrectly flag tail call > optimizations.
Maybe we should instead just split out a separate submit_lock_objects_vmbind() and restore the error path 'goto error' instead of returning from within the loop? Ie. basically revert submit_lock_objects to the way it was before commit 92395af63a99 ("drm/msm: Add VM_BIND submitqueue"), and then move the rest into a new fxn (with 'goto error' instead of 'return ret'? In retrospect the vmbind case is kinda just shoehorned into the existing fxn. I can type up this version if you have better things to do. BR, -R > Fixes: 92395af63a99 ("drm/msm: Add VM_BIND submitqueue") > Signed-off-by: Sasha Levin <sas...@kernel.org> > --- > drivers/gpu/drm/msm/msm_gem_submit.c | 43 ++++++++++++---------------- > 1 file changed, 19 insertions(+), 24 deletions(-) > > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c > b/drivers/gpu/drm/msm/msm_gem_submit.c > index 5f8e939a5906..253347b6e328 100644 > --- a/drivers/gpu/drm/msm/msm_gem_submit.c > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c > @@ -276,46 +276,41 @@ static int submit_lock_objects(struct msm_gem_submit > *submit) > { > unsigned flags = DRM_EXEC_INTERRUPTIBLE_WAIT; > struct drm_exec *exec = &submit->exec; > - int ret; > + int ret = 0; > > - if (msm_context_is_vmbind(submit->queue->ctx)) { > + if (msm_context_is_vmbind(submit->queue->ctx)) > flags |= DRM_EXEC_IGNORE_DUPLICATES; > > - drm_exec_init(&submit->exec, flags, submit->nr_bos); > + drm_exec_init(&submit->exec, flags, submit->nr_bos); > > - drm_exec_until_all_locked (&submit->exec) { > + drm_exec_until_all_locked (&submit->exec) { > + if (msm_context_is_vmbind(submit->queue->ctx)) { > ret = drm_gpuvm_prepare_vm(submit->vm, exec, 1); > drm_exec_retry_on_contention(exec); > if (ret) > - return ret; > + break; > > ret = drm_gpuvm_prepare_objects(submit->vm, exec, 1); > drm_exec_retry_on_contention(exec); > if (ret) > - return ret; > - } > - > - return 0; > - } > - > - drm_exec_init(&submit->exec, flags, submit->nr_bos); > - > - drm_exec_until_all_locked (&submit->exec) { > - ret = drm_exec_lock_obj(&submit->exec, > - drm_gpuvm_resv_obj(submit->vm)); > - drm_exec_retry_on_contention(&submit->exec); > - if (ret) > - return ret; > - for (unsigned i = 0; i < submit->nr_bos; i++) { > - struct drm_gem_object *obj = submit->bos[i].obj; > - ret = drm_exec_prepare_obj(&submit->exec, obj, 1); > + break; > + } else { > + ret = drm_exec_lock_obj(&submit->exec, > + > drm_gpuvm_resv_obj(submit->vm)); > drm_exec_retry_on_contention(&submit->exec); > if (ret) > - return ret; > + break; > + for (unsigned i = 0; i < submit->nr_bos; i++) { > + struct drm_gem_object *obj = > submit->bos[i].obj; > + ret = drm_exec_prepare_obj(&submit->exec, > obj, 1); > + drm_exec_retry_on_contention(&submit->exec); > + if (ret) > + break; > + } > } > } > > - return 0; > + return ret; > } > > static int submit_fence_sync(struct msm_gem_submit *submit) > -- > 2.39.5 >