From: Yunseong Kim <ysk@kzalloc.com>
To: Byungchul Park <byungchul@sk.com>, Nathan Chancellor <nathan@kernel.org>
Cc: kernel_team@skhynix.com, torvalds@linux-foundation.org,
gregkh@linuxfoundation.org, kernel-team@lge.com,
linux-mm@kvack.org, minchan@kernel.org, harry.yoo@oracle.com,
gwan-gyeong.mun@intel.com, max.byungchul.park@gmail.com,
"Peter Zijlstra" <peterz@infradead.org>,
"Ingo Molnar" <mingo@redhat.com>, "Will Deacon" <will@kernel.org>,
boqun.feng@gmail.com, "Waiman Long" <longman@redhat.com>,
yunseong.kim@ericsson.com, yeoreum.yun@arm.com,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Matthew Brost" <matthew.brost@intel.com>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
"Nick Desaulniers" <nick.desaulniers+lkml@gmail.com>,
"Bill Wendling" <morbo@google.com>,
"Justin Stitt" <justinstitt@google.com>,
"Stuart Summers" <stuart.summers@intel.com>,
"Nirmoy Das" <nirmoy.das@intel.com>,
intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
llvm@lists.linux.dev, patches@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v18 20/42] dept: apply timeout consideration to dma fence wait
Date: Thu, 12 Mar 2026 01:38:19 +0900 [thread overview]
Message-ID: <02e5b102-d8e2-4fbf-8818-55863e425c96@kzalloc.com> (raw)
In-Reply-To: <20251205071855.72743-21-byungchul@sk.com>
Hi all,
I have been investigating repeated Clang build failures of the form:
"cannot jump from this indirect goto statement to one of its possible targets"
"note: jump enters a statement expression"
triggered by the interaction between drm_exec's indirect goto
(goto *__drm_exec_retry_ptr) and diagnostic macros such as _THIS_IP_,
LOCKDEP, and DEPT.
Link: https://lore.kernel.org/all/?q=b%3A%22error%3A+cannot+jump+from+this+indirect+goto+statement+to+one+of+its+possible+targets%22
Notably, failures on DEPT are currently observed on arm64 builds.
On arm64, _THIS_IP_ uses the common implementation based on a GNU C
statement expression with an address-taken label, relying on compiler
optimization rather than an architecture-specific definition. This makes
arm64 particularly sensitive to Clang's treatment of address-taken labels
and indirect goto targets.
This is also not limited to a single driver. I have observed the same
failure pattern in multiple DRM drivers when DEPT instrumentation is in
the call path (e.g. dma_fence_wait() -> sdt_might_sleep_start_timeout()
-> _THIS_IP_), including msm and others.
$ clang --version
clang version 23.0.0git (https://github.com/llvm/llvm-project.git
1ff1e5f10a5c765b4cf1344c4964604dcd09fef3)
drivers/gpu/drm/msm/msm_gem_vma.c:919:3: error: cannot jump from this
indirect goto statement to one of its possible targets
919 | 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/msm/msm_gem_vma.c:909:3: note: possible target of
indirect goto statement
909 | dma_fence_wait(vm->last_fence, false);
| ^
./include/linux/dma-fence.h:677:2: note: expanded from macro 'dma_fence_wait'
677 | sdt_might_sleep_start_timeout(NULL,
MAX_SCHEDULE_TIMEOUT); \
| ^
./include/linux/dept_sdt.h:46:31: note: expanded from macro
'sdt_might_sleep_start_timeout'
46 | unsigned long __this_ip__ = _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/msm/msm_gem_vma.c:909:3: note: jump enters a statement
expression
./include/linux/dma-fence.h:677:2: note: expanded from macro 'dma_fence_wait'
677 | sdt_might_sleep_start_timeout(NULL,
MAX_SCHEDULE_TIMEOUT); \
| ^
./include/linux/dept_sdt.h:46:31: note: expanded from macro
'sdt_might_sleep_start_timeout'
46 | unsigned long __this_ip__ = _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; })
| ^
drivers/gpu/drm/msm/msm_gem_vma.c:909:3: note: jump enters a statement
expression
./include/linux/dma-fence.h:673:38: note: expanded from macro 'dma_fence_wait'
673 | #define dma_fence_wait(f, intr)
\
|
^
drivers/gpu/drm/msm/msm_gem_vma.c:933:5: error: cannot jump from this
indirect goto statement to one of its possible targets
933 | 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/msm/msm_gem_vma.c:909:3: note: possible target of
indirect goto statement
909 | dma_fence_wait(vm->last_fence, false);
| ^
./include/linux/dma-fence.h:677:2: note: expanded from macro 'dma_fence_wait'
677 | sdt_might_sleep_start_timeout(NULL,
MAX_SCHEDULE_TIMEOUT); \
| ^
./include/linux/dept_sdt.h:46:31: note: expanded from macro
'sdt_might_sleep_start_timeout'
46 | unsigned long __this_ip__ = _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/msm/msm_gem_vma.c:909:3: note: jump enters a statement
expression
./include/linux/dma-fence.h:677:2: note: expanded from macro 'dma_fence_wait'
677 | sdt_might_sleep_start_timeout(NULL,
MAX_SCHEDULE_TIMEOUT); \
| ^
./include/linux/dept_sdt.h:46:31: note: expanded from macro
'sdt_might_sleep_start_timeout'
46 | unsigned long __this_ip__ = _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; })
| ^
drivers/gpu/drm/msm/msm_gem_vma.c:909:3: note: jump enters a statement
expression
./include/linux/dma-fence.h:673:38: note: expanded from macro 'dma_fence_wait'
673 | #define dma_fence_wait(f, intr)
\
|
^
I was able to find the pattern of the kernel source code that uses this pattern:
$ git grep -n 'goto \*' | grep ';' | grep -v "\*/" | \
grep -Ev "(\*[[:space:]]+goto|_goto.*\*\);)"
drivers/gpu/drm/xe/xe_validation.h:149: goto *__drm_exec_retry_ptr; \
drivers/misc/lkdtm/cfi.c:129: goto *labels[1];
drivers/misc/lkdtm/cfi.c:131: goto *labels[2];
drivers/misc/lkdtm/cfi.c:133: goto *labels[3];
drivers/misc/lkdtm/cfi.c:135: goto *labels[4];
include/drm/drm_exec.h:123: goto *__drm_exec_retry_ptr; \
kernel/bpf/core.c:1776: goto *jumptable[insn->code];
scripts/gcc-plugins/gcc-common.h:368: return as_a<ggoto *>(stmt);
scripts/gcc-plugins/gcc-common.h:373: return as_a<const ggoto *>(stmt);
tools/testing/selftests/bpf/progs/bpf_gotox.c:219: goto *jt[ctx->x & 0xff];
tools/testing/selftests/bpf/progs/bpf_gotox.c:261: goto *jt1[a];
tools/testing/selftests/bpf/progs/bpf_gotox.c:263: goto *jt2[b];
tools/testing/selftests/bpf/progs/bpf_gotox.c:284: goto *jt[a];
tools/testing/selftests/bpf/progs/bpf_gotox.c:287: goto *jt[a + b];
I understand that Clang's behavior here is intentional and conservative:
any address-taken label in the same function is treated as a potential
indirect goto target, and jumping into a statement expression is diagnosed
to avoid semantic issues. This aligns with:
- [Clang] Diagnose jumps into statement expressions (D154696)
https://reviews.llvm.org/D154696
At the same time, the kernel is not using _THIS_IP_ for control flow.
The label address is used purely for diagnostics (lockdep/DEPT attribution).
However, as discussed in:
- LLVM Issue #138272: Add builtin/intrinsic to get current instruction pointer
https://github.com/llvm/llvm-project/issues/138272
using blockaddress (&&label) purely to obtain an instruction pointer is
problematic in LLVM's model, since blockaddress has defined behavior only
when used with indirectbr or for null comparisons.
Similar issues have also been observed in other contexts where indirect
goto interacts with address-taken labels, e.g.:
- LLVM Issue #28019: Wrong 'cannot jump from this indirect goto statement'
https://github.com/llvm/llvm-project/issues/28019
Given this, I think there is three possible directions:
1) Continue per-callsite structural workarounds
Keep separating indirect goto usage from any code that expands _THIS_IP_
(e.g. moving PROVE_LOCKING / DEPT paths into helper functions). This avoids
the diagnostic but requires ongoing refactoring and does not scale well as
similar patterns reappear across drivers.
2) Introduce a compiler-supported alternative to _THIS_IP_
As discussed in LLVM Issue #138272, a dedicated builtin or intrinsic to
obtain a best-effort instruction pointer for diagnostics would allow the
kernel to avoid address-taken labels entirely and eliminate this class of
conflicts.
3) DRM/drm_exec-scoped refactoring as a pragmatic middle ground
Since drm_exec is the common convergence point where indirect goto and
DEPT/LOCKDEP instrumentation can meet in the same function across multiple
DRM drivers, we could refactor the drm_exec usage patterns (or provide a
recommended wrapper pattern) to structurally separate the retry/indirect-goto
region from instrumentation that expands _THIS_IP_. This would avoid
kernel-wide churn while addressing the recurring failures in DRM drivers.
I am not proposing to weaken Clang's diagnostics. Rather, I would like
feedback on whether option (3) is considered an acceptable short- to
medium-term approach, and whether option (2) is the preferred long-term
direction from the compiler side.
Any guidance from the LOCKDEP and kernel LLVM maintainers on the preferred
path forward would be greatly appreciated.
On 12/5/25 4:18 PM, Byungchul Park wrote:
> Now that CONFIG_DEPT_AGGRESSIVE_TIMEOUT_WAIT was introduced, apply the
> consideration to dma fence wait.
>
> Signed-off-by: Byungchul Park <byungchul@sk.com>
> ---
> drivers/dma-buf/dma-fence.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
> index b313bb59dc9c..f2cc7068af65 100644
> --- a/drivers/dma-buf/dma-fence.c
> +++ b/drivers/dma-buf/dma-fence.c
> @@ -799,7 +799,7 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
> cb.task = current;
> list_add(&cb.base.node, &fence->cb_list);
>
> - sdt_might_sleep_start(NULL);
> + sdt_might_sleep_start_timeout(NULL, timeout);
> while (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) && ret > 0) {
> if (intr)
> __set_current_state(TASK_INTERRUPTIBLE);
> @@ -903,7 +903,7 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
> }
> }
>
> - sdt_might_sleep_start(NULL);
> + sdt_might_sleep_start_timeout(NULL, timeout);
> while (ret > 0) {
> if (intr)
> set_current_state(TASK_INTERRUPTIBLE);
Best regards,
Yuseong
next prev parent reply other threads:[~2026-03-11 16:38 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-05 7:18 [PATCH v18 00/42] DEPT(DEPendency Tracker) Byungchul Park
2025-12-05 7:18 ` [PATCH v18 01/42] dept: implement " Byungchul Park
2025-12-05 7:18 ` [PATCH v18 02/42] dept: add single event dependency tracker APIs Byungchul Park
2025-12-05 7:18 ` [PATCH v18 03/42] dept: add lock " Byungchul Park
2025-12-05 7:18 ` [PATCH v18 04/42] dept: tie to lockdep and IRQ tracing Byungchul Park
2025-12-05 7:18 ` [PATCH v18 05/42] dept: add proc knobs to show stats and dependency graph Byungchul Park
2025-12-05 7:18 ` [PATCH v18 06/42] dept: distinguish each kernel context from another Byungchul Park
2025-12-05 7:18 ` [PATCH v18 07/42] dept: distinguish each work " Byungchul Park
2025-12-05 7:18 ` [PATCH v18 08/42] dept: add a mechanism to refill the internal memory pools on running out Byungchul Park
2025-12-05 7:18 ` [PATCH v18 09/42] dept: record the latest one out of consecutive waits of the same class Byungchul Park
2025-12-05 7:18 ` [PATCH v18 10/42] dept: apply sdt_might_sleep_{start,end}() to wait_for_completion()/complete() Byungchul Park
2025-12-05 7:18 ` [PATCH v18 11/42] dept: apply sdt_might_sleep_{start,end}() to swait Byungchul Park
2025-12-05 7:18 ` [PATCH v18 12/42] dept: apply sdt_might_sleep_{start,end}() to waitqueue wait Byungchul Park
2025-12-05 7:18 ` [PATCH v18 13/42] dept: apply sdt_might_sleep_{start,end}() to hashed-waitqueue wait Byungchul Park
2025-12-05 7:18 ` [PATCH v18 14/42] dept: apply sdt_might_sleep_{start,end}() to dma fence Byungchul Park
2025-12-05 7:18 ` [PATCH v18 15/42] dept: track timeout waits separately with a new Kconfig Byungchul Park
2025-12-05 7:18 ` [PATCH v18 16/42] dept: apply timeout consideration to wait_for_completion()/complete() Byungchul Park
2025-12-05 7:18 ` [PATCH v18 17/42] dept: apply timeout consideration to swait Byungchul Park
2025-12-05 7:18 ` [PATCH v18 18/42] dept: apply timeout consideration to waitqueue wait Byungchul Park
2025-12-05 7:18 ` [PATCH v18 19/42] dept: apply timeout consideration to hashed-waitqueue wait Byungchul Park
2025-12-05 7:18 ` [PATCH v18 20/42] dept: apply timeout consideration to dma fence wait Byungchul Park
2026-03-11 16:38 ` Yunseong Kim [this message]
2026-03-12 1:44 ` Byungchul Park
2025-12-05 7:18 ` [PATCH v18 21/42] dept: make dept able to work with an external wgen Byungchul Park
2025-12-05 7:18 ` [PATCH v18 22/42] dept: track PG_locked with dept Byungchul Park
2025-12-05 7:18 ` [PATCH v18 23/42] dept: print staged wait's stacktrace on report Byungchul Park
2025-12-05 7:18 ` [PATCH v18 24/42] locking/lockdep: prevent various lockdep assertions when lockdep_off()'ed Byungchul Park
2025-12-05 7:18 ` [PATCH v18 25/42] dept: add documents for dept Byungchul Park
2025-12-06 0:25 ` Bagas Sanjaya
2025-12-15 4:22 ` Byungchul Park
2025-12-05 7:18 ` [PATCH v18 26/42] cpu/hotplug: use a weaker annotation in AP thread Byungchul Park
2025-12-05 7:18 ` [PATCH v18 27/42] dept: assign dept map to mmu notifier invalidation synchronization Byungchul Park
2025-12-05 7:18 ` [PATCH v18 28/42] dept: assign unique dept_key to each distinct dma fence caller Byungchul Park
2025-12-05 7:18 ` [PATCH v18 29/42] dept: make dept aware of lockdep_set_lock_cmp_fn() annotation Byungchul Park
2025-12-05 7:18 ` [PATCH v18 30/42] dept: make dept stop from working on debug_locks_off() Byungchul Park
2025-12-05 7:18 ` [PATCH v18 31/42] dept: assign unique dept_key to each distinct wait_for_completion() caller Byungchul Park
2026-02-15 6:42 ` Dirk Behme
2026-02-23 0:32 ` Byungchul Park
2025-12-05 7:18 ` [PATCH v18 32/42] completion, dept: introduce init_completion_dmap() API Byungchul Park
2025-12-05 7:18 ` [PATCH v18 33/42] dept: introduce a new type of dependency tracking between multi event sites Byungchul Park
2025-12-05 7:18 ` [PATCH v18 34/42] dept: add module support for struct dept_event_site and dept_event_site_dep Byungchul Park
2026-01-07 12:19 ` Petr Pavlu
2026-02-13 5:50 ` Byungchul Park
2026-02-18 15:08 ` Petr Pavlu
2026-02-23 0:33 ` Byungchul Park
2025-12-05 7:18 ` [PATCH v18 35/42] dept: introduce event_site() to disable event tracking if it's recoverable Byungchul Park
2025-12-05 7:18 ` [PATCH v18 36/42] dept: implement a basic unit test for dept Byungchul Park
2025-12-05 7:18 ` [PATCH v18 37/42] dept: call dept_hardirqs_off() in local_irq_*() regardless of irq state Byungchul Park
2025-12-05 7:18 ` [PATCH v18 38/42] rcu/update: fix same dept key collision between various types of RCU Byungchul Park
2025-12-05 7:18 ` [PATCH v18 39/42] dept: introduce APIs to set page usage and use subclasses_evt for the usage Byungchul Park
2025-12-05 7:18 ` [PATCH v18 40/42] dept: track PG_writeback with dept Byungchul Park
2025-12-05 7:18 ` [PATCH v18 41/42] SUNRPC: relocate struct rcu_head to the first field of struct rpc_xprt Byungchul Park
2025-12-05 9:27 ` Jeff Layton
2025-12-15 5:15 ` Byungchul Park
2025-12-05 7:18 ` [PATCH v18 42/42] mm: percpu: increase PERCPU_DYNAMIC_SIZE_SHIFT on DEPT and large PAGE_SIZE Byungchul Park
2026-03-17 4:44 ` [PATCH v18 00/42] DEPT(DEPendency Tracker) Byungchul Park
2026-03-18 5:58 ` Yunseong Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=02e5b102-d8e2-4fbf-8818-55863e425c96@kzalloc.com \
--to=ysk@kzalloc.com \
--cc=airlied@gmail.com \
--cc=boqun.feng@gmail.com \
--cc=byungchul@sk.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gregkh@linuxfoundation.org \
--cc=gwan-gyeong.mun@intel.com \
--cc=harry.yoo@oracle.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=justinstitt@google.com \
--cc=kernel-team@lge.com \
--cc=kernel_team@skhynix.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=llvm@lists.linux.dev \
--cc=longman@redhat.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=matthew.brost@intel.com \
--cc=max.byungchul.park@gmail.com \
--cc=minchan@kernel.org \
--cc=mingo@redhat.com \
--cc=morbo@google.com \
--cc=mripard@kernel.org \
--cc=nathan@kernel.org \
--cc=nick.desaulniers+lkml@gmail.com \
--cc=nirmoy.das@intel.com \
--cc=patches@lists.linux.dev \
--cc=peterz@infradead.org \
--cc=rodrigo.vivi@intel.com \
--cc=simona@ffwll.ch \
--cc=stuart.summers@intel.com \
--cc=thomas.hellstrom@linux.intel.com \
--cc=torvalds@linux-foundation.org \
--cc=tzimmermann@suse.de \
--cc=will@kernel.org \
--cc=yeoreum.yun@arm.com \
--cc=yunseong.kim@ericsson.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox