[<prev] [next>] [day] [month] [year] [list]
Message-ID: <693e0aa4-34cd-4cb8-88a2-2cbacbe99a42@kzalloc.com>
Date: Sun, 1 Jun 2025 19:10:32 +0900
From: Yunseong Kim <ysk@...lloc.com>
To: Aaron Ballman <aaron@...selapp.com>, Reid Kleckner <reid@...m.org>,
David Greene <david.greene@...el.com>,
Christian König <christian.koenig@....com>
Cc: Boris Brezillon <boris.brezillon@...labora.com>,
Danilo Krummrich <dakr@...hat.com>, Alex Deucher
<alexander.deucher@....com>, llvm-dev <llvm-dev@...ts.llvm.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Byungchul Park <byungchul@...com>,
"max.byungchul.park@...il.com" <max.byungchul.park@...il.com>,
Yeo Reum Yun <YeoReum.Yun@....com>, Yunseong Kim
<yunseong.kim@...csson.com>,
"kernel_team@...ynix.com" <kernel_team@...ynix.com>
Subject: Clang compilation error in Linux kernel with DEPT patch: cannot jump
from this indirect goto statement to one of its possible targets
Dear LLVM/Clang Developers,
I'm encountering a compilation error when building the Linux kernel with Clang
(clang version 20.1.3 (Fedora 20.1.3-1.fc42)) after applying a DEPT
(Dynamic Execution Path Tracing) patch.
Link: https://lore.kernel.org/all/20250519091826.19752-1-byungchul@sk.com/
The error occurs in “drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c” and is related to
an indirect ‘goto’ jumping into a statement expression. This issue does not
occur when compiling with GCC(gcc version 15.1.1 20250425
(Red Hat 15.1.1-1)).
Problem Description:
The core error message is:
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c:1372:3: error: cannot jump from this indirect goto statement to one of its possible targets
1372 | drm_exec_retry_on_contention(&exec);
| ^
Followed by notes showing the expansion:
./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/amd/amdgpu/amdgpu_mes.c:1399:2: note: possible target of indirect goto statement
1399 | dma_fence_wait(fence, false);
| ^
./include/linux/dma-fence.h:679:2: note: expanded from macro 'dma_fence_wait'
679 | sdt_might_sleep_start_timeout(NULL, MAX_SCHEDULE_TIMEOUT); \
| ^
./include/linux/dept_sdt.h:45:45: note: expanded from macro 'sdt_might_sleep_start_timeout'
45 | dept_stage_wait(__m, __m ? NULL : &__key, _THIS_IP_, __func__, t);\
| ^
./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/amd/amdgpu/amdgpu_mes.c:1399:2: note: jump enters a statement expression
./include/linux/dma-fence.h:679:2: note: expanded from macro 'dma_fence_wait'
679 | sdt_might_sleep_start_timeout(NULL, MAX_SCHEDULE_TIMEOUT); \
| ^
./include/linux/dept_sdt.h:45:45: note: expanded from macro 'sdt_might_sleep_start_timeout'
45 | dept_stage_wait(__m, __m ? NULL : &__key, _THIS_IP_, __func__, t);\
| ^
./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/amd/amdgpu/amdgpu_mes.c:1399:2: note: jump enters a statement expression
./include/linux/dma-fence.h:675:38: note: expanded from macro 'dma_fence_wait'
675 | #define dma_fence_wait(f, intr) \
| ^
1 error generated.
Context and Analysis:
1. “ _THIS_IP_” Macro: This macro, defined in
“include/linux/instruction_pointer.h”, uses a GNU C statement expression with
an address-of-label (&&__here) to obtain the current instruction pointer.
2. Code Flow:
The “drm_exec_retry_on_contention” macro (from include/drm/drm_exec.h)
expands to an indirect ‘goto’ statement (goto *_drm_exec_retry_ptr;). This
pointer is set within the “drm_exec_until_all_locked” macro. One of the
possible targets of this indirect ‘goto’ (as identified by Clang) is a line
within the “dma_fence_wait()” function call.
“dma_fence_wait()” (from include/linux/dma-fence.h) calls
“sdt_might_sleep_start_timeout” (from include/linux/dept_sdt.h).
“sdt_might_sleep_start_timeout” then utilizes the “_THIS_IP_” macro.
3. The Problem:
Clang reports an error because the indirect ‘goto’ from
“drm_exec_retry_on_contention” attempts to jump into the statement
expression generated by “_THIS_IP_”. The diagnostic “note: jump enters
a statement expression” is the key.
Comparison with GCC:
GCC compiles this code without errors. This highlights a difference in how GCC
and Clang handle GNU extensions like statement expressions and
address-of-labels, especially when combined with indirect ‘goto’ for control
flow. GCC appears more lenient or implements these features differently.
Relevant LLVM Issues/Patches:
1. LLVM Issue 138272 (Add builtin/intrinsic to get current instruction pointer):
Link: https://github.com/llvm/llvm-project/issues/138272
This issue discusses the problematic nature of _THIS_IP_'s usage in LLVM.
It indicates that ‘blockaddress’ (LLVM's representation for ‘&&label’) has
defined behavior only when used as an operand to “indirectbr” or for null
comparisons. Using it merely to obtain the instruction pointer violates
LLVM's requirements.
2. LLVM Patch D154696 ([Clang] Diagnose jumps into statement expressions):
Link: https://reviews.llvm.org/D154696
This patch directly addresses the issue of jumps into statement expressions.
It was initially reverted due to breaking the Linux kernel build but was
later relanded. This shows Clang's active effort to enforce stricter
diagnostics for such constructs, which GCC's documentation also implicitly
states as undefined behavior.
3. LLVM Issue 28019 (Wrong 'error: cannot jump from this indirect goto statement
to one of its possible targets'):
Link: https://github.com/llvm/llvm-project/issues/28019
While not directly about statement expressions, this issue describes a
similar error where Clang flags an indirect ‘goto’ bypassing VLA
initialization. This reinforces Clang's conservative static analysis and its
tendency to diagnose potential undefined behavior.
Conclusion and Request:
The compilation error seems to stem from Clang's stricter adherence to LLVM's
‘blockaddress’ usage rules and its diagnostics for jumps into statement
expressions, which Clang considers undefined behavior. The DEPT patch integrates
“sdt_might_sleep_start_timeout” into the “dma_fence_wait” call path, exposing
this problematic pattern when combined with “drm_exec_retry_on_contention”.
I haven't found any specific Clang compiler options that would allow us to
disable this diagnostic or work around the issue.
Could you please provide guidance on how to address this compilation error? Is
this a known limitation or an intended diagnostic behavior that kernel
developers need to adapt to? Are there any recommended patterns or compiler
flags that could mitigate this issue without fundamentally altering the kernel's
use of these GNU extensions?
Thank you for your time and assistance.
Sincerely,
Yunseong Kim
Powered by blists - more mailing lists