On Wed, Jan 21, 2026 at 03:57:35PM -0700, Nathan Chancellor wrote:
> After commit a3866ce7b122 ("drm/xe: Add vm to exec queues association"),
> building for an architecture other than x86 (which defines its own
> _THIS_IP_) with clang fails with:
> 
>   drivers/gpu/drm/xe/xe_vm.c:1586:3: error: cannot jump from this indirect 
> goto statement to one of its possible targets
>    1586 |                 drm_exec_retry_on_contention(&exec);
>         |                 ^
>   include/drm/drm_exec.h:123:4: note: expanded from macro 
> 'drm_exec_retry_on_contention'
>     123 |                         goto *__drm_exec_retry_ptr;             \
>         |                         ^
>   drivers/gpu/drm/xe/xe_vm.c:1542:3: note: possible target of indirect goto 
> statement
>    1542 |                 might_lock(&vm->exec_queues.lock);
>         |                 ^
>   include/linux/lockdep.h:553:33: note: expanded from macro 'might_lock'
>     553 |         lock_release(&(lock)->dep_map, _THIS_IP_);                  
>     \
>         |                                        ^
>   include/linux/instruction_pointer.h:10:41: note: expanded from macro 
> '_THIS_IP_'
>      10 | #define _THIS_IP_  ({ __label__ __here; __here: (unsigned 
> long)&&__here; })
>         |                                         ^
>   drivers/gpu/drm/xe/xe_vm.c:1583:2: note: jump exits scope of variable with 
> __attribute__((cleanup))
>    1583 |         xe_validation_guard(&ctx, &xe->val, &exec, (struct 
> xe_val_flags) {.interruptible = true},
>         |         ^
>   drivers/gpu/drm/xe/xe_validation.h:189:2: note: expanded from macro 
> 'xe_validation_guard'
>     189 |         scoped_guard(xe_validation, _ctx, _val, _exec, _flags, 
> &_ret) \
>         |         ^
>   include/linux/cleanup.h:442:2: note: expanded from macro 'scoped_guard'
>     442 |         __scoped_guard(_name, __UNIQUE_ID(label), args)
>         |         ^
>   include/linux/cleanup.h:433:20: note: expanded from macro '__scoped_guard'
>     433 |         for (CLASS(_name, scope)(args);                             
>     \
>         |                           ^
>   drivers/gpu/drm/xe/xe_vm.c:1542:3: note: jump enters a statement expression
>    1542 |                 might_lock(&vm->exec_queues.lock);
>         |                 ^
>   include/linux/lockdep.h:553:33: note: expanded from macro 'might_lock'
>     553 |         lock_release(&(lock)->dep_map, _THIS_IP_);                  
>     \
>         |                                        ^
>   include/linux/instruction_pointer.h:10:20: note: expanded from macro 
> '_THIS_IP_'
>      10 | #define _THIS_IP_  ({ __label__ __here; __here: (unsigned 
> long)&&__here; })
>         |                    ^
> 
> While this is a false positive error because __drm_exec_retry_ptr is
> only ever assigned the label in drm_exec_until_all_locked() (thus it can
> never jump over the cleanup variable), this error is not unreasonable in
> general because the only supported use case for taking the address of a
> label is computed gotos [1]. The kernel's use of the address of a label
> in _THIS_IP_ is considered problematic by both GCC [2][3] and clang [4]
> but they need to provide something equivalent before they can break this
> use case.
> 
> Hide the usage of _THIS_IP_ by moving the CONFIG_PROVE_LOCKING if
> statement to its own function, avoiding the error. This is similar to
> commit 187e16f69de2 ("drm/xe: Work around clang multiple goto-label
> error") but with the sources of _THIS_IP_.
> 
> Fixes: a3866ce7b122 ("drm/xe: Add vm to exec queues association")
> Link: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html [1]
> Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44298 [2]
> Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120071 [3]
> Link: https://github.com/llvm/llvm-project/issues/138272 [4]
> Signed-off-by: Nathan Chancellor <[email protected]>

Reviewed-by: Matthew Brost <[email protected]>

> ---
>  drivers/gpu/drm/xe/xe_vm.c | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index f7bb21ac1987..293b92ed2fdd 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -1474,6 +1474,20 @@ static void xe_vm_pt_destroy(struct xe_vm *vm)
>       }
>  }
>  
> +static void xe_vm_init_prove_locking(struct xe_device *xe, struct xe_vm *vm)
> +{
> +     if (!IS_ENABLED(CONFIG_PROVE_LOCKING))
> +             return;
> +
> +     fs_reclaim_acquire(GFP_KERNEL);
> +     might_lock(&vm->exec_queues.lock);
> +     fs_reclaim_release(GFP_KERNEL);
> +
> +     down_read(&vm->exec_queues.lock);
> +     might_lock(&xe_root_mmio_gt(xe)->uc.guc.ct.lock);
> +     up_read(&vm->exec_queues.lock);
> +}
> +
>  struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags, struct xe_file 
> *xef)
>  {
>       struct drm_gem_object *vm_resv_obj;
> @@ -1537,15 +1551,7 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 
> flags, struct xe_file *xef)
>               vm->preempt.min_run_period_ms = xe->min_run_period_lr_ms;
>  
>       init_rwsem(&vm->exec_queues.lock);
> -     if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
> -             fs_reclaim_acquire(GFP_KERNEL);
> -             might_lock(&vm->exec_queues.lock);
> -             fs_reclaim_release(GFP_KERNEL);
> -
> -             down_read(&vm->exec_queues.lock);
> -             might_lock(&xe_root_mmio_gt(xe)->uc.guc.ct.lock);
> -             up_read(&vm->exec_queues.lock);
> -     }
> +     xe_vm_init_prove_locking(xe, vm);
>  
>       for_each_tile(tile, xe, id)
>               xe_range_fence_tree_init(&vm->rftree[id]);
> 
> ---
> base-commit: 9dd1048bca4fe2aa67c7a286bafb3947537adedb
> change-id: 20260121-xe-vm-fix-clang-goto-error-b23c9d6bbf68
> 
> Best regards,
> --  
> Nathan Chancellor <[email protected]>
> 

Reply via email to