Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/xe: Move _THIS_IP_ usage from xe_vm_create() to dedicated function

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 <nathan@kernel.org>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patch.msgid.link/20260121-xe-vm-fix-clang-goto-error-v1-1-7e121d81512e@kernel.org

authored by

Nathan Chancellor and committed by
Matthew Brost
91e0c2fe 60bfb8ba

+15 -9
+15 -9
drivers/gpu/drm/xe/xe_vm.c
··· 1474 1474 } 1475 1475 } 1476 1476 1477 + static void xe_vm_init_prove_locking(struct xe_device *xe, struct xe_vm *vm) 1478 + { 1479 + if (!IS_ENABLED(CONFIG_PROVE_LOCKING)) 1480 + return; 1481 + 1482 + fs_reclaim_acquire(GFP_KERNEL); 1483 + might_lock(&vm->exec_queues.lock); 1484 + fs_reclaim_release(GFP_KERNEL); 1485 + 1486 + down_read(&vm->exec_queues.lock); 1487 + might_lock(&xe_root_mmio_gt(xe)->uc.guc.ct.lock); 1488 + up_read(&vm->exec_queues.lock); 1489 + } 1490 + 1477 1491 struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags, struct xe_file *xef) 1478 1492 { 1479 1493 struct drm_gem_object *vm_resv_obj; ··· 1551 1537 vm->preempt.min_run_period_ms = xe->min_run_period_lr_ms; 1552 1538 1553 1539 init_rwsem(&vm->exec_queues.lock); 1554 - if (IS_ENABLED(CONFIG_PROVE_LOCKING)) { 1555 - fs_reclaim_acquire(GFP_KERNEL); 1556 - might_lock(&vm->exec_queues.lock); 1557 - fs_reclaim_release(GFP_KERNEL); 1558 - 1559 - down_read(&vm->exec_queues.lock); 1560 - might_lock(&xe_root_mmio_gt(xe)->uc.guc.ct.lock); 1561 - up_read(&vm->exec_queues.lock); 1562 - } 1540 + xe_vm_init_prove_locking(xe, vm); 1563 1541 1564 1542 for_each_tile(tile, xe, id) 1565 1543 xe_range_fence_tree_init(&vm->rftree[id]);