diff options
| author | Miguel Ojeda <ojeda@kernel.org> | 2026-08-16 15:32:33 +0200 |
|---|---|---|
| committer | Miguel Ojeda <ojeda@kernel.org> | 2026-08-23 21:27:17 +0200 |
| commit | 5febf432df1cfa5b25d99b54c32103fafbdd0eb9 (patch) | |
| tree | 93a1ed1d337bc53adf1e572c2586d347703b286e /include/trace/events/host1x.h | |
| download | linux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.tar.gz linux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.zip | |
kbuild: rust: keep Rust objects out of Clang LTO with inline helpersgrafted
Under `CONFIG_LTO_CLANG` + `CONFIG_RUST_INLINE_HELPERS`, one may hit
`objtool` errors such as:
vmlinux.o: error: objtool: _R..._3Gsp4boot+0xd6a:
can't find jump dest instruction at .text._R..._3Gsp4boot+0x1dfd
The reason is that in such builds, the Clang invocation that compiles
the combined Rust plus helpers bitcode emits LLVM bitcode (again) --
the final code generation happens in the linker's LTO step, which the
`-mllvm` trap options passed to Clang do not reach.
This, in turn, means that unreachable traps are missing, and the
impossible paths do not merely fallthrough to the next symbol, but past
the end of their own section, since LTO builds place each function in
its own section.
Thus filter `CC_FLAGS_LTO` out of the Clang invocation, so that it always
emits machine code directly, with the traps in place.
Assisted-by: LLM
Cc: Gary Guo <gary@garyguo.net>
Cc: Boqun Feng <boqun@kernel.org>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: Matthew Maurer <mmaurer@google.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
Fixes: 3a2486cc1da5 ("kbuild: rust: provide an option to inline C helpers into Rust")
Acked-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260816133233.197500-2-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'include/trace/events/host1x.h')
| -rw-r--r-- | include/trace/events/host1x.h | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/include/trace/events/host1x.h b/include/trace/events/host1x.h new file mode 100644 index 000000000..1b6aeb7b1 --- /dev/null +++ b/include/trace/events/host1x.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * include/trace/events/host1x.h + * + * host1x event logging to ftrace. + * + * Copyright (c) 2010-2013, NVIDIA Corporation. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM host1x + +#if !defined(_TRACE_HOST1X_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOST1X_H + +#include <linux/ktime.h> +#include <linux/tracepoint.h> + +struct host1x_bo; + +DECLARE_EVENT_CLASS(host1x, + TP_PROTO(const char *name), + TP_ARGS(name), + TP_STRUCT__entry(__string(name, name)), + TP_fast_assign( + __assign_str(name); + ), + TP_printk("name=%s", __get_str(name)) +); + +DEFINE_EVENT(host1x, host1x_channel_open, + TP_PROTO(const char *name), + TP_ARGS(name) +); + +DEFINE_EVENT(host1x, host1x_channel_release, + TP_PROTO(const char *name), + TP_ARGS(name) +); + +DEFINE_EVENT(host1x, host1x_cdma_begin, + TP_PROTO(const char *name), + TP_ARGS(name) +); + +DEFINE_EVENT(host1x, host1x_cdma_end, + TP_PROTO(const char *name), + TP_ARGS(name) +); + +TRACE_EVENT(host1x_cdma_push, + TP_PROTO(const char *name, u32 op1, u32 op2), + + TP_ARGS(name, op1, op2), + + TP_STRUCT__entry( + __string(name, name) + __field(u32, op1) + __field(u32, op2) + ), + + TP_fast_assign( + __assign_str(name); + __entry->op1 = op1; + __entry->op2 = op2; + ), + + TP_printk("name=%s, op1=%08x, op2=%08x", + __get_str(name), __entry->op1, __entry->op2) +); + +TRACE_EVENT(host1x_cdma_push_wide, + TP_PROTO(const char *name, u32 op1, u32 op2, u32 op3, u32 op4), + + TP_ARGS(name, op1, op2, op3, op4), + + TP_STRUCT__entry( + __string(name, name) + __field(u32, op1) + __field(u32, op2) + __field(u32, op3) + __field(u32, op4) + ), + + TP_fast_assign( + __assign_str(name); + __entry->op1 = op1; + __entry->op2 = op2; + __entry->op3 = op3; + __entry->op4 = op4; + ), + + TP_printk("name=%s, op1=%08x, op2=%08x, op3=%08x op4=%08x", + __get_str(name), __entry->op1, __entry->op2, __entry->op3, + __entry->op4) +); + +TRACE_EVENT(host1x_cdma_push_gather, + TP_PROTO(const char *name, struct host1x_bo *bo, + u32 words, u32 offset, void *cmdbuf), + + TP_ARGS(name, bo, words, offset, cmdbuf), + + TP_STRUCT__entry( + __string(name, name) + __field(struct host1x_bo *, bo) + __field(u32, words) + __field(u32, offset) + __field(bool, cmdbuf) + __dynamic_array(u32, cmdbuf, words) + ), + + TP_fast_assign( + if (cmdbuf) { + memcpy(__get_dynamic_array(cmdbuf), cmdbuf+offset, + words * sizeof(u32)); + } + __entry->cmdbuf = cmdbuf; + __assign_str(name); + __entry->bo = bo; + __entry->words = words; + __entry->offset = offset; + ), + + TP_printk("name=%s, bo=%p, words=%u, offset=%d, contents=[%s]", + __get_str(name), __entry->bo, + __entry->words, __entry->offset, + __print_hex(__get_dynamic_array(cmdbuf), + __entry->cmdbuf ? __entry->words * 4 : 0)) +); + +TRACE_EVENT(host1x_channel_submit, + TP_PROTO(const char *name, u32 cmdbufs, u32 relocs, u32 syncpt_id, + u32 syncpt_incrs), + + TP_ARGS(name, cmdbufs, relocs, syncpt_id, syncpt_incrs), + + TP_STRUCT__entry( + __string(name, name) + __field(u32, cmdbufs) + __field(u32, relocs) + __field(u32, syncpt_id) + __field(u32, syncpt_incrs) + ), + + TP_fast_assign( + __assign_str(name); + __entry->cmdbufs = cmdbufs; + __entry->relocs = relocs; + __entry->syncpt_id = syncpt_id; + __entry->syncpt_incrs = syncpt_incrs; + ), + + TP_printk("name=%s, cmdbufs=%u, relocs=%u, syncpt_id=%u, " + "syncpt_incrs=%u", + __get_str(name), __entry->cmdbufs, __entry->relocs, + __entry->syncpt_id, __entry->syncpt_incrs) +); + +TRACE_EVENT(host1x_channel_submitted, + TP_PROTO(const char *name, u32 syncpt_base, u32 syncpt_max), + + TP_ARGS(name, syncpt_base, syncpt_max), + + TP_STRUCT__entry( + __string(name, name) + __field(u32, syncpt_base) + __field(u32, syncpt_max) + ), + + TP_fast_assign( + __assign_str(name); + __entry->syncpt_base = syncpt_base; + __entry->syncpt_max = syncpt_max; + ), + + TP_printk("name=%s, syncpt_base=%d, syncpt_max=%d", + __get_str(name), __entry->syncpt_base, __entry->syncpt_max) +); + +TRACE_EVENT(host1x_channel_submit_complete, + TP_PROTO(const char *name, int count, u32 thresh), + + TP_ARGS(name, count, thresh), + + TP_STRUCT__entry( + __string(name, name) + __field(int, count) + __field(u32, thresh) + ), + + TP_fast_assign( + __assign_str(name); + __entry->count = count; + __entry->thresh = thresh; + ), + + TP_printk("name=%s, count=%d, thresh=%d", + __get_str(name), __entry->count, __entry->thresh) +); + +TRACE_EVENT(host1x_wait_cdma, + TP_PROTO(const char *name, u32 eventid), + + TP_ARGS(name, eventid), + + TP_STRUCT__entry( + __string(name, name) + __field(u32, eventid) + ), + + TP_fast_assign( + __assign_str(name); + __entry->eventid = eventid; + ), + + TP_printk("name=%s, event=%d", __get_str(name), __entry->eventid) +); + +TRACE_EVENT(host1x_syncpt_load_min, + TP_PROTO(u32 id, u32 val), + + TP_ARGS(id, val), + + TP_STRUCT__entry( + __field(u32, id) + __field(u32, val) + ), + + TP_fast_assign( + __entry->id = id; + __entry->val = val; + ), + + TP_printk("id=%d, val=%d", __entry->id, __entry->val) +); + +TRACE_EVENT(host1x_syncpt_wait_check, + TP_PROTO(struct host1x_bo *bo, u32 offset, u32 syncpt_id, u32 thresh, + u32 min), + + TP_ARGS(bo, offset, syncpt_id, thresh, min), + + TP_STRUCT__entry( + __field(struct host1x_bo *, bo) + __field(u32, offset) + __field(u32, syncpt_id) + __field(u32, thresh) + __field(u32, min) + ), + + TP_fast_assign( + __entry->bo = bo; + __entry->offset = offset; + __entry->syncpt_id = syncpt_id; + __entry->thresh = thresh; + __entry->min = min; + ), + + TP_printk("bo=%p, offset=%05x, id=%d, thresh=%d, current=%d", + __entry->bo, __entry->offset, + __entry->syncpt_id, __entry->thresh, + __entry->min) +); + +#endif /* _TRACE_HOST1X_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> |
