* Re: [syzbot] [trace?] KASAN: use-after-free Write in ring_buffer_read_page
From: Alexander Potapenko @ 2026-06-03 8:49 UTC (permalink / raw)
To: Aleksandr Nogikh
Cc: Masami Hiramatsu, Steven Rostedt, syzbot, linux-kernel,
linux-trace-kernel, mathieu.desnoyers, syzkaller-bugs
In-Reply-To: <CANp29Y55QBfKT=FLpn=trH5Tmxj2P_7H7yhJG_xXCbCdR3Lv_A@mail.gmail.com>
On Wed, Jun 3, 2026 at 8:38 AM Aleksandr Nogikh <nogikh@google.com> wrote:
>
> On Wed, Jun 3, 2026 at 3:34 AM 'Masami Hiramatsu' via syzkaller-bugs
> <syzkaller-bugs@googlegroups.com> wrote:
> >
> > On Tue, 2 Jun 2026 12:28:29 -0400
> > Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > > On Tue, 02 Jun 2026 06:45:31 -0700
> > > syzbot <syzbot+2dd9d02f60775ce5c1fb@syzkaller.appspotmail.com> wrote:
> > >
> > > > syzbot found the following issue on:
> > > >
> > > > HEAD commit: e7ae89a0c97c Linux 7.1-rc5
> > > > git tree: upstream
> > > > console output: https://syzkaller.appspot.com/x/log.txt?x=16f06e2e580000
> > > > kernel config: https://syzkaller.appspot.com/x/.config?x=58acee1ac5406016
> > > > dashboard link: https://syzkaller.appspot.com/bug?extid=2dd9d02f60775ce5c1fb
> > > > compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> > > >
> > > > Unfortunately, I don't have any reproducer for this issue yet.
> > >
> > > Looks like the test was doing something really weird to trigger this.
> > > Without a reproducer, it's pretty much impossible to find out what
> > > happened. Maybe AI could do it?
> > >
> >
> > Does the "I don't have any reproducer for this issue yet." means
> > this is not reproducible even if it runs completely same sequence
> > in the console output? If so, might this be a timing related issue?
> > (e.g. read v.s. write-event)
>
> Yes, syzbot normally re-plays the sequence of last programs executed
> on the crashed VM to find a reproducer, and, in many cases, they no
> longer crash the kernel..
>
> In the meanwhile, syzbot's AI bug reproduction functionality has found
> a C reproducer for a KASAN crash in the kernel/trace's ring buffer,
> although with a slightly different stack trace:
> https://syzkaller.appspot.com/ai_job?id=b2620161-1632-4d4e-9314-114a8a5e79ef
>
> Cc Alexander Potapenko
Yes, the bug that the AI reproduced manifests with a different stack:
BUG: KASAN: slab-use-after-free in instrument_copy_to_user
include/linux/instrumented.h:129 [inline]
BUG: KASAN: slab-use-after-free in _inline_copy_to_user
include/linux/uaccess.h:205 [inline]
BUG: KASAN: slab-use-after-free in _copy_to_user+0x79/0xb0 lib/usercopy.c:26
Read of size 12288 at addr ffff888180423000 by task syz-executor144/5941
CPU: 1 UID: 0 PID: 5941 Comm: syz-executor144 Not tainted syzkaller #1
PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_address_description+0x55/0x1e0 mm/kasan/report.c:378
print_report+0x58/0x70 mm/kasan/report.c:482
kasan_report+0x117/0x150 mm/kasan/report.c:595
check_region_inline mm/kasan/generic.c:-1 [inline]
kasan_check_range+0x264/0x2c0 mm/kasan/generic.c:200
instrument_copy_to_user include/linux/instrumented.h:129 [inline]
_inline_copy_to_user include/linux/uaccess.h:205 [inline]
_copy_to_user+0x79/0xb0 lib/usercopy.c:26
copy_to_user include/linux/uaccess.h:236 [inline]
tracing_buffers_read+0x4cd/0xd60 kernel/trace/trace.c:7158
vfs_read+0x20c/0xa70 fs/read_write.c:572
ksys_read+0x150/0x270 fs/read_write.c:717
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0x560 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f9facd00cde
Code: 08 0f 85 f5 e2 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89
c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 90
41 57 41 56 4d 89 c6 41 55 4d 89 cd 41 54 55 53 48 83 ec 08
RSP: 002b:00007f9fabc9e198 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
RAX: ffffffffffffffda RBX: 00007f9fabca26c0 RCX: 00007f9facd00cde
RDX: 0000000000004000 RSI: 00007f9fabc9e200 RDI: 0000000000000006
RBP: 00007f9fabc9e200 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f9facd7ab20
R13: 0000000000000000 R14: 00007ffd6ed73110 R15: 00007ffd6ed731f8
</TASK>
Quoting the AI itself:
"""
The reproducer successfully triggered a KASAN use-after-free crash in
the tracing subsystem. Although the exact crash signature differs
slightly (a read in `_copy_to_user` called from `tracing_buffers_read`
vs a write in `ring_buffer_read_page` called from
`tracing_buffers_read`), both crashes are use-after-free bugs on ring
buffer pages accessed during `tracing_buffers_read`. The reproduced
crash shows the page being freed by `ring_buffer_subbuf_order_set`
(via `buffer_subbuf_size_write`) while being concurrently accessed by
`tracing_buffers_read`. This confirms the underlying race condition
between reading the trace buffers and modifying the buffer size/order
has been successfully reproduced.
"""
I took a glance at the reports, and the above makes sense: we just
happen to access filp->private_data->spare at different times after it
has been freed.
PS. Please bear with repro-c, it's making its baby steps.
The reproducer contains some dead code, and the results are hard to navigate.
At some point we'll probably be able to link AI-generated repros from
the original bugs.
^ permalink raw reply
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Arnd Bergmann @ 2026-06-03 8:41 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Andy Shevchenko, Arnd Bergmann, Steven Rostedt, Masami Hiramatsu,
Andrew Morton, Petr Mladek, Nathan Chancellor, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Arend van Spriel,
Miri Korenblit, Mathieu Desnoyers, Sergey Senozhatsky,
Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka (SUSE), linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <875x40hz7k.fsf@prevas.dk>
On Wed, Jun 3, 2026, at 09:15, Rasmus Villemoes wrote:
> On Tue, Jun 02 2026, "Arnd Bergmann" <arnd@arndb.de> wrote:
>> On Tue, Jun 2, 2026, at 20:59, Andy Shevchenko wrote:
>>> On Tue, Jun 02, 2026 at 05:07:05PM +0200, Arnd Bergmann wrote:
>
> May I suggest a different approach, that avoids having that extra
> function emitted (which presumably compiles to a single jump
> instruction, but still, with retpoline and CFI and all that it all adds
> up): Keep the declaration of __vsnprintf() in the header without the
> __print() attribute, but then do
>
> int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> __alias(vsnprintf);
>
> in vsprintf.c. Aside from reusing the same entry point, I could well
> imagine a compiler some day complaining about seeing the printf
> attribute applied in a local extra declaration but not having it in the
> header file.
>
> Presumably it will need its own EXPORT_SYMBOL if any of the intended
> users are modular, and it certainly still needs a comment.
I had tried that earlier but given up because the attributes have to
match exactly.
This definition works with all currently supported versions of gcc,
but may have to change when the there is a new version that adds
even more attributes:
int
__printf(3, 0)
__attribute__((nothrow))
__attribute__((nonnull(1)))
__vsnprintf(char *__restrict buf, size_t size,
const char * __restrict fmt_str, va_list args)
__alias(vsnprintf);
We'd probably want to also add __nothrow and __nonnull macros
in linux/compiler-attributes.h if we do this.
For reference, see below for the alternative idea I had
that avoids adding the __vsnprintf() alias altogether by
passing down the va_format using "%pV".
I don't think I actually got this one right in the end
since I only build-tested it, but I expect it could be done
if someone is able to test and fix all the corner cases
properly.
Arnd
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 4715330c7b6b..8e44fc3e60b0 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -956,14 +956,11 @@ perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type,
* gcc warns that you can not use a va_list in an inlined
* function. But lets me make it into a macro :-/
*/
-#define __trace_event_vstr_len(fmt, va) \
+#define __trace_event_vstr_len(vf) \
({ \
- va_list __ap; \
int __ret; \
\
- va_copy(__ap, *(va)); \
- __ret = __vsnprintf(NULL, 0, fmt, __ap) + 1; \
- va_end(__ap); \
+ __ret = snprintf(NULL, 0, "%pV", vf) + 1; \
\
min(__ret, TRACE_EVENT_STR_MAX); \
})
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
index 1a05fc153353..2f3ee3632e77 100644
--- a/samples/trace_events/trace-events-sample.h
+++ b/samples/trace_events/trace-events-sample.h
@@ -143,20 +143,20 @@
* saved string into the "foo" field.
*
* __vstring: This is similar to __string() but instead of taking a
- * dynamic length, it takes a variable list va_list 'va' variable.
+ * dynamic length, it takes a variable list va_format 'vaf' variable.
* Some event callers already have a message from parameters saved
- * in a va_list. Passing in the format and the va_list variable
- * will save just enough on the ring buffer for that string.
- * Note, the va variable used is a pointer to a va_list, not
- * to the va_list directly.
+ * in a va_format. Passing in the va_format variable will save just
+ * enough on the ring buffer for that string.
*
- * (va_list *va)
+ * (va_format *vaf)
*
- * __vstring(foo, fmt, va) is similar to: vsnprintf(foo, fmt, va)
+ * __vstring(foo, vaf) is similar to:
+ *
+ * vsnprintf(foo, "%pV", vaf)
*
* To assign the string, use the helper macro __assign_vstr().
*
- * __assign_vstr(foo, fmt, va);
+ * __assign_vstr(foo, vaf);
*
* In most cases, the __assign_vstr() macro will take the same
* parameters as the __vstring() macro had to declare the string.
@@ -292,9 +292,9 @@ TRACE_EVENT(foo_bar,
TP_PROTO(const char *foo, int bar, const int *lst,
const char *string, const struct cpumask *mask,
- const char *fmt, va_list *va),
+ struct va_format *vaf),
- TP_ARGS(foo, bar, lst, string, mask, fmt, va),
+ TP_ARGS(foo, bar, lst, string, mask, vaf),
TP_STRUCT__entry(
__array( char, foo, 10 )
@@ -303,7 +303,7 @@ TRACE_EVENT(foo_bar,
__string( str, string )
__bitmask( cpus, num_possible_cpus() )
__cpumask( cpum )
- __vstring( vstr, fmt, va )
+ __vstring( vstr, vaf )
__string_len( lstr, foo, bar / 2 < strlen(foo) ? bar / 2 : strlen(foo) )
),
@@ -314,7 +314,7 @@ TRACE_EVENT(foo_bar,
__length_of(lst) * sizeof(int));
__assign_str(str);
__assign_str(lstr);
- __assign_vstr(vstr, fmt, va);
+ __assign_vstr(vstr, vaf);
__assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus());
__assign_cpumask(cpum, cpumask_bits(mask));
),
diff --git a/include/trace/stages/stage6_event_callback.h b/include/trace/stages/stage6_event_callback.h
index 7d6a6ca6e779..2a4611b20afa 100644
--- a/include/trace/stages/stage6_event_callback.h
+++ b/include/trace/stages/stage6_event_callback.h
@@ -28,7 +28,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __assign_str
#define __assign_str(dst) \
@@ -41,13 +41,8 @@
} while (0)
#undef __assign_vstr
-#define __assign_vstr(dst, fmt, va) \
- do { \
- va_list __cp_va; \
- va_copy(__cp_va, *(va)); \
- __vsnprintf(__get_str(dst), TRACE_EVENT_STR_MAX, fmt, __cp_va); \
- va_end(__cp_va); \
- } while (0)
+#define __assign_vstr(dst, vf) \
+ snprintf(__get_str(dst), TRACE_EVENT_STR_MAX, "%pV", vf);
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
diff --git a/drivers/infiniband/hw/hfi1/trace_dbg.h b/drivers/infiniband/hw/hfi1/trace_dbg.h
index 05c4f1354269..c96144d516db 100644
--- a/drivers/infiniband/hw/hfi1/trace_dbg.h
+++ b/drivers/infiniband/hw/hfi1/trace_dbg.h
@@ -26,10 +26,10 @@ DECLARE_EVENT_CLASS(hfi1_trace_template,
TP_PROTO(const char *function, struct va_format *vaf),
TP_ARGS(function, vaf),
TP_STRUCT__entry(__string(function, function)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(__assign_str(function);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("(%s) %s",
__get_str(function),
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index 68b78ca17eaa..c258ad7de79e 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -52,12 +52,12 @@ DECLARE_EVENT_CLASS(ath10k_log_event,
TP_STRUCT__entry(
__string(device, dev_name(ar->dev))
__string(driver, dev_driver_string(ar->dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
"%s %s %s",
@@ -89,13 +89,13 @@ TRACE_EVENT(ath10k_log_dbg,
__string(device, dev_name(ar->dev))
__string(driver, dev_driver_string(ar->dev))
__field(unsigned int, level)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
__entry->level = level;
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
"%s %s %s",
diff --git a/drivers/net/wireless/ath/ath11k/trace.h b/drivers/net/wireless/ath/ath11k/trace.h
index 75246b0a82e3..0ac14b72deac 100644
--- a/drivers/net/wireless/ath/ath11k/trace.h
+++ b/drivers/net/wireless/ath/ath11k/trace.h
@@ -127,12 +127,12 @@ DECLARE_EVENT_CLASS(ath11k_log_event,
TP_STRUCT__entry(
__string(device, dev_name(ab->dev))
__string(driver, dev_driver_string(ab->dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
"%s %s %s",
diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h
index 8577aa459c58..d46fe6b675f9 100644
--- a/drivers/net/wireless/ath/ath6kl/trace.h
+++ b/drivers/net/wireless/ath/ath6kl/trace.h
@@ -253,10 +253,10 @@ DECLARE_EVENT_CLASS(ath6kl_log_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
@@ -281,11 +281,11 @@ TRACE_EVENT(ath6kl_log_dbg,
TP_ARGS(level, vaf),
TP_STRUCT__entry(
__field(unsigned int, level)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/net/wireless/ath/trace.h b/drivers/net/wireless/ath/trace.h
index 82aac0a4baff..298a56349ea7 100644
--- a/drivers/net/wireless/ath/trace.h
+++ b/drivers/net/wireless/ath/trace.h
@@ -40,13 +40,13 @@ TRACE_EVENT(ath_log,
TP_STRUCT__entry(
__string(device, wiphy_name(wiphy))
__string(driver, KBUILD_MODNAME)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
diff --git a/drivers/net/wireless/ath/wil6210/trace.h b/drivers/net/wireless/ath/wil6210/trace.h
index 201f44612c31..7eb6ca2b0cb6 100644
--- a/drivers/net/wireless/ath/wil6210/trace.h
+++ b/drivers/net/wireless/ath/wil6210/trace.h
@@ -70,10 +70,10 @@ DECLARE_EVENT_CLASS(wil6210_log_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
index 6c4e00e9ccd1..66b179adb80c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
@@ -33,11 +33,11 @@ TRACE_EVENT(brcmf_err,
TP_ARGS(func, vaf),
TP_STRUCT__entry(
__string(func, func)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(func);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(func), __get_str(msg))
);
@@ -48,12 +48,12 @@ TRACE_EVENT(brcmf_dbg,
TP_STRUCT__entry(
__field(u32, level)
__string(func, func)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
__assign_str(func);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(func), __get_str(msg))
);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h
index dc296d8bf775..369171af1a30 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h
@@ -28,10 +28,10 @@ DECLARE_EVENT_CLASS(brcms_msg_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
@@ -62,12 +62,12 @@ TRACE_EVENT(brcms_dbg,
TP_STRUCT__entry(
__field(u32, level)
__string(func, func)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
__assign_str(func);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(func), __get_str(msg))
);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
index 0db1fa5477af..80cfb9fc8ad8 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
@@ -18,10 +18,10 @@ DECLARE_EVENT_CLASS(iwlwifi_msg_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
@@ -53,12 +53,12 @@ TRACE_EVENT(iwlwifi_dbg,
TP_STRUCT__entry(
__field(u32, level)
__string(function, function)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
__assign_str(function);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/usb/chipidea/trace.h b/drivers/usb/chipidea/trace.h
index 1875419cd17f..9ec0df074872 100644
--- a/drivers/usb/chipidea/trace.h
+++ b/drivers/usb/chipidea/trace.h
@@ -28,11 +28,11 @@ TRACE_EVENT(ci_log,
TP_ARGS(ci, vaf),
TP_STRUCT__entry(
__string(name, dev_name(ci->dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(name);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(name), __get_str(msg))
);
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 724cba2dbb78..575c02109b4b 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -28,9 +28,9 @@
DECLARE_EVENT_CLASS(xhci_log_msg,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
- TP_STRUCT__entry(__vstring(msg, vaf->fmt, vaf->va)),
+ TP_STRUCT__entry(__vstring(msg, vaf)),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/usb/mtu3/mtu3_trace.h b/drivers/usb/mtu3/mtu3_trace.h
index 89870175d635..56c9263a99d8 100644
--- a/drivers/usb/mtu3/mtu3_trace.h
+++ b/drivers/usb/mtu3/mtu3_trace.h
@@ -23,11 +23,11 @@ TRACE_EVENT(mtu3_log,
TP_ARGS(dev, vaf),
TP_STRUCT__entry(
__string(name, dev_name(dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(name);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(name), __get_str(msg))
);
diff --git a/drivers/usb/musb/musb_trace.h b/drivers/usb/musb/musb_trace.h
index 726e6697d475..7dba44b0496d 100644
--- a/drivers/usb/musb/musb_trace.h
+++ b/drivers/usb/musb/musb_trace.h
@@ -28,11 +28,11 @@ TRACE_EVENT(musb_log,
TP_ARGS(musb, vaf),
TP_STRUCT__entry(
__string(name, dev_name(musb->controller))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(name);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(name), __get_str(msg))
);
diff --git a/include/trace/events/iscsi.h b/include/trace/events/iscsi.h
index 990fd154f586..2e2667658b51 100644
--- a/include/trace/events/iscsi.h
+++ b/include/trace/events/iscsi.h
@@ -26,12 +26,12 @@ DECLARE_EVENT_CLASS(iscsi_log_msg,
TP_STRUCT__entry(
__string(dname, dev_name(dev) )
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(dname);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s",__get_str(dname), __get_str(msg)
diff --git a/include/trace/events/qla.h b/include/trace/events/qla.h
index 74a7534b99b6..554ae9a623c6 100644
--- a/include/trace/events/qla.h
+++ b/include/trace/events/qla.h
@@ -17,11 +17,11 @@ DECLARE_EVENT_CLASS(qla_log_event,
TP_STRUCT__entry(
__string(buf, buf)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(buf);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s %s", __get_str(buf), __get_str(msg))
diff --git a/include/trace/stages/stage1_struct_define.h b/include/trace/stages/stage1_struct_define.h
index 69e0dae453bf..0ae49a935d16 100644
--- a/include/trace/stages/stage1_struct_define.h
+++ b/include/trace/stages/stage1_struct_define.h
@@ -27,7 +27,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(char, item, -1)
diff --git a/include/trace/stages/stage2_data_offsets.h b/include/trace/stages/stage2_data_offsets.h
index 8b0cff06d346..5c6dc3092e07 100644
--- a/include/trace/stages/stage2_data_offsets.h
+++ b/include/trace/stages/stage2_data_offsets.h
@@ -33,7 +33,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
diff --git a/include/trace/stages/stage4_event_fields.h b/include/trace/stages/stage4_event_fields.h
index b6f679ae21aa..77f74d509760 100644
--- a/include/trace/stages/stage4_event_fields.h
+++ b/include/trace/stages/stage4_event_fields.h
@@ -42,7 +42,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
diff --git a/include/trace/stages/stage5_get_offsets.h b/include/trace/stages/stage5_get_offsets.h
index c6a62dfb18ef..1ce5ca15a8ed 100644
--- a/include/trace/stages/stage5_get_offsets.h
+++ b/include/trace/stages/stage5_get_offsets.h
@@ -65,8 +65,8 @@ static inline const char *__string_src(const char *str)
__data_offsets->item##_ptr_ = src;
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, \
- __trace_event_vstr_len(fmt, ap))
+#define __vstring(item, vf) __dynamic_array(char, item, \
+ __trace_event_vstr_len(vf))
#undef __rel_dynamic_array
#define __rel_dynamic_array(type, item, len) \
diff --git a/net/batman-adv/trace.h b/net/batman-adv/trace.h
index 7da692ec38e9..ac88789330a3 100644
--- a/net/batman-adv/trace.h
+++ b/net/batman-adv/trace.h
@@ -36,13 +36,13 @@ TRACE_EVENT(batadv_dbg,
TP_STRUCT__entry(
__string(device, bat_priv->mesh_iface->name)
__string(driver, KBUILD_MODNAME)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h
index aea4ce55c5ac..0de50dfa13ed 100644
--- a/net/mac80211/trace_msg.h
+++ b/net/mac80211/trace_msg.h
@@ -22,11 +22,11 @@ DECLARE_EVENT_CLASS(mac80211_msg_event,
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c
index ecc7db237f2e..07096eadfb7b 100644
--- a/samples/trace_events/trace-events-sample.c
+++ b/samples/trace_events/trace-events-sample.c
@@ -23,6 +23,7 @@ static void do_simple_thread_func(int cnt, const char *fmt, ...)
{
unsigned long bitmask[1] = {0xdeadbeefUL};
va_list va;
+ struct va_format vf = { .fmt = fmt };
int array[6];
int len = cnt % 5;
int i;
@@ -35,10 +36,11 @@ static void do_simple_thread_func(int cnt, const char *fmt, ...)
array[i] = 0;
va_start(va, fmt);
+ vf.va = &va;
/* Silly tracepoints */
trace_foo_bar("hello", cnt, array, random_strings[len],
- current->cpus_ptr, fmt, &va);
+ current->cpus_ptr, &vf);
va_end(va);
^ permalink raw reply related
* Re: [PATCH mm-unstable v18 11/14] mm/khugepaged: Introduce mTHP collapse support
From: David Hildenbrand (Arm) @ 2026-06-03 8:05 UTC (permalink / raw)
To: Lance Yang, Nico Pache
Cc: linux-doc, linux-kernel, linux-mm, linux-trace-kernel, aarcange,
akpm, anshuman.khandual, apopple, baohua, baolin.wang, byungchul,
catalin.marinas, cl, corbet, dave.hansen, dev.jain, gourry,
hannes, hughd, jack, jackmanb, jannh, jglisse, joshua.hahnjy, kas,
liam, ljs, mathieu.desnoyers, matthew.brost, mhiramat, mhocko,
peterx, pfalcato, rakie.kim, raquini, rdunlap, richard.weiyang,
rientjes, rostedt, rppt, ryan.roberts, shivankg, sunnanyong,
surenb, thomas.hellstrom, tiwai, usamaarif642, vbabka,
vishal.moola, wangkefeng.wang, will, willy, yang, ying.huang, ziy,
zokeefe
In-Reply-To: <185f5699-3797-4300-8c54-bb99fc2a45e0@linux.dev>
On 6/2/26 17:44, Lance Yang wrote:
>
>
> On 2026/6/2 18:58, Nico Pache wrote:
>> On Sun, May 31, 2026 at 1:19 AM Lance Yang <lance.yang@linux.dev> wrote:
>>>
>>>
>>> [...]
>>>
>>> Hmm ... don't we lose the allocation-failure result here?
>>>
>>> Previously collapse_scan_pmd() propagated SCAN_ALLOC_HUGE_PAGE_FAIL from
>>> collapse_huge_page(), so khugepaged would call khugepaged_alloc_sleep()
>>> in khugepaged_do_scan().
>>>
>>> Now if allocation fails and nr_collapsed stays 0, we just return
>>> SCAN_FAIL. So we won't back off via khugepaged_alloc_sleep() anymore?
>>
>> Ok I did the error propagation! I think I handled both of these cases
>> you brought up pretty easily.
>
> Thanks.
>
>> However I don't know what to do in the following case: We successfully
>> collapsed some portion of the PMD, but during that process, we also
>> hit an allocation failure. Is it best to back off entirely? or can we
>> treat some forward progress as a sign we can continue trying collapses
>> without sleeping.
>>
>> Basically, do we prioritize SCAN_ALLOC_HUGE_PAGE_FAIL or the
>> successful collapses as the returned value?
>
> Thinking out loud, forward progress should win here, the allocation
> failure only matter if we made no progress at all?
Agreed, in the first approach, forward progress makes sense.
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Rasmus Villemoes @ 2026-06-03 7:15 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andy Shevchenko, Arnd Bergmann, Steven Rostedt, Masami Hiramatsu,
Andrew Morton, Petr Mladek, Nathan Chancellor, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Arend van Spriel,
Miri Korenblit, Mathieu Desnoyers, Sergey Senozhatsky,
Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka (SUSE), linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <35c1ba62-e74d-4abc-aa73-ccd35968ff89@app.fastmail.com>
On Tue, Jun 02 2026, "Arnd Bergmann" <arnd@arndb.de> wrote:
> On Tue, Jun 2, 2026, at 20:59, Andy Shevchenko wrote:
>> On Tue, Jun 02, 2026 at 05:07:05PM +0200, Arnd Bergmann wrote:
>>>
>>> A number of tracing headers turn off -Wsuggest-attribute=format for
>>> gcc, but they don't turn it off for clang, so the same warning still
>>> happens on new versions of clang that support the format attribute.
>>>
>>> To avoid duplicating the same thing in each tracing header, as well
>>> as changing all of them to also turn it off for clang, add a new
>>> __vsnprintf() helper that is not annotated this way in linux/sprintf.h
>>> but is defined to work the same way as the regular vsprintf.
>>
>> vsprintf()
>
> Fixed now
>
>> Why the __printf() annotation is in the C file and not here?
>> Is this all about headers as the second paragraph in the commit message
>> explains?
>> I would add a comment to explain it here, otherwise we might see false
>> patches to "make things consistent" in a wrong way.
>
> I've tried to come up with a kerneldoc comment now, similar to
> the one for the vsnprintf() function, and added a separate prototype
> in the header. Does this address your concern?
>
> Arnd
>
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 3caf0796f54d..7c696aea2ed3 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -2975,7 +2975,23 @@ int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> }
> EXPORT_SYMBOL(vsnprintf);
>
> -int __printf(3, 0) __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> +/**
> + * __vsnprintf - vsnprintf() wrapper without __printf() attribute
> + * @buf: The buffer to place the result into
> + * @size: The size of the buffer, including the trailing null space
> + * @fmt_str: The format string to use
> + * @args: Arguments for the format string
> + *
> + * This has the exact same behavior as vsnprintf() but can be used in call
> + * sites that are missing a __printf() annotation, e.g. because they
> + * get a 'va_format' argument instead of format and varargs.
> + *
> + * For this to work, the attribute is added to the declaration here but
> + * not in the header.
> + */
> +int __printf(3, 0) __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args);
> +
> +int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> {
> return vsnprintf(buf, size, fmt_str, args);
> }
May I suggest a different approach, that avoids having that extra
function emitted (which presumably compiles to a single jump
instruction, but still, with retpoline and CFI and all that it all adds
up): Keep the declaration of __vsnprintf() in the header without the
__print() attribute, but then do
int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
__alias(vsnprintf);
in vsprintf.c. Aside from reusing the same entry point, I could well
imagine a compiler some day complaining about seeing the printf
attribute applied in a local extra declaration but not having it in the
header file.
Presumably it will need its own EXPORT_SYMBOL if any of the intended
users are modular, and it certainly still needs a comment.
Rasmus
^ permalink raw reply
* Re: [PATCH 1/8] scripts/sorttable: Handle RISC-V patchable ftrace entries
From: Chen Pei @ 2026-06-03 7:14 UTC (permalink / raw)
To: wanghan
Cc: acme, alex, andybnac, aou, bjorn, catalin.marinas, conor.dooley,
cp0613, debug, jikos, joe.lawrence, jpoimboe, linux-kernel,
linux-kselftest, linux-perf-users, linux-riscv,
linux-trace-kernel, live-patching, mark.rutland, mbenes, mhiramat,
mingo, namhyung, palmer, peterz, pjw, pmladek, puranjay, rostedt,
shuah
In-Reply-To: <20260527123530.2593918-2-wanghan@linux.alibaba.com>
On Wed, 27 May 2026 20:35:23 +0800, wanghan@linux.alibaba.com wrote:
> On an affected RISC-V QEMU boot with both CONFIG_FTRACE_SORT_STARTUP_TEST
> and CONFIG_FTRACE_STARTUP_TEST enabled, the sort check still passes
> while ftrace reports zero usable entries and the early selftests fail:
>
> [ 0.000000] ftrace section at ffffffff8101da98 sorted properly
> [ 0.000000] ftrace: allocating 0 entries in 128 pages
> [ 0.054999] Testing tracer function: .. no entries found ..FAILED!
> [ 0.172407] tracer: function failed selftest, disabling
> [ 0.178186] Failed to init function_graph tracer, init returned -19
>
> Handle RISC-V like arm64 for the function-range check and allow
> patchable entries up to 8 bytes before the function address.
>
> With this fix, a RISC-V QEMU smoke boot with ftrace startup tests shows
> the vmlinux ftrace table is populated and dynamic ftrace still works:
>
> [ 0.000000] ftrace: allocating 46749 entries in 184 pages
> [ 0.051115] Testing tracer function: PASSED
> [ 1.283782] Testing dynamic ftrace: PASSED
> [ 6.275456] Testing tracer function_graph: PASSED
>
> Fixes: 0ca1724b56af ("riscv: ftrace: select HAVE_BUILDTIME_MCOUNT_SORT")
Oops, sorry for missing that. Thanks for the quick fix!
Reviewed-by: Chen Pei <cp0613@linux.alibaba.com>
^ permalink raw reply
* Re: [LSF/MM/BPF TOPIC][RFC PATCH v4 00/27] Private Memory Nodes (w/ Compressed RAM)
From: Gregory Price @ 2026-06-03 7:02 UTC (permalink / raw)
To: Balbir Singh
Cc: lsf-pc, linux-kernel, linux-cxl, cgroups, linux-mm,
linux-trace-kernel, damon, kernel-team, gregkh, rafael, dakr,
dave, jonathan.cameron, dave.jiang, alison.schofield,
vishal.l.verma, ira.weiny, dan.j.williams, longman, akpm, david,
lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko,
osalvador, ziy, matthew.brost, joshua.hahnjy, rakie.kim,
byungchul, ying.huang, apopple, axelrasmussen, yuanchu, weixugc,
yury.norov, linux, mhiramat, mathieu.desnoyers, tj, hannes,
mkoutny, jackmanb, sj, baolin.wang, npache, ryan.roberts,
dev.jain, baohua, lance.yang, muchun.song, xu.xin16,
chengming.zhou, jannh, linmiaohe, nao.horiguchi, pfalcato,
rientjes, shakeel.butt, riel, harry.yoo, cl, roman.gushchin,
chrisl, kasong, shikemeng, nphamcs, bhe, zhengqi.arch,
terry.bowman
In-Reply-To: <ah-0CyZurn5D1ezY@parvat>
On Wed, Jun 03, 2026 at 03:00:01PM +1000, Balbir Singh wrote:
> On Tue, Jun 02, 2026 at 09:57:48AM +0100, Gregory Price wrote:
> > On Tue, Jun 02, 2026 at 12:16:50PM +1000, Balbir Singh wrote:
> > >
> > > I was think we wouldn't need explicit flags and that allocations would
> > > happen from user space using __GFP_THISNODE to the node or via a nodemask
> > > based on nodes of interest. Is there a reason to add this flag, a system
> > > might have more than one source of N_MEMORY_PRIVATE?
> > >
> >
> > There's a few things to unpack here. I discussed this many times on
> > list and at LSF, but to reiterate.
> >
> > 1) __GFP_THISNODE is insufficient to enforce isolation and otherwise
> > not particularly useful. Additionally, from userland, it's not
> > something you can actually set.
>
> I was thinking mbind()/mempolicy() is how we get to it. It already
> accepts a nodemask.
>
First let me say: I want to enable mbind access to these nodes.
But let me caveat: I think that needs more time to develop, and
in the meantime, we can enable the /dev/xxx pattern somewhat trivially.
First let me address a few things about mbind/mempolicy and how it
interacts with page_alloc.c, I gave this overview at LSF but I don't
remember if I posted it in any of my follow ups.
1) Fallback lists are filtered by nodemask, the nodemask does not replace
the fallback list.
Here is how the page allocator fallback lists and nodemasks interact:
Fallbacks A: A B
Fallbacks B: B A
Fallbacks C: C A B (Private)
Fallbacks D: D B A (Private)
Lets say you pass:
alloc_pages_node(C, ..., nodemask(A,C,D))
So we get
Fallback(C,A,B) & nodemask(A,C,D) -> iterate(C,A)
If we wanted to change this behavior, realistically we'd be looking for
a way to add specific nodes to certain fallback lists - rather than
modify the nodemask interaction in some way.
I think this is out of scope for the first iteration - so supporting
anything other than mbind() from the start is just pointless.
The only feasible mempolicy you can apply is single-node bind, so
realistically you can only support mbind.
2) full mempolicy support doesn't really make sense
task mempolicy PROBABLY should never really touch private nodes,
while VMA policy certainly can. Assuming we're able to support
multi-private-node masks, none of the non-bind mempolicies even
make sense for most private nodes (interleave? weighted interleave?)
I haven't worked through all the implications of a task policy having
a private node attached, but the longer I think about it, the less it
makes sense to just support this outright.
3) Introducing mbind support is not just a simple nodemask on a VMA,
It also implies migration, cgroup/cpuset, and UAPI interactions.
a) migration:
mbind/mempolicy can and will engage migration when it is called
with certain flags. Migration has subtle LRU interactions, but
the patch set I have at least allows this to work.
b) cgroup/cpuset:
cpuset.mems rebinding will cause private nodes to be quietly
rebound to non-private nodes within a nodemask.
c) between A and B - we really want MPOL_F_STATIC to be required
for mbind to be applied to private node so that it is never
forcefully remapped.
That's a UAPI semantic change specific for private nodes we
should really take time to consider.
4) File VMA interactions don't entirely make sense with mbind
In theory you might want:
fd = open("somefile", ...);
mem = mmap(fd, ...);
mbind(mem, ..., private_node);
for page in mem:
mem[page_off] /* fault file into private memory */
In reality: This does not work the way you want.
I went digging and we need a few mild extensions to allow
migration on mbind to work for pagecache pages, and the fault
path does not necessarily respect the vma mempolicy always.
You also start getting into the question of "what happens when
the node is out of memory and you don't have reclaim support?".
The OOM implications jump out at you pretty aggressively.
Moreover other tasks can force the page cache pages to be moved
as well. So the programming model here just kind of sucks.
Works great for anon memory though :]
For all these reasons, I think the be mbind/mempolicy support with
private nodes needs to be brought in with follow up work - not
introduced as part of the baseline set.
> >
> > for node in possible_nodes:
> > alloc_pages_node(private_node, __GFP_THISNODE)
> >
> > In fact it's the opposite semantic of what we want.
> > THISNODE says: "Do not fallback back to OTHER nodes".
> >
>
> That's why we need to control the fallback nodes carefully for
> N_MEMORY_PRIVATE
>
My point is that __GFP_THISNODE is not actually useful.
If we go by nodemask, submitting a single-node nodemask is the
equivalent of an empty fallback list.
If we gate access to a private node by __GFP_THISNODE... this is the
same as just providing a single-node nodelist (putting aside the OOM
implications for a moment).
And it doesn't even buy you any new filtering ability against existing
nodemask iterators that may already utilize __GFP_THISNODE. i.e.
for node in online_nodes:
alloc_pages_node(node, __GFP_THISNODE, ...)
/* Alloc per-node resources */
This pattern is undesirable, but completely valid.
So overloading/requiring __GFP_THISNODE is just not useful.
I will follow up soon with a new version that limits the private node
interface to just nodemask and fallback list controls.
I need to test a few more things related to removing normal nodes from
private node fallbacks before I feel comfortable shipping without
__GFP_PRIVATE.
> > The semantic we want is "Do not allow allocations from private
> > nodes UNLESS we specifically request" (__GFP_PRIVATE).
> >
> > __GFP_THISNODE does not actually buy you anything here, AND it's
> > worse, in the scenario where a private node makes its way into the
> > preferred slot (via possible_nodes or some other nodemask), the
> > allocator cannot fall back to a node it can access.
> >
> > __GFP_THISNODE cannot be overloaded to do anything useful here.
>
> Let me clarify, I meant to say, let's use a nodemask for allocation
> and __GFP_THISNODE gets us to the node we desire, if that is the only
> node. My earlier comment might not have been clear.
>
My point was that __GFP_THISNODE is pointless and reduces to providing a
single node nodemask anyway.
The contention over __GFP_PRIVATE is a bit ideological - do we want:
1) A hard guarantee that allocations to a private node are controlled
(__GFP_PRIVATE implies the caller knows what it's doing)
or
2) A soft guarantee (fallback list isolation only), and needing to
deal with undesired behavior that's "not technically a bug"
associated with existing users of global nodemasks (possible,
online, etc).
I am arguing for #1 - the community has argued for #2 and "fixing
existing nodemask users". I think we can ship #2 and pivot to #1 if we
find fixing existing users is infeasible or too much of a maintenance
burden.
>
> Why not use mbind() API's? Do we want to gate allocation/privileges
> via a /dev?
>
We want to eventually enable it, but we really need to treat these
extensions as a separate step from the base so that the UAPI
implications are given proper scrutiny.
In the short term, /dev/xxx and driver-local/service-local control
of a node is still very useful.
For example, for my compressed memory work, I have found that if
implemented as a swap backend - the kernel can manage the node without
any UAPI implications at all :].
A driver managing memory on a private node could do the same.
~Gregory
^ permalink raw reply
* Re: [syzbot] [trace?] KASAN: use-after-free Write in ring_buffer_read_page
From: Aleksandr Nogikh @ 2026-06-03 6:38 UTC (permalink / raw)
To: Masami Hiramatsu, Alexander Potapenko
Cc: Steven Rostedt, syzbot, linux-kernel, linux-trace-kernel,
mathieu.desnoyers, syzkaller-bugs
In-Reply-To: <20260603103445.236f260a3c5eafe140055761@kernel.org>
On Wed, Jun 3, 2026 at 3:34 AM 'Masami Hiramatsu' via syzkaller-bugs
<syzkaller-bugs@googlegroups.com> wrote:
>
> On Tue, 2 Jun 2026 12:28:29 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
>
> > On Tue, 02 Jun 2026 06:45:31 -0700
> > syzbot <syzbot+2dd9d02f60775ce5c1fb@syzkaller.appspotmail.com> wrote:
> >
> > > syzbot found the following issue on:
> > >
> > > HEAD commit: e7ae89a0c97c Linux 7.1-rc5
> > > git tree: upstream
> > > console output: https://syzkaller.appspot.com/x/log.txt?x=16f06e2e580000
> > > kernel config: https://syzkaller.appspot.com/x/.config?x=58acee1ac5406016
> > > dashboard link: https://syzkaller.appspot.com/bug?extid=2dd9d02f60775ce5c1fb
> > > compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> > >
> > > Unfortunately, I don't have any reproducer for this issue yet.
> >
> > Looks like the test was doing something really weird to trigger this.
> > Without a reproducer, it's pretty much impossible to find out what
> > happened. Maybe AI could do it?
> >
>
> Does the "I don't have any reproducer for this issue yet." means
> this is not reproducible even if it runs completely same sequence
> in the console output? If so, might this be a timing related issue?
> (e.g. read v.s. write-event)
Yes, syzbot normally re-plays the sequence of last programs executed
on the crashed VM to find a reproducer, and, in many cases, they no
longer crash the kernel..
In the meanwhile, syzbot's AI bug reproduction functionality has found
a C reproducer for a KASAN crash in the kernel/trace's ring buffer,
although with a slightly different stack trace:
https://syzkaller.appspot.com/ai_job?id=b2620161-1632-4d4e-9314-114a8a5e79ef
Cc Alexander Potapenko
>
> Thanks,
>
> --
> Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
^ permalink raw reply
* [PATCH 2/2] tracing/synthetic: Free type string on error path
From: Yu Peng @ 2026-06-03 6:25 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers
Cc: linux-trace-kernel, linux-kernel, Yu Peng
In-Reply-To: <20260603062533.1096320-1-pengyu@kylinos.cn>
parse_synth_field() builds a "__data_loc ..." type string before
assigning it to field->type. If the seq_buf check fails, the common
cleanup cannot free the temporary string. Free it before leaving.
Signed-off-by: Yu Peng <pengyu@kylinos.cn>
---
kernel/trace/trace_events_synth.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index cdd5b93328358..dc15658a887cb 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -839,8 +839,10 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
seq_buf_puts(&s, "__data_loc ");
seq_buf_puts(&s, field->type);
- if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
+ if (WARN_ON_ONCE(!seq_buf_buffer_left(&s))) {
+ kfree(type);
goto free;
+ }
s.buffer[s.len] = '\0';
kfree(field->type);
--
2.43.0
^ permalink raw reply related
* [PATCH 1/2] tracing/synthetic: Free pending field on error path
From: Yu Peng @ 2026-06-03 6:25 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers
Cc: linux-trace-kernel, linux-kernel, Yu Peng
Some __create_synth_event() error paths run after parse_synth_field()
succeeds but before the field is stored in fields[]. The common cleanup
then misses the field. Free it before freeing argv.
Signed-off-by: Yu Peng <pengyu@kylinos.cn>
---
kernel/trace/trace_events_synth.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index e6871230bde96..cdd5b93328358 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -1446,13 +1446,13 @@ static int __create_synth_event(const char *name, const char *raw_fields)
if (cmd_version > 1 && n_fields_this_loop >= 1) {
synth_err(SYNTH_ERR_INVALID_CMD, errpos(field_str));
ret = -EINVAL;
- goto err_free_arg;
+ goto err_free_field;
}
if (n_fields == SYNTH_FIELDS_MAX) {
synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0);
ret = -EINVAL;
- goto err_free_arg;
+ goto err_free_field;
}
fields[n_fields++] = field;
@@ -1491,6 +1491,8 @@ static int __create_synth_event(const char *name, const char *raw_fields)
kfree(saved_fields);
return ret;
+ err_free_field:
+ free_synth_field(field);
err_free_arg:
argv_free(argv);
err:
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Andy Shevchenko @ 2026-06-03 5:46 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Arnd Bergmann, Steven Rostedt, Andrew Morton, Petr Mladek,
Nathan Chancellor, Arnd Bergmann, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Arend van Spriel,
Miri Korenblit, Mathieu Desnoyers, Rasmus Villemoes,
Sergey Senozhatsky, Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka, linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <20260603105842.1e0ef8cb4a55cb776d6a4971@kernel.org>
On Wed, Jun 03, 2026 at 10:58:42AM +0900, Masami Hiramatsu wrote:
> On Tue, 2 Jun 2026 17:07:05 +0200
> Arnd Bergmann <arnd@kernel.org> wrote:
...
> I think this is a slightly confusing name. What about vsnprintf_nocheck()?
What check? If you want to be more precise: vsnprintf_no_printf_attr() or
vsnprintf_no_format_check(). But they also seem to me not the good choices.
(Just slight preference to the latter one no_format_check.)
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [LSF/MM/BPF TOPIC][RFC PATCH v4 00/27] Private Memory Nodes (w/ Compressed RAM)
From: Balbir Singh @ 2026-06-03 5:00 UTC (permalink / raw)
To: Gregory Price
Cc: lsf-pc, linux-kernel, linux-cxl, cgroups, linux-mm,
linux-trace-kernel, damon, kernel-team, gregkh, rafael, dakr,
dave, jonathan.cameron, dave.jiang, alison.schofield,
vishal.l.verma, ira.weiny, dan.j.williams, longman, akpm, david,
lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko,
osalvador, ziy, matthew.brost, joshua.hahnjy, rakie.kim,
byungchul, ying.huang, apopple, axelrasmussen, yuanchu, weixugc,
yury.norov, linux, mhiramat, mathieu.desnoyers, tj, hannes,
mkoutny, jackmanb, sj, baolin.wang, npache, ryan.roberts,
dev.jain, baohua, lance.yang, muchun.song, xu.xin16,
chengming.zhou, jannh, linmiaohe, nao.horiguchi, pfalcato,
rientjes, shakeel.butt, riel, harry.yoo, cl, roman.gushchin,
chrisl, kasong, shikemeng, nphamcs, bhe, zhengqi.arch,
terry.bowman
In-Reply-To: <ah6bDNxlB1zBUnzN@gourry-fedora-PF4VCD3F>
On Tue, Jun 02, 2026 at 09:57:48AM +0100, Gregory Price wrote:
> On Tue, Jun 02, 2026 at 12:16:50PM +1000, Balbir Singh wrote:
> > On Sun, May 24, 2026 at 09:50:06PM -0400, Gregory Price wrote:
> > >
> > > I'm debating on whether to include OPS_MEMPOLICY in the initial version
> > > if only because it's not intuitive how it interacts with pagecache. That
> > > needs more time to bake.
> > >
> >
> > It makes sense to look at it and then decide if it makes sense.
> >
>
> I am thinking i will ship without any OPS flags at all for now and the
> have the introduction of ops as a separate series.
>
> > > alloc_pages_node() is the kernel interface
> >
> > I was think we wouldn't need explicit flags and that allocations would
> > happen from user space using __GFP_THISNODE to the node or via a nodemask
> > based on nodes of interest. Is there a reason to add this flag, a system
> > might have more than one source of N_MEMORY_PRIVATE?
> >
>
> There's a few things to unpack here. I discussed this many times on
> list and at LSF, but to reiterate.
>
> 1) __GFP_THISNODE is insufficient to enforce isolation and otherwise
> not particularly useful. Additionally, from userland, it's not
> something you can actually set.
I was thinking mbind()/mempolicy() is how we get to it. It already
accepts a nodemask.
>
> for node in possible_nodes:
> alloc_pages_node(private_node, __GFP_THISNODE)
>
> In fact it's the opposite semantic of what we want.
> THISNODE says: "Do not fallback back to OTHER nodes".
>
That's why we need to control the fallback nodes carefully for
N_MEMORY_PRIVATE
> The semantic we want is "Do not allow allocations from private
> nodes UNLESS we specifically request" (__GFP_PRIVATE).
>
> __GFP_THISNODE does not actually buy you anything here, AND it's
> worse, in the scenario where a private node makes its way into the
> preferred slot (via possible_nodes or some other nodemask), the
> allocator cannot fall back to a node it can access.
>
> __GFP_THISNODE cannot be overloaded to do anything useful here.
Let me clarify, I meant to say, let's use a nodemask for allocation
and __GFP_THISNODE gets us to the node we desire, if that is the only
node. My earlier comment might not have been clear.
>
> 2) We're trying not to expose *ANY* userland APIs for this, at all.
>
> The ultimate goal here should be one of two things:
>
> 1) fd = open(/dev/xxx, ...);
> mem = mmap(fd, ...);
> mem[0] = 0xDEADBEEF; /* Fault device page into page table */
>
> In this case, the driver is responsible for doing the
> alloc_pages_node() call.
>
> or
>
> 2) mem = mmap(NULL, ..., ANON);
> mbind(mem, ..., private_node);
> mem[0] = 0xDEADBEEF; /* Fault device page into page table */
>
> in this case mempolicy.c is responsible for doing the
> alloc_pages_node() call via the _mpol() alloc variants.
>
> Addition OPT flags (reclaim, compaction, whatever), would
> (optionally) allow mm/ to operate on the device memory with, for
> example, mmu_notifier callbacks to tell the device to invalidate
> whatever it's caching about that page.
>
> This would all be relatively transparent the userland, all userland
> "knows" is that it's getting memory from a device (/dev/xxx) or a
> node it's otherwise aware of hosting device memory somehow.
>
Why not use mbind() API's? Do we want to gate allocation/privileges
via a /dev?
Balbir
^ permalink raw reply
* Re: [PATCH v8 2/6] mm/memory-failure: surface unhandlable kernel pages as -ENOTRECOVERABLE
From: Miaohe Lin @ 2026-06-03 2:33 UTC (permalink / raw)
To: David Hildenbrand (Arm), Breno Leitao
Cc: linux-mm, linux-kernel, linux-doc, linux-kselftest,
linux-trace-kernel, kernel-team, Lance Yang, Andrew Morton,
Lorenzo Stoakes, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Shuah Khan, Naoya Horiguchi,
Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Jonathan Corbet, Shuah Khan, Liam R. Howlett
In-Reply-To: <21732071-14a1-486a-951c-34de97b7c757@kernel.org>
On 2026/6/2 17:41, David Hildenbrand (Arm) wrote:
> On 6/2/26 05:08, Miaohe Lin wrote:
>> On 2026/6/1 21:22, David Hildenbrand (Arm) wrote:
>>> On 6/1/26 14:28, Miaohe Lin wrote:
>>>>
>>>> Thanks for your patch.
>>>>
>>>>
>>>> Once shake_page finds a lightweight range-based way to shrink slab, slab pages could be freed
>>>> into buddy and above PageSlab test should be removed then. Maybe add a TODO or XXX here?
>>>>
>>>>
>>>> I'm not sure but is it safe or a common way to test PageReserved, PageSlab,
>>>> PageTable and PageLargeKmalloc without extra page refcnt?
>>>
>>> Checking typed pages in a racy fashion is fine (PageSlab, PageTable,
>>> PageLargeKmalloc).
>>
>> Got it. Thanks.
>>
>>> Checking PageReserved in a racy fashion is fine as well. TESTPAGEFLAG() will
>>> allow checking it on compound pages.
>>
>> It seems PageReserved is not intended to be set on compound pages. I see there are PF_NO_COMPOUND
>> in its definition: PAGEFLAG(Reserved, reserved, PF_NO_COMPOUND).
>>
>>>
>>> For PageLargeKmalloc, we would want to check the head page, though. The page
>>> type is only stored for the head page.
>>
>> Maybe we should check the head page for PageSlab and PageTable too? alloc_slab_page only
>> set PageSlab on the head page and __pagetable_ctor uses __folio_set_pgtable to set PageTable
>> on folio.
>>
>>>
>>> So maybe we want to lookup the compound head (if any) and perform the type
>>> checks against that?
>>
>> Maybe we should or we might miss some pages that could have been handled. And
>> if compound head is required, should we hold an extra page refcnt to guard against
>> possible folio split race?
>
> Races are fine. We might miss some pages, but that can happen on races either way.
>
>
> I'd just do something like
>
> if (PageReserved(page))
> return true;
>
> head = compound_head(page);
If @head is split just after compound_head. And then @head is freed into buddy and re-allocated as slab
page while @page is still in the buddy. We would panic on this scene as @head is PageSlab. But we were
supposed to successfully handle @page. Or am I miss something?
Thanks.
.
> return PageSlab(head) || ...;
>
>
^ permalink raw reply
* Re: [PATCH v2 1/8] scripts/sorttable: Handle RISC-V patchable ftrace entries
From: Shuai Xue @ 2026-06-03 2:10 UTC (permalink / raw)
To: Steven Rostedt
Cc: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Masami Hiramatsu, Mark Rutland, Catalin Marinas,
Chen Pei, Andy Chiu, Björn Töpel, Deepak Gupta,
Puranjay Mohan, Conor Dooley, Josh Poimboeuf, Jiri Kosina,
Miroslav Benes, Petr Mladek, Joe Lawrence, Shuah Khan,
Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, oliver.yang, zhuo.song, jkchen, linux-riscv,
linux-kernel, linux-trace-kernel, live-patching, linux-kselftest,
linux-perf-users
In-Reply-To: <20260601095746.70c01d24@fedora>
On 6/1/26 9:57 PM, Steven Rostedt wrote:
> On Mon, 1 Jun 2026 14:17:08 +0800
> Shuai Xue <xueshuai@linux.alibaba.com> wrote:
>
>>> diff --git a/scripts/sorttable.c b/scripts/sorttable.c
>>> index e8ed11c680c6..4c10e85bb5af 100644
>>> --- a/scripts/sorttable.c
>>> +++ b/scripts/sorttable.c
>>> @@ -891,17 +891,21 @@ static int do_file(char const *const fname, void *addr)
>>> table_sort_t custom_sort = NULL;
>>>
>>> switch (elf_map_machine(ehdr)) {
>>> - case EM_AARCH64:
>>> #ifdef MCOUNT_SORT_ENABLED
>>> + case EM_AARCH64:
>>> sort_reloc = true;
>>> rela_type = 0x403;
>>> - /* arm64 uses patchable function entry placing before function */
>>> + /* fallthrough */
>>> + case EM_RISCV:
>>> + /* arm64 and RISC-V place patchable entries before the function */
>>> before_func = 8;
>>
>> Nit: The shared comment now sits under `case EM_RISCV:` but the two
>> lines above it (sort_reloc / rela_type = 0x403) are strictly
>> arm64-only — they configure the RELA-based weak-function fixup that
>> RISC-V does not need. On a quick read it is easy to wonder if RISC-V
>> is implicitly inheriting that path. Splitting the comments would
>> help, e.g.:
>>
>> case EM_AARCH64:
>> /* arm64 needs RELA-based weak-function fixup */
>> sort_reloc = true;
>> rela_type = 0x403;
>> /* fallthrough */
>> case EM_RISCV:
>> /* arm64 and RISC-V place patchable entries before the function */
>> before_func = 8;
>
> Makes sense.
>
> Care to send a v3?
>
> -- Steve
Hi, Steve,
It's a pure comment cosmetic, not worth a respin on its own. But for the
rest of the feedback on this series (the frame-record metadata contract
in patch 2 and the dead state->regs field / Call Trace output change in
patch 6) are the ones actually worth a new version.
Just to get the routing straight: are you planning to pick this one up
through the tracing tree on its own?
It feels like a good candidate for that -- it's an independent
regression fix (Fixes: 0ca1724b56af) that breaks *all* RISC-V dynamic
ftrace, not just livepatch, so it shouldn't have to wait on the rest of
the livepatch series.
Thanks.
Shuai
^ permalink raw reply
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Masami Hiramatsu @ 2026-06-03 1:58 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Steven Rostedt, Andrew Morton, Petr Mladek, Nathan Chancellor,
Arnd Bergmann, Dennis Dalessandro, Jason Gunthorpe,
Leon Romanovsky, Arend van Spriel, Miri Korenblit,
Mathieu Desnoyers, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka, linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <20260602150904.2258624-1-arnd@kernel.org>
On Tue, 2 Jun 2026 17:07:05 +0200
Arnd Bergmann <arnd@kernel.org> wrote:
> diff --git a/include/linux/sprintf.h b/include/linux/sprintf.h
> index f06f7b785091..036a247b7c1e 100644
> --- a/include/linux/sprintf.h
> +++ b/include/linux/sprintf.h
> @@ -12,6 +12,7 @@ __printf(2, 3) int sprintf(char *buf, const char * fmt, ...);
> __printf(2, 0) int vsprintf(char *buf, const char *, va_list);
> __printf(3, 4) int snprintf(char *buf, size_t size, const char *fmt, ...);
> __printf(3, 0) int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
> +int __vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
> __printf(3, 4) int scnprintf(char *buf, size_t size, const char *fmt, ...);
> __printf(3, 0) int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
> __printf(2, 3) __malloc char *kasprintf(gfp_t gfp, const char *fmt, ...);
> diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
> index d49338c44014..4715330c7b6b 100644
> --- a/include/linux/trace_events.h
> +++ b/include/linux/trace_events.h
> @@ -962,7 +962,7 @@ perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type,
> int __ret; \
> \
> va_copy(__ap, *(va)); \
> - __ret = vsnprintf(NULL, 0, fmt, __ap) + 1; \
> + __ret = __vsnprintf(NULL, 0, fmt, __ap) + 1; \
> va_end(__ap); \
> \
> min(__ret, TRACE_EVENT_STR_MAX); \
I think this is a slightly confusing name. What about vsnprintf_nocheck()?
Thanks,
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH v2 8/8] selftests/livepatch: Add RISC-V syscall wrapper prefix
From: Shuai Xue @ 2026-06-03 1:54 UTC (permalink / raw)
To: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou
Cc: Steven Rostedt, Alexandre Ghiti, Masami Hiramatsu, Mark Rutland,
Catalin Marinas, Chen Pei, Andy Chiu, Björn Töpel,
Deepak Gupta, Puranjay Mohan, Conor Dooley, Josh Poimboeuf,
Jiri Kosina, Miroslav Benes, Petr Mladek, Joe Lawrence,
Shuah Khan, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, oliver.yang, zhuo.song, jkchen, linux-riscv,
linux-kernel, linux-trace-kernel, live-patching, linux-kselftest,
linux-perf-users
In-Reply-To: <20260528082310.1994388-9-wanghan@linux.alibaba.com>
On 5/28/26 4:23 PM, Wang Han wrote:
> The syscall livepatch selftest resolves and patches a syscall wrapper
> symbol. To use that test for RISC-V livepatch validation, add the
> RISC-V FN_PREFIX definition for ARCH_HAS_SYSCALL_WRAPPER.
>
> Without this macro, the syscall livepatch selftest cannot resolve the
> RISC-V target symbol, and the syscall-related livepatch test fails on
> RISC-V.
>
> Signed-off-by: Wang Han <wanghan@linux.alibaba.com>
> ---
> .../testing/selftests/livepatch/test_modules/test_klp_syscall.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
> index dd802783ea84..275e4b10cf59 100644
> --- a/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
> +++ b/tools/testing/selftests/livepatch/test_modules/test_klp_syscall.c
> @@ -18,6 +18,8 @@
> #define FN_PREFIX __s390x_
> #elif defined(__aarch64__)
> #define FN_PREFIX __arm64_
> +#elif defined(__riscv)
> +#define FN_PREFIX __riscv_
> #else
> /* powerpc does not select ARCH_HAS_SYSCALL_WRAPPER */
> #define FN_PREFIX
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Thanks.
Shuai
^ permalink raw reply
* Re: [PATCH v2 7/8] riscv: Kconfig: enable HAVE_RELIABLE_STACKTRACE and HAVE_LIVEPATCH
From: Shuai Xue @ 2026-06-03 1:49 UTC (permalink / raw)
To: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou
Cc: Steven Rostedt, Alexandre Ghiti, Masami Hiramatsu, Mark Rutland,
Catalin Marinas, Chen Pei, Andy Chiu, Björn Töpel,
Deepak Gupta, Puranjay Mohan, Conor Dooley, Josh Poimboeuf,
Jiri Kosina, Miroslav Benes, Petr Mladek, Joe Lawrence,
Shuah Khan, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, oliver.yang, zhuo.song, jkchen, linux-riscv,
linux-kernel, linux-trace-kernel, live-patching, linux-kselftest,
linux-perf-users
In-Reply-To: <20260528082310.1994388-8-wanghan@linux.alibaba.com>
On 5/28/26 4:23 PM, Wang Han wrote:
> Now that the metadata frame records, the kunwind state machine and
> arch_stack_walk_reliable() are all in place, advertise the capability
> to the rest of the kernel:
>
> * select HAVE_RELIABLE_STACKTRACE under FRAME_POINTER && 64BIT, so
> only the configurations that actually have the metadata records
> and the FP-based reliable walker enable it.
The 64BIT gate is conservative scoping rather than a hard technical
requirement: the metadata frame record, kunwind state machine and
arch_stack_walk_reliable() all build on RV32 too (and the
call_on_irq_stack change in patch 2/8 actually fixes a latent RV32
issue). However, the syscall livepatch selftest and module relocation
path have only been exercised on RV64 (QEMU virt SMP=2/4/8). The
64BIT gate can be dropped in a follow-up once RV32 has equivalent
coverage.
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Thanks.
Shuai
^ permalink raw reply
* Re: [PATCH v2 6/8] riscv: stacktrace: switch to frame-pointer based unwinder
From: Shuai Xue @ 2026-06-03 1:35 UTC (permalink / raw)
To: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou
Cc: Steven Rostedt, Alexandre Ghiti, Masami Hiramatsu, Mark Rutland,
Catalin Marinas, Chen Pei, Andy Chiu, Björn Töpel,
Deepak Gupta, Puranjay Mohan, Conor Dooley, Josh Poimboeuf,
Jiri Kosina, Miroslav Benes, Petr Mladek, Joe Lawrence,
Shuah Khan, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, oliver.yang, zhuo.song, jkchen, linux-riscv,
linux-kernel, linux-trace-kernel, live-patching, linux-kselftest,
linux-perf-users
In-Reply-To: <20260528082310.1994388-7-wanghan@linux.alibaba.com>
On 5/28/26 4:23 PM, Wang Han wrote:
> Replace the open-coded frame-pointer walker in arch_stack_walk() with a
> robust kunwind state machine, modelled on arch/arm64/kernel/stacktrace.c
> and retargeted to the RISC-V {fp, ra} frame record convention. The new
> walker tracks stack bounds, consumes frame records monotonically,
> understands the metadata pt_regs records added in the previous frame
> record metadata patch, and recovers return addresses replaced by
> function graph tracing and kretprobes.
>
> This commit introduces arch_stack_walk_reliable() but does not yet
> select HAVE_RELIABLE_STACKTRACE; that is done in a follow-up Kconfig
> patch so this commit can be reviewed and bisected as a pure unwinder
> replacement. Until that Kconfig change lands, livepatch is not yet
> enabled and arch_stack_walk_reliable() has no in-tree caller.
>
> Three related callers are updated to keep the same frame-record
> assumptions everywhere:
>
> * Function graph tracing: the old RISC-V unwinder matched function
> graph return-stack entries by the saved return-address slot. That
> was consistent with the static mcount path, but not with the dynamic
> ftrace path where the parent slot is ftrace_regs::ra. Use the
> architectural frame pointer as the function graph return-address
> cookie, matching the kunwind walker.
>
> * Perf callchains: route kernel callchain collection through
> arch_stack_walk() so perf sees the same frame-pointer unwind
> behaviour as dump_stack() and the upcoming livepatch path.
>
> * dump_backtrace() / __get_wchan() / show_stack(): these now go
> through arch_stack_walk(); the explicit "Call Trace:" header is
> moved into dump_backtrace() to preserve the original output.
>
> The non-frame-pointer fallback walker is kept untouched for
> !CONFIG_FRAME_POINTER builds.
>
> Signed-off-by: Wang Han <wanghan@linux.alibaba.com>
> ---
> arch/riscv/kernel/ftrace.c | 6 +-
> arch/riscv/kernel/perf_callchain.c | 2 +-
> arch/riscv/kernel/stacktrace.c | 560 ++++++++++++++++++++++++-----
> 3 files changed, 472 insertions(+), 96 deletions(-)
>
> diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
> index b430edfb83f4..5d55199a9230 100644
> --- a/arch/riscv/kernel/ftrace.c
> +++ b/arch/riscv/kernel/ftrace.c
> @@ -242,7 +242,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
> */
> old = *parent;
>
> - if (!function_graph_enter(old, self_addr, frame_pointer, parent))
> + if (!function_graph_enter(old, self_addr, frame_pointer,
> + (void *)frame_pointer))
> *parent = return_hooker;
> }
>
> @@ -264,7 +265,8 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
> */
> old = *parent;
>
> - if (!function_graph_enter_regs(old, ip, frame_pointer, parent, fregs))
> + if (!function_graph_enter_regs(old, ip, frame_pointer,
> + (void *)frame_pointer, fregs))
> *parent = return_hooker;
> }
> #endif /* CONFIG_DYNAMIC_FTRACE */
> diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
> index b465bc9eb870..436af96ea59c 100644
> --- a/arch/riscv/kernel/perf_callchain.c
> +++ b/arch/riscv/kernel/perf_callchain.c
> @@ -44,5 +44,5 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
> return;
> }
>
> - walk_stackframe(NULL, regs, fill_callchain, entry);
> + arch_stack_walk(fill_callchain, entry, NULL, regs);
> }
> diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
> index 2692d3a06afa..0d76320b3a29 100644
> --- a/arch/riscv/kernel/stacktrace.c
> +++ b/arch/riscv/kernel/stacktrace.c
> @@ -11,98 +11,16 @@
> #include <linux/sched/task_stack.h>
> #include <linux/stacktrace.h>
> #include <linux/ftrace.h>
> +#include <linux/kprobes.h>
> +#include <linux/llist.h>
>
> #include <asm/stacktrace.h>
>
> -#ifdef CONFIG_FRAME_POINTER
> -
> /*
> - * This disables KASAN checking when reading a value from another task's stack,
> - * since the other task could be running on another CPU and could have poisoned
> - * the stack in the meantime.
> + * Non-frame-pointer fallback unwinder.
> + * Only compiled when CONFIG_FRAME_POINTER is not enabled.
> */
> -#define READ_ONCE_TASK_STACK(task, x) \
> -({ \
> - unsigned long val; \
> - unsigned long addr = x; \
> - if ((task) == current) \
> - val = READ_ONCE(addr); \
> - else \
> - val = READ_ONCE_NOCHECK(addr); \
> - val; \
> -})
> -
> -extern asmlinkage void handle_exception(void);
> -extern unsigned long ret_from_exception_end;
> -
> -static inline int fp_is_valid(unsigned long fp, unsigned long sp)
> -{
> - unsigned long low, high;
> -
> - low = sp + sizeof(struct stackframe);
> - high = ALIGN(sp, THREAD_SIZE);
> -
> - return !(fp < low || fp > high || fp & 0x07);
> -}
> -
> -void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
> - bool (*fn)(void *, unsigned long), void *arg)
> -{
> - unsigned long fp, sp, pc;
> - int graph_idx = 0;
> - int level = 0;
> -
> - if (regs) {
> - fp = frame_pointer(regs);
> - sp = user_stack_pointer(regs);
> - pc = instruction_pointer(regs);
> - } else if (task == NULL || task == current) {
> - fp = (unsigned long)__builtin_frame_address(0);
> - sp = current_stack_pointer;
> - pc = (unsigned long)walk_stackframe;
> - level = -1;
> - } else {
> - /* task blocked in __switch_to */
> - fp = task->thread.s[0];
> - sp = task->thread.sp;
> - pc = task->thread.ra;
> - }
> -
> - for (;;) {
> - struct stackframe *frame;
> -
> - if (unlikely(!__kernel_text_address(pc) || (level++ >= 0 && !fn(arg, pc))))
> - break;
> -
> - if (unlikely(!fp_is_valid(fp, sp)))
> - break;
> -
> - /* Unwind stack frame */
> - frame = (struct stackframe *)fp - 1;
> - sp = fp;
> - if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) {
> - /* We hit function where ra is not saved on the stack */
> - fp = frame->ra;
> - pc = regs->ra;
> - } else {
> - fp = READ_ONCE_TASK_STACK(task, frame->fp);
> - pc = READ_ONCE_TASK_STACK(task, frame->ra);
> - pc = ftrace_graph_ret_addr(task, &graph_idx, pc,
> - &frame->ra);
> - if (pc >= (unsigned long)handle_exception &&
> - pc < (unsigned long)&ret_from_exception_end) {
> - if (unlikely(!fn(arg, pc)))
> - break;
> -
> - pc = ((struct pt_regs *)sp)->epc;
> - fp = ((struct pt_regs *)sp)->s0;
> - }
> - }
> -
> - }
> -}
> -
> -#else /* !CONFIG_FRAME_POINTER */
> +#ifndef CONFIG_FRAME_POINTER
>
> void notrace walk_stackframe(struct task_struct *task,
> struct pt_regs *regs, bool (*fn)(void *, unsigned long), void *arg)
> @@ -133,7 +51,12 @@ void notrace walk_stackframe(struct task_struct *task,
> }
> }
>
> -#endif /* CONFIG_FRAME_POINTER */
> +#endif /* !CONFIG_FRAME_POINTER */
> +
> +/*
> + * Common trace helpers.
> + * These are used by both the FP (kunwind) and non-FP (walk_stackframe) paths.
> + */
>
> static bool print_trace_address(void *arg, unsigned long pc)
> {
> @@ -146,12 +69,12 @@ static bool print_trace_address(void *arg, unsigned long pc)
> noinline void dump_backtrace(struct pt_regs *regs, struct task_struct *task,
> const char *loglvl)
> {
> - walk_stackframe(task, regs, print_trace_address, (void *)loglvl);
> + printk("%sCall Trace:\n", loglvl);
> + arch_stack_walk(print_trace_address, (void *)loglvl, task, regs);
> }
>
> void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
> {
> - pr_cont("%sCall Trace:\n", loglvl);
> dump_backtrace(NULL, task, loglvl);
> }
>
> @@ -171,17 +94,468 @@ unsigned long __get_wchan(struct task_struct *task)
>
> if (!try_get_task_stack(task))
> return 0;
> - walk_stackframe(task, NULL, save_wchan, &pc);
> + arch_stack_walk(save_wchan, &pc, task, NULL);
> put_task_stack(task);
> return pc;
> }
>
> -noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
> - struct task_struct *task, struct pt_regs *regs)
> +/*
> + * Frame-pointer-based kernel unwind infrastructure.
> + * Only compiled when CONFIG_FRAME_POINTER is enabled.
> + *
> + * See: arch/arm64/kernel/stacktrace.c for the reference implementation.
> + */
> +#ifdef CONFIG_FRAME_POINTER
> +
> +/*
> + * Per-cpu stacks are only accessible when unwinding the current task in a
> + * non-preemptible context.
> + */
> +#define STACKINFO_CPU(task, name) \
> + ({ \
> + (((task) == current) && !preemptible()) \
> + ? stackinfo_get_##name() \
> + : stackinfo_get_unknown(); \
> + })
> +
> +enum kunwind_source {
> + KUNWIND_SOURCE_UNKNOWN,
> + KUNWIND_SOURCE_FRAME,
> + KUNWIND_SOURCE_CALLER,
> + KUNWIND_SOURCE_TASK,
> + KUNWIND_SOURCE_REGS_PC,
> +};
> +
> +union unwind_flags {
> + unsigned long all;
> + struct {
> + unsigned long fgraph : 1,
> + kretprobe : 1;
> + };
> +};
> +
> +/*
> + * Kernel unwind state
> + *
> + * @common: Common unwind state.
> + * @task: The task being unwound.
> + * @graph_idx: Used by ftrace_graph_ret_addr() for optimized stack unwinding.
> + * @kr_cur: When KRETPROBES is selected, holds the kretprobe instance
> + * associated with the most recently encountered replacement ra
> + * value.
> + */
> +struct kunwind_state {
> + struct unwind_state common;
> + struct task_struct *task;
> + int graph_idx;
> +#ifdef CONFIG_KRETPROBES
> + struct llist_node *kr_cur;
> +#endif
> + enum kunwind_source source;
> + union unwind_flags flags;
> + struct pt_regs *regs;
> +};
> +
> +static __always_inline void
> +kunwind_init(struct kunwind_state *state,
> + struct task_struct *task)
> +{
> + unwind_init_common(&state->common);
> + state->task = task;
> + state->source = KUNWIND_SOURCE_UNKNOWN;
> + state->flags.all = 0;
> + state->regs = NULL;
> +}
> +
> +/*
> + * Start an unwind from a pt_regs.
> + *
> + * The unwind will begin at the PC within the regs.
> + *
> + * The regs must be on a stack currently owned by the calling task.
> + */
> +static __always_inline void
> +kunwind_init_from_regs(struct kunwind_state *state,
> + struct pt_regs *regs)
> +{
> + kunwind_init(state, current);
> +
> + state->regs = regs;
> + state->common.fp = frame_pointer(regs);
> + state->common.pc = instruction_pointer(regs);
> + state->source = KUNWIND_SOURCE_REGS_PC;
> +}
> +
> +/*
> + * Start an unwind from a caller.
> + *
> + * The unwind will begin at the caller of whichever function this is inlined
> + * into.
> + *
> + * The function which invokes this must be noinline.
> + */
> +static __always_inline void
> +kunwind_init_from_caller(struct kunwind_state *state)
> +{
> + unsigned long fp = (unsigned long)__builtin_frame_address(0);
> + struct frame_record *record = (struct frame_record *)fp - 1;
> +
> + kunwind_init(state, current);
> +
> + state->common.fp = READ_ONCE(record->fp);
> + state->common.pc = READ_ONCE(record->ra);
> + state->source = KUNWIND_SOURCE_CALLER;
> +}
> +
> +/*
> + * Start an unwind from a blocked task.
> + *
> + * The unwind will begin at the blocked task's saved PC (i.e. the caller of
> + * __switch_to).
> + *
> + * The caller should ensure the task is blocked in __switch_to for the
> + * duration of the unwind, or the unwind will be bogus. It is never valid to
> + * call this for the current task.
> + */
> +static __always_inline void
> +kunwind_init_from_task(struct kunwind_state *state,
> + struct task_struct *task)
> +{
> + kunwind_init(state, task);
> +
> + state->common.fp = task->thread.s[0];
> + state->common.pc = task->thread.ra;
> + state->source = KUNWIND_SOURCE_TASK;
> +}
> +
> +static __always_inline int
> +kunwind_recover_return_address(struct kunwind_state *state)
> +{
> +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> + if (state->task->ret_stack &&
> + state->common.pc == (unsigned long)return_to_handler) {
> + unsigned long orig_pc;
> +
> + orig_pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
> + state->common.pc,
> + (void *)state->common.fp);
> + if (state->common.pc == orig_pc) {
> + WARN_ON_ONCE(state->task == current);
> + return -EINVAL;
> + }
> + state->common.pc = orig_pc;
> + state->flags.fgraph = 1;
> + }
> +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
> +
> +#ifdef CONFIG_KRETPROBES
> + if (is_kretprobe_trampoline(state->common.pc)) {
> + unsigned long orig_pc;
> +
> + orig_pc = kretprobe_find_ret_addr(state->task,
> + (void *)state->common.fp,
> + &state->kr_cur);
> + if (!orig_pc)
> + return -EINVAL;
> + state->common.pc = orig_pc;
> + state->flags.kretprobe = 1;
> + }
> +#endif /* CONFIG_KRETPROBES */
> +
> + return 0;
> +}
> +
> +/*
> + * When we reach an exception boundary marked by a metadata frame record,
> + * extract pt_regs from the stack and continue unwinding from the saved
> + * context (epc and s0/fp).
> + *
> + * On RISC-V, fp points above the metadata record, so the record's
> + * frame_record portion is at fp - sizeof(struct frame_record).
> + */
> +static __always_inline int
> +kunwind_next_regs_pc(struct kunwind_state *state)
> +{
> + struct stack_info *info;
> + unsigned long fp = state->common.fp;
> + struct pt_regs *regs;
> +
> + regs = container_of((unsigned long *)(fp - sizeof(struct frame_record)),
> + struct pt_regs, stackframe.record.fp);
> +
> + info = unwind_find_stack(&state->common, (unsigned long)regs,
> + sizeof(*regs));
> + if (!info)
> + return -EINVAL;
> +
> + unwind_consume_stack(&state->common, info, (unsigned long)regs,
> + sizeof(*regs));
> +
> + state->regs = regs;
> + state->common.pc = regs->epc;
> + state->common.fp = frame_pointer(regs);
> + state->regs = NULL;
state->regs is a dead field, and kunwind_next_regs_pc() clears
it in a way that contradicts both arm64 and your own
init_from_regs.
struct kunwind_state has a `struct pt_regs *regs`, but I can't find any
reader of it anywhere in the file — arch_kunwind_consume_entry() and
arch_reliable_kunwind_consume_entry() only ever read common.pc and
source. It is written in three places:
kunwind_init(): state->regs = NULL;
kunwind_init_from_regs(): state->regs = regs; /* not cleared */
kunwind_next_regs_pc(): state->regs = regs;
state->common.pc = regs->epc;
state->common.fp = frame_pointer(regs);
state->regs = NULL; /* cleared! */
Two things:
(a) The field has no consumer, so it's currently dead.
(b) In kunwind_next_regs_pc() you set state->regs = regs and then
immediately reset it to NULL two lines later. The arm64 reference
does *not* clear it there, and your own kunwind_init_from_regs()
leaves it set. So the three REGS_PC producers disagree on whether
->regs is valid.
It's harmless today only because nothing reads ->regs. But the moment
someone adds a consumer (e.g. to expose the pt_regs at an exception
boundary for a reliable dump), the stray `state->regs = NULL;` in
kunwind_next_regs_pc() becomes a silent bug.
Please either:
- drop the field and all three writes, if it's genuinely unused, or
- keep it and remove the `state->regs = NULL;` in
kunwind_next_regs_pc() so it matches arm64 and init_from_regs.
> + state->source = KUNWIND_SOURCE_REGS_PC;
> + return 0;
> +}
> +
> +/*
> + * Handle a metadata frame record embedded in pt_regs.
> + *
> + * On RISC-V, fp points above the record (fp = metadata + 16), so the
> + * frame_record_meta starts at fp - sizeof(struct frame_record).
> + *
> + * FRAME_META_TYPE_FINAL: This is the outermost exception entry
> + * (user -> kernel). Unwinding terminates successfully.
> + * FRAME_META_TYPE_PT_REGS: This is a nested exception entry
> + * (kernel -> kernel). Continue unwinding from the saved context.
> + */
> +static __always_inline int
> +kunwind_next_frame_record_meta(struct kunwind_state *state)
> +{
> + struct task_struct *tsk = state->task;
> + unsigned long fp = state->common.fp;
> + unsigned long meta_base = fp - sizeof(struct frame_record);
> + struct frame_record_meta *meta;
> + struct stack_info *info;
> +
> + info = unwind_find_stack(&state->common, meta_base, sizeof(*meta));
> + if (!info)
> + return -EINVAL;
> +
> + meta = (struct frame_record_meta *)meta_base;
> + switch (READ_ONCE(meta->type)) {
> + case FRAME_META_TYPE_FINAL:
> + if (meta == &task_pt_regs(tsk)->stackframe)
> + return -ENOENT;
> + WARN_ON_ONCE(tsk == current);
> + return -EINVAL;
> + case FRAME_META_TYPE_PT_REGS:
> + return kunwind_next_regs_pc(state);
> + default:
> + WARN_ON_ONCE(tsk == current);
> + return -EINVAL;
> + }
> +}
> +
> +/*
> + * Unwind from one frame record to the next.
> + *
> + * On RISC-V, the frame record sits at fp - sizeof(struct frame_record),
> + * immediately below the address pointed to by fp/s0. This applies to both
> + * normal frame records and metadata frame records (embedded in pt_regs).
> + *
> + * A metadata record is identified by both fp and ra being zero in the
> + * frame_record portion, with a type value following at fp + 16.
> + */
> +static __always_inline int
> +kunwind_next_frame_record(struct kunwind_state *state)
> +{
> + unsigned long fp = state->common.fp;
> + struct frame_record *record;
> + struct stack_info *info;
> + unsigned long new_fp, new_pc;
> + unsigned long record_base;
> +
> + if (fp & 0x7)
> + return -EINVAL;
> +
> + record_base = fp - sizeof(*record);
> +
> + info = unwind_find_stack(&state->common, record_base, sizeof(*record));
> + if (!info)
> + return -EINVAL;
> +
> + record = (struct frame_record *)record_base;
> + new_fp = READ_ONCE(record->fp);
> + new_pc = READ_ONCE(record->ra);
> +
> + if (!new_fp && !new_pc)
> + return kunwind_next_frame_record_meta(state);
> +
> + unwind_consume_stack(&state->common, info, record_base,
> + sizeof(*record));
> +
> + state->common.fp = new_fp;
> + state->common.pc = new_pc;
> + state->source = KUNWIND_SOURCE_FRAME;
> +
> + return 0;
> +}
> +
> +/*
> + * Unwind from one frame record (A) to the next frame record (B).
> + *
> + * We terminate early if the location of B indicates a malformed chain of frame
> + * records (e.g. a cycle), determined based on the location and fp value of A
> + * and the location (but not the fp value) of B.
> + */
> +static __always_inline int
> +kunwind_next(struct kunwind_state *state)
> +{
> + int err;
> +
> + state->flags.all = 0;
> +
> + switch (state->source) {
> + case KUNWIND_SOURCE_FRAME:
> + case KUNWIND_SOURCE_CALLER:
> + case KUNWIND_SOURCE_TASK:
> + case KUNWIND_SOURCE_REGS_PC:
> + err = kunwind_next_frame_record(state);
> + break;
> + default:
> + err = -EINVAL;
> + }
> +
> + if (err)
> + return err;
> +
> + return kunwind_recover_return_address(state);
> +}
> +
> +typedef bool (*kunwind_consume_fn)(const struct kunwind_state *state, void *cookie);
> +
> +static __always_inline int
> +do_kunwind(struct kunwind_state *state, kunwind_consume_fn consume_state,
> + void *cookie)
> +{
> + int ret;
> +
> + ret = kunwind_recover_return_address(state);
> + if (ret)
> + return ret;
> +
> + while (1) {
> + if (!consume_state(state, cookie))
> + return -EINVAL;
> + ret = kunwind_next(state);
> + if (ret == -ENOENT)
> + return 0;
> + if (ret < 0)
> + return ret;
> + }
> +}
> +
> +static __always_inline int
> +kunwind_stack_walk(kunwind_consume_fn consume_state,
> + void *cookie, struct task_struct *task,
> + struct pt_regs *regs)
> +{
> + struct task_struct *tsk = task ?: current;
> + struct stack_info stacks[] = {
> + stackinfo_get_task(tsk),
> + STACKINFO_CPU(tsk, irq),
> +#ifdef CONFIG_VMAP_STACK
> + STACKINFO_CPU(tsk, overflow),
> +#endif
> + };
> + struct kunwind_state state = {
> + .common = {
> + .stacks = stacks,
> + .nr_stacks = ARRAY_SIZE(stacks),
> + },
> + };
> +
> + if (regs) {
> + if (tsk != current)
> + return -EINVAL;
> + kunwind_init_from_regs(&state, regs);
> + } else if (tsk == current) {
> + kunwind_init_from_caller(&state);
> + } else {
> + kunwind_init_from_task(&state, tsk);
> + }
> +
> + return do_kunwind(&state, consume_state, cookie);
> +}
> +
> +struct kunwind_consume_entry_data {
> + stack_trace_consume_fn consume_entry;
> + void *cookie;
> +};
> +
> +static __always_inline bool
> +arch_kunwind_consume_entry(const struct kunwind_state *state, void *cookie)
> +{
> + struct kunwind_consume_entry_data *data = cookie;
> +
> + return data->consume_entry(data->cookie, state->common.pc);
> +}
> +
> +static __always_inline bool
> +arch_reliable_kunwind_consume_entry(const struct kunwind_state *state, void *cookie)
> +{
> + /*
> + * At an exception boundary we can reliably consume the saved PC. We do
> + * not know whether the LR was live when the exception was taken, and
Nit: s/LR/ra/ here. RISC-V has no link register; the equivalent is the
return-address register ra (x1). You already localized this correctly in
the kr_cur docstring ("replacement ra value"), so this comment is just an
oversight.
Thanks.
Shuai
^ permalink raw reply
* Re: [syzbot] [trace?] KASAN: use-after-free Write in ring_buffer_read_page
From: Masami Hiramatsu @ 2026-06-03 1:34 UTC (permalink / raw)
To: Steven Rostedt
Cc: syzbot, linux-kernel, linux-trace-kernel, mathieu.desnoyers,
mhiramat, syzkaller-bugs
In-Reply-To: <20260602122829.4a91864f@gandalf.local.home>
On Tue, 2 Jun 2026 12:28:29 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Tue, 02 Jun 2026 06:45:31 -0700
> syzbot <syzbot+2dd9d02f60775ce5c1fb@syzkaller.appspotmail.com> wrote:
>
> > syzbot found the following issue on:
> >
> > HEAD commit: e7ae89a0c97c Linux 7.1-rc5
> > git tree: upstream
> > console output: https://syzkaller.appspot.com/x/log.txt?x=16f06e2e580000
> > kernel config: https://syzkaller.appspot.com/x/.config?x=58acee1ac5406016
> > dashboard link: https://syzkaller.appspot.com/bug?extid=2dd9d02f60775ce5c1fb
> > compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> >
> > Unfortunately, I don't have any reproducer for this issue yet.
>
> Looks like the test was doing something really weird to trigger this.
> Without a reproducer, it's pretty much impossible to find out what
> happened. Maybe AI could do it?
>
Does the "I don't have any reproducer for this issue yet." means
this is not reproducible even if it runs completely same sequence
in the console output? If so, might this be a timing related issue?
(e.g. read v.s. write-event)
Thanks,
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH v2 5/8] riscv: stacktrace: introduce stack-bound tracking helpers
From: Shuai Xue @ 2026-06-03 1:23 UTC (permalink / raw)
To: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou
Cc: Steven Rostedt, Alexandre Ghiti, Masami Hiramatsu, Mark Rutland,
Catalin Marinas, Chen Pei, Andy Chiu, Björn Töpel,
Deepak Gupta, Puranjay Mohan, Conor Dooley, Josh Poimboeuf,
Jiri Kosina, Miroslav Benes, Petr Mladek, Joe Lawrence,
Shuah Khan, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, oliver.yang, zhuo.song, jkchen, linux-riscv,
linux-kernel, linux-trace-kernel, live-patching, linux-kselftest,
linux-perf-users
In-Reply-To: <20260528082310.1994388-6-wanghan@linux.alibaba.com>
On 5/28/26 4:23 PM, Wang Han wrote:
> A reliable unwinder needs to validate that every frame record it reads
> is fully contained in a known kernel stack, and it needs to refuse to
> walk back into a stack it has already left. Add the building blocks
> for that:
>
> * struct stack_info / struct unwind_state in a new
> asm/stacktrace/common.h, modelled on the arm64 reference
> implementation.
> * stackinfo_get_irq() / stackinfo_get_task() / stackinfo_get_overflow()
> plus the corresponding on_*_stack() predicates in asm/stacktrace.h,
> so callers can ask "is this object on stack X?" by stack kind
> rather than open-coded address arithmetic.
> * unwind_init_common(), unwind_find_stack() and
> unwind_consume_stack() helpers that enforce the
> forward-progress-only invariant required for reliability.
>
> No existing user is wired up to these helpers in this commit; the
> unwinder switch comes in a follow-up. The header changes leave
> on_thread_stack() with the same semantics as before, just expressed in
> terms of the new helpers.
>
> Signed-off-by: Wang Han <wanghan@linux.alibaba.com>
> ---
> arch/riscv/include/asm/stacktrace.h | 65 ++++++++-
> arch/riscv/include/asm/stacktrace/common.h | 159 +++++++++++++++++++++
> 2 files changed, 222 insertions(+), 2 deletions(-)
> create mode 100644 arch/riscv/include/asm/stacktrace/common.h
>
> diff --git a/arch/riscv/include/asm/stacktrace.h b/arch/riscv/include/asm/stacktrace.h
> index b1495a7e06ce..bc87c4940379 100644
> --- a/arch/riscv/include/asm/stacktrace.h
> +++ b/arch/riscv/include/asm/stacktrace.h
> @@ -3,8 +3,13 @@
> #ifndef _ASM_RISCV_STACKTRACE_H
> #define _ASM_RISCV_STACKTRACE_H
>
> +#include <linux/percpu.h>
> #include <linux/sched.h>
> +#include <linux/sched/task_stack.h>
> +
> +#include <asm/irq_stack.h>
> #include <asm/ptrace.h>
> +#include <asm/stacktrace/common.h>
>
> struct stackframe {
> unsigned long fp;
> @@ -16,14 +21,70 @@ extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *re
> extern void dump_backtrace(struct pt_regs *regs, struct task_struct *task,
> const char *loglvl);
>
> -static inline bool on_thread_stack(void)
> +/*
> + * IRQ stack accessors
> + */
> +static inline struct stack_info stackinfo_get_irq(void)
> +{
> + unsigned long low = (unsigned long)raw_cpu_read(irq_stack_ptr);
> + unsigned long high = low + IRQ_STACK_SIZE;
> +
> + return (struct stack_info) {
> + .low = low,
> + .high = high,
> + };
> +}
> +
> +static inline bool on_irq_stack(unsigned long sp, unsigned long size)
> +{
> + struct stack_info info = stackinfo_get_irq();
> +
> + return stackinfo_on_stack(&info, sp, size);
> +}
> +
> +/*
> + * Task stack accessors
> + */
> +static inline struct stack_info stackinfo_get_task(const struct task_struct *tsk)
> {
> - return !(((unsigned long)(current->stack) ^ current_stack_pointer) & ~(THREAD_SIZE - 1));
> + unsigned long low = (unsigned long)task_stack_page(tsk);
> + unsigned long high = low + THREAD_SIZE;
> +
> + return (struct stack_info) {
> + .low = low,
> + .high = high,
> + };
> +}
> +
> +static inline bool on_task_stack(const struct task_struct *tsk,
> + unsigned long sp, unsigned long size)
> +{
> + struct stack_info info = stackinfo_get_task(tsk);
> +
> + return stackinfo_on_stack(&info, sp, size);
> }
>
> +/*
> + * Cast is necessary since current->stack is an opaque ptr.
> + */
> +#define on_thread_stack() (on_task_stack(current, current_stack_pointer, 1))
>
> +/*
> + * Overflow stack accessors
> + */
> #ifdef CONFIG_VMAP_STACK
> DECLARE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack);
> +
> +static inline struct stack_info stackinfo_get_overflow(void)
> +{
> + unsigned long low = (unsigned long)raw_cpu_ptr(overflow_stack);
> + unsigned long high = low + OVERFLOW_STACK_SIZE;
> +
> + return (struct stack_info) {
> + .low = low,
> + .high = high,
> + };
> +}
> #endif /* CONFIG_VMAP_STACK */
>
> #endif /* _ASM_RISCV_STACKTRACE_H */
> diff --git a/arch/riscv/include/asm/stacktrace/common.h b/arch/riscv/include/asm/stacktrace/common.h
> new file mode 100644
> index 000000000000..87d6d40672f3
> --- /dev/null
> +++ b/arch/riscv/include/asm/stacktrace/common.h
> @@ -0,0 +1,159 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * RISC-V common stack unwinder types and helpers.
> + *
> + * See: arch/arm64/include/asm/stacktrace/common.h for the reference
> + * implementation.
> + *
> + * Copyright (C) 2024
Nit: The new common.h carries "Copyright (C) 2024", but this is a 2026
submission.
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Thanks.
Shuai
^ permalink raw reply
* Re: [PATCH v2] tracing: fix CFI violation in probestub test
From: Masami Hiramatsu @ 2026-06-03 1:20 UTC (permalink / raw)
To: kernel test robot
Cc: Eva Kurchatova, mhiramat, rostedt, oe-kbuild-all,
linux-trace-kernel, linux-kernel, mathieu.desnoyers, peterz,
jpoimboe, samitolvanen
In-Reply-To: <202606022312.7cKiQBmg-lkp@intel.com>
On Tue, 2 Jun 2026 23:40:51 +0200
kernel test robot <lkp@intel.com> wrote:
> Hi Eva,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on trace/for-next]
> [also build test ERROR on linus/master v6.16-rc1 next-20260602]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Eva-Kurchatova/tracing-fix-CFI-violation-in-probestub-test/20260602-222302
> base: https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
> patch link: https://lore.kernel.org/r/20260602135425.542073-1-eva.kurchatova%40virtuozzo.com
> patch subject: [PATCH v2] tracing: fix CFI violation in probestub test
> config: x86_64-rhel-9.4-kselftests (https://download.01.org/0day-ci/archive/20260602/202606022312.7cKiQBmg-lkp@intel.com/config)
> compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260602/202606022312.7cKiQBmg-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202606022312.7cKiQBmg-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
> In file included from drivers/dma-buf/sync_trace.h:10,
> from drivers/dma-buf/sw_sync.c:18:
> include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
Hmm, it seems that this macro is not defined in this build
configuration? Maybe we need:
#include <linux/cfi.h>
instead of asm/cfi.h?
Thanks,
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/../../drivers/dma-buf/sync_trace.h:12:1: note: in expansion of macro 'TRACE_EVENT'
> 12 | TRACE_EVENT(sync_timeline,
> | ^~~~~~~~~~~
> include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/../../drivers/dma-buf/sync_trace.h:12:1: note: in expansion of macro 'TRACE_EVENT'
> 12 | TRACE_EVENT(sync_timeline,
> | ^~~~~~~~~~~
> >> include/trace/../../drivers/dma-buf/sync_trace.h:13:25: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
> 13 | TP_PROTO(struct sync_timeline *timeline),
> | ^~~~~~~~~~~~~
> include/linux/tracepoint.h:394:48: note: in definition of macro '__DEFINE_TRACE_EXT'
> 394 | void __probestub_##_name(void *__data, proto) \
> | ^~~~~
> include/linux/tracepoint.h:424:41: note: in expansion of macro 'PARAMS'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/define_trace.h:28:28: note: in expansion of macro 'PARAMS'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~
> include/trace/../../drivers/dma-buf/sync_trace.h:12:1: note: in expansion of macro 'TRACE_EVENT'
> 12 | TRACE_EVENT(sync_timeline,
> | ^~~~~~~~~~~
> include/trace/../../drivers/dma-buf/sync_trace.h:13:9: note: in expansion of macro 'TP_PROTO'
> 13 | TP_PROTO(struct sync_timeline *timeline),
> | ^~~~~~~~
> --
> In file included from include/trace/events/lock.h:9,
> from kernel/locking/mutex.c:35:
> include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:24:1: note: in expansion of macro 'TRACE_EVENT'
> 24 | TRACE_EVENT(lock_acquire,
> | ^~~~~~~~~~~
> include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:24:1: note: in expansion of macro 'TRACE_EVENT'
> 24 | TRACE_EVENT(lock_acquire,
> | ^~~~~~~~~~~
> >> include/trace/events/lock.h:28:24: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
> 28 | struct lockdep_map *next_lock, unsigned long ip),
> | ^~~~~~~~~~~
> include/linux/tracepoint.h:394:48: note: in definition of macro '__DEFINE_TRACE_EXT'
> 394 | void __probestub_##_name(void *__data, proto) \
> | ^~~~~
> include/linux/tracepoint.h:424:41: note: in expansion of macro 'PARAMS'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/define_trace.h:28:28: note: in expansion of macro 'PARAMS'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~
> include/trace/events/lock.h:24:1: note: in expansion of macro 'TRACE_EVENT'
> 24 | TRACE_EVENT(lock_acquire,
> | ^~~~~~~~~~~
> include/trace/events/lock.h:26:9: note: in expansion of macro 'TP_PROTO'
> 26 | TP_PROTO(struct lockdep_map *lock, unsigned int subclass,
> | ^~~~~~~~
> include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:61:9: note: in expansion of macro 'DEFINE_TRACE'
> 61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:69:1: note: in expansion of macro 'DEFINE_EVENT'
> 69 | DEFINE_EVENT(lock, lock_release,
> | ^~~~~~~~~~~~
> include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:61:9: note: in expansion of macro 'DEFINE_TRACE'
> 61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:69:1: note: in expansion of macro 'DEFINE_EVENT'
> 69 | DEFINE_EVENT(lock, lock_release,
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:71:25: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
> 71 | TP_PROTO(struct lockdep_map *lock, unsigned long ip),
> | ^~~~~~~~~~~
> include/linux/tracepoint.h:394:48: note: in definition of macro '__DEFINE_TRACE_EXT'
> 394 | void __probestub_##_name(void *__data, proto) \
> | ^~~~~
> include/linux/tracepoint.h:424:41: note: in expansion of macro 'PARAMS'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~
> include/trace/define_trace.h:61:9: note: in expansion of macro 'DEFINE_TRACE'
> 61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/define_trace.h:61:28: note: in expansion of macro 'PARAMS'
> 61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~
> include/trace/events/lock.h:69:1: note: in expansion of macro 'DEFINE_EVENT'
> 69 | DEFINE_EVENT(lock, lock_release,
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:71:9: note: in expansion of macro 'TP_PROTO'
> 71 | TP_PROTO(struct lockdep_map *lock, unsigned long ip),
> | ^~~~~~~~
> include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:95:1: note: in expansion of macro 'TRACE_EVENT'
> 95 | TRACE_EVENT(contention_begin,
> | ^~~~~~~~~~~
> include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
> 403 | CFI_NOSEAL(__probestub_##_name); \
> | ^~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:95:1: note: in expansion of macro 'TRACE_EVENT'
> 95 | TRACE_EVENT(contention_begin,
> | ^~~~~~~~~~~
> include/linux/tracepoint.h:380:24: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
> 380 | struct tracepoint_func *it_func_ptr; \
> | ^~~~~~~~~~~~~~~
> include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
> 424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
> | ^~~~~~~~~~~~~~~~~~
> include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
> 28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
> | ^~~~~~~~~~~~
> include/trace/events/lock.h:95:1: note: in expansion of macro 'TRACE_EVENT'
> 95 | TRACE_EVENT(contention_begin,
>
>
> vim +13 include/trace/../../drivers/dma-buf/sync_trace.h
>
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 11
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 12 TRACE_EVENT(sync_timeline,
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 @13 TP_PROTO(struct sync_timeline *timeline),
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 14
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 15 TP_ARGS(timeline),
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 16
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 17 TP_STRUCT__entry(
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 18 __string(name, timeline->name)
> 5c1401f83a16b7e drivers/staging/android/trace/sync.h Gustavo Padovan 2016-05-31 19 __field(u32, value)
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 20 ),
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 21
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 22 TP_fast_assign(
> 2c92ca849fcc6ee drivers/dma-buf/sync_trace.h Steven Rostedt (Google 2024-05-16 23) __assign_str(name);
> 5c1401f83a16b7e drivers/staging/android/trace/sync.h Gustavo Padovan 2016-05-31 24 __entry->value = timeline->value;
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 25 ),
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 26
> 5c1401f83a16b7e drivers/staging/android/trace/sync.h Gustavo Padovan 2016-05-31 27 TP_printk("name=%s value=%d", __get_str(name), __entry->value)
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 28 );
> b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 29
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH] tracing/events: Expand ring buffer for in-kernel event enables
From: manjunath.b.patil @ 2026-06-02 23:53 UTC (permalink / raw)
To: Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-kernel,
linux-trace-kernel
In-Reply-To: <20260602090025.06ae761f@gandalf.local.home>
On 6/2/26 6:00 AM, Steven Rostedt wrote:
> On Mon, 1 Jun 2026 16:24:43 -0700
> Manjunath Patil <manjunath.b.patil@oracle.com> wrote:
>
>> Ftrace keeps trace arrays at a boot-minimum ring-buffer size until
>> tracing is used. Tracefs event-enable paths already call
>> tracing_update_buffers() before enabling events, but the exported
>> in-kernel helpers trace_set_clr_event() and trace_array_set_clr_event()
>> directly enable events through __ftrace_set_clr_event().
>>
>> This can leave events enabled by in-kernel users recording into the tiny
>> boot-minimum buffer instead of the configured default-sized buffer. Any
>> caller that enables events through these exported helpers observes
>> different buffer-expansion behavior than a userspace tracefs event enable.
>>
>> Expand the relevant trace array before enabling events through the
>> exported in-kernel helpers, matching the tracefs event-enable behavior.
>> Disabling events remains unchanged.
>
> The above explains everything correctly, but you left out what needs this?
>
> Internal code should not be using the main ring buffer except for
> debugging, in which case you can use trace_printk(), which will cause the
> tracing buffers to be expanded by default.
>
> Other areas of the kernel should create their own trace array which will be
> created expanded by default too.
>
> -- Steve
Thanks Steve, that makes sense.
The concrete case I was trying to address is not an upstream in-tree
user. It is a downstream UEK RDS compatibility path where the legacy
rds_rt_debug_bitmap module parameter is mapped to RDS
tracepoints by calling trace_set_clr_event() against the global trace
array during module init. That can leave the default RDS tracepoints
recording into the boot-minimum buffer unless userspace expands tracing
first.
Looking at mainline again, trace-array users are already created
expanded by default, and the remaining global-buffer use is
debugging-style. So I agree this generic tracing/events change does not
have a good upstream justification.
Please drop this patch. We will handle the downstream RDS compatibility
case downstream, or move it to an explicit userspace/trace-array setup.
Thanks,
Manjunath
^ permalink raw reply
* Re: [PATCH v7 07/42] KVM: guest_memfd: Only prepare folios for private pages
From: Ackerley Tng @ 2026-06-02 22:41 UTC (permalink / raw)
To: Suzuki K Poulose, aik, andrew.jones, binbin.wu, brauner,
chao.p.peng, david, ira.weiny, jmattson, jthoughton, michael.roth,
oupton, pankaj.gupta, qperret, rick.p.edgecombe, rientjes,
shivankg, steven.price, tabba, willy, wyihan, yan.y.zhao,
forkloop, pratyush, aneesh.kumar, liam, Paolo Bonzini,
Sean Christopherson, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Jonathan Corbet, Shuah Khan,
Shuah Khan, Vishal Annapurve, Andrew Morton, Chris Li,
Kairui Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Youngjun Park, Qi Zheng,
Shakeel Butt, Kiryl Shutsemau, Jason Gunthorpe, Vlastimil Babka
Cc: kvm, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest,
linux-mm, linux-coco
In-Reply-To: <144bbb9f-39a2-4c90-8903-51521e022da0@arm.com>
Suzuki K Poulose <suzuki.poulose@arm.com> writes:
>
> [...snip...]
>
>>> @@ -914,7 +916,8 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct
>>> kvm_memory_slot *slot,
>>> folio_mark_uptodate(folio);
>>> }
>>> - r = kvm_gmem_prepare_folio(kvm, slot, gfn, folio);
>>> + if (kvm_gmem_is_private_mem(inode, index))
>>
>> Don't we need to make sure the entire folio is private ? Not just the
>> page at the index ?
>> if (kvm_gmem_range_is_private(, index, folio_nr_pages(folio)) ?
I was thinking to fix this when I do huge pages, for now guest_memfd is
always just PAGE_SIZE, so just looking up index is fine.
Is that okay?
>
> Or rather, we should go through the individual pages and apply the
> prepare for ones that are private ?
>
> Suzuki
>
IIRC the plan was to make kvm_gmem_prepare_folio() idempotent, as in, if
a page is already private, just skip. Currently sev_gmem_prepare() does
a pr_debug(), which I guess is technically still idempotent.
I'm thinking that the information tha needs tracking to make
.gmem_prepare() idempotent should be tracked by arch code.
Does this work for ARM CCA?
>>
>> [...snip...]
>>
^ permalink raw reply
* Re: [PATCH v2] tracing: fix CFI violation in probestub test
From: kernel test robot @ 2026-06-02 21:40 UTC (permalink / raw)
To: Eva Kurchatova, mhiramat, rostedt
Cc: oe-kbuild-all, linux-trace-kernel, linux-kernel,
mathieu.desnoyers, peterz, jpoimboe, samitolvanen, eva.kurchatova
In-Reply-To: <20260602135425.542073-1-eva.kurchatova@virtuozzo.com>
Hi Eva,
kernel test robot noticed the following build errors:
[auto build test ERROR on trace/for-next]
[also build test ERROR on linus/master v6.16-rc1 next-20260602]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Eva-Kurchatova/tracing-fix-CFI-violation-in-probestub-test/20260602-222302
base: https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link: https://lore.kernel.org/r/20260602135425.542073-1-eva.kurchatova%40virtuozzo.com
patch subject: [PATCH v2] tracing: fix CFI violation in probestub test
config: x86_64-rhel-9.4-kselftests (https://download.01.org/0day-ci/archive/20260602/202606022312.7cKiQBmg-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260602/202606022312.7cKiQBmg-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606022312.7cKiQBmg-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/dma-buf/sync_trace.h:10,
from drivers/dma-buf/sw_sync.c:18:
include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/../../drivers/dma-buf/sync_trace.h:12:1: note: in expansion of macro 'TRACE_EVENT'
12 | TRACE_EVENT(sync_timeline,
| ^~~~~~~~~~~
include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/../../drivers/dma-buf/sync_trace.h:12:1: note: in expansion of macro 'TRACE_EVENT'
12 | TRACE_EVENT(sync_timeline,
| ^~~~~~~~~~~
>> include/trace/../../drivers/dma-buf/sync_trace.h:13:25: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
13 | TP_PROTO(struct sync_timeline *timeline),
| ^~~~~~~~~~~~~
include/linux/tracepoint.h:394:48: note: in definition of macro '__DEFINE_TRACE_EXT'
394 | void __probestub_##_name(void *__data, proto) \
| ^~~~~
include/linux/tracepoint.h:424:41: note: in expansion of macro 'PARAMS'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/define_trace.h:28:28: note: in expansion of macro 'PARAMS'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~
include/trace/../../drivers/dma-buf/sync_trace.h:12:1: note: in expansion of macro 'TRACE_EVENT'
12 | TRACE_EVENT(sync_timeline,
| ^~~~~~~~~~~
include/trace/../../drivers/dma-buf/sync_trace.h:13:9: note: in expansion of macro 'TP_PROTO'
13 | TP_PROTO(struct sync_timeline *timeline),
| ^~~~~~~~
--
In file included from include/trace/events/lock.h:9,
from kernel/locking/mutex.c:35:
include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/events/lock.h:24:1: note: in expansion of macro 'TRACE_EVENT'
24 | TRACE_EVENT(lock_acquire,
| ^~~~~~~~~~~
include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/events/lock.h:24:1: note: in expansion of macro 'TRACE_EVENT'
24 | TRACE_EVENT(lock_acquire,
| ^~~~~~~~~~~
>> include/trace/events/lock.h:28:24: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
28 | struct lockdep_map *next_lock, unsigned long ip),
| ^~~~~~~~~~~
include/linux/tracepoint.h:394:48: note: in definition of macro '__DEFINE_TRACE_EXT'
394 | void __probestub_##_name(void *__data, proto) \
| ^~~~~
include/linux/tracepoint.h:424:41: note: in expansion of macro 'PARAMS'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/define_trace.h:28:28: note: in expansion of macro 'PARAMS'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~
include/trace/events/lock.h:24:1: note: in expansion of macro 'TRACE_EVENT'
24 | TRACE_EVENT(lock_acquire,
| ^~~~~~~~~~~
include/trace/events/lock.h:26:9: note: in expansion of macro 'TP_PROTO'
26 | TP_PROTO(struct lockdep_map *lock, unsigned int subclass,
| ^~~~~~~~
include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:61:9: note: in expansion of macro 'DEFINE_TRACE'
61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/events/lock.h:69:1: note: in expansion of macro 'DEFINE_EVENT'
69 | DEFINE_EVENT(lock, lock_release,
| ^~~~~~~~~~~~
include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:61:9: note: in expansion of macro 'DEFINE_TRACE'
61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/events/lock.h:69:1: note: in expansion of macro 'DEFINE_EVENT'
69 | DEFINE_EVENT(lock, lock_release,
| ^~~~~~~~~~~~
include/trace/events/lock.h:71:25: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
71 | TP_PROTO(struct lockdep_map *lock, unsigned long ip),
| ^~~~~~~~~~~
include/linux/tracepoint.h:394:48: note: in definition of macro '__DEFINE_TRACE_EXT'
394 | void __probestub_##_name(void *__data, proto) \
| ^~~~~
include/linux/tracepoint.h:424:41: note: in expansion of macro 'PARAMS'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~
include/trace/define_trace.h:61:9: note: in expansion of macro 'DEFINE_TRACE'
61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/define_trace.h:61:28: note: in expansion of macro 'PARAMS'
61 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~
include/trace/events/lock.h:69:1: note: in expansion of macro 'DEFINE_EVENT'
69 | DEFINE_EVENT(lock, lock_release,
| ^~~~~~~~~~~~
include/trace/events/lock.h:71:9: note: in expansion of macro 'TP_PROTO'
71 | TP_PROTO(struct lockdep_map *lock, unsigned long ip),
| ^~~~~~~~
include/linux/tracepoint.h:403:9: warning: data definition has no type or storage class
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/events/lock.h:95:1: note: in expansion of macro 'TRACE_EVENT'
95 | TRACE_EVENT(contention_begin,
| ^~~~~~~~~~~
include/linux/tracepoint.h:403:9: error: type defaults to 'int' in declaration of 'CFI_NOSEAL' [-Wimplicit-int]
403 | CFI_NOSEAL(__probestub_##_name); \
| ^~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/events/lock.h:95:1: note: in expansion of macro 'TRACE_EVENT'
95 | TRACE_EVENT(contention_begin,
| ^~~~~~~~~~~
include/linux/tracepoint.h:380:24: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
380 | struct tracepoint_func *it_func_ptr; \
| ^~~~~~~~~~~~~~~
include/linux/tracepoint.h:424:9: note: in expansion of macro '__DEFINE_TRACE_EXT'
424 | __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
| ^~~~~~~~~~~~~~~~~~
include/trace/define_trace.h:28:9: note: in expansion of macro 'DEFINE_TRACE'
28 | DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^~~~~~~~~~~~
include/trace/events/lock.h:95:1: note: in expansion of macro 'TRACE_EVENT'
95 | TRACE_EVENT(contention_begin,
vim +13 include/trace/../../drivers/dma-buf/sync_trace.h
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 11
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 12 TRACE_EVENT(sync_timeline,
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 @13 TP_PROTO(struct sync_timeline *timeline),
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 14
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 15 TP_ARGS(timeline),
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 16
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 17 TP_STRUCT__entry(
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 18 __string(name, timeline->name)
5c1401f83a16b7e drivers/staging/android/trace/sync.h Gustavo Padovan 2016-05-31 19 __field(u32, value)
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 20 ),
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 21
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 22 TP_fast_assign(
2c92ca849fcc6ee drivers/dma-buf/sync_trace.h Steven Rostedt (Google 2024-05-16 23) __assign_str(name);
5c1401f83a16b7e drivers/staging/android/trace/sync.h Gustavo Padovan 2016-05-31 24 __entry->value = timeline->value;
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 25 ),
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 26
5c1401f83a16b7e drivers/staging/android/trace/sync.h Gustavo Padovan 2016-05-31 27 TP_printk("name=%s value=%d", __get_str(name), __entry->value)
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 28 );
b699a644f82110e drivers/staging/android/trace/sync.h Erik Gilling 2013-02-28 29
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v7 34/42] KVM: selftests: Test conversion with elevated page refcount
From: Askar Safin @ 2026-06-02 21:26 UTC (permalink / raw)
To: devnull+ackerleytng.google.com
Cc: ackerleytng, aik, akpm, andrew.jones, aneesh.kumar, axelrasmussen,
baohua, bhe, binbin.wu, bp, brauner, chao.p.peng, chrisl, corbet,
dave.hansen, david, forkloop, hpa, ira.weiny, jgg, jmattson,
jthoughton, kas, kasong, kvm, liam, linux-coco, linux-doc,
linux-kernel, linux-kselftest, linux-mm, linux-trace-kernel,
mathieu.desnoyers, mhiramat, michael.roth, mingo, nphamcs, oupton,
pankaj.gupta, pbonzini, pratyush, qi.zheng, qperret,
rick.p.edgecombe, rientjes, rostedt, seanjc, shakeel.butt,
shikemeng, shivankg, shuah, skhan, steven.price, suzuki.poulose,
tabba, tglx, vannapurve, vbabka, weixugc, willy, wyihan, x86,
yan.y.zhao, youngjun.park, yuanchu
In-Reply-To: <20260522-gmem-inplace-conversion-v7-34-2f0fae496530@google.com>
Ackerley Tng via B4 Relay <devnull+ackerleytng.google.com@kernel.org>:
> This test uses vmsplice to increment the refcount of a specific page
I recently submitted a patch, which makes vmsplice equivalent to
preadv2/pwritev2, and it was accepted to next.
For now it is just an experiment, it is possible it will be reverted.
https://lore.kernel.org/all/20260601-aufweichen-dissens-ausrechnen-0d9b84728113@brauner/
--
Askar Safin
^ permalink raw reply
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Andy Shevchenko @ 2026-06-02 21:05 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Arnd Bergmann, Steven Rostedt, Masami Hiramatsu, Andrew Morton,
Petr Mladek, Nathan Chancellor, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Arend van Spriel,
Miri Korenblit, Mathieu Desnoyers, Rasmus Villemoes,
Sergey Senozhatsky, Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka (SUSE), linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <35c1ba62-e74d-4abc-aa73-ccd35968ff89@app.fastmail.com>
On Tue, Jun 02, 2026 at 10:32:04PM +0200, Arnd Bergmann wrote:
> On Tue, Jun 2, 2026, at 20:59, Andy Shevchenko wrote:
> > On Tue, Jun 02, 2026 at 05:07:05PM +0200, Arnd Bergmann wrote:
...
> > Why the __printf() annotation is in the C file and not here?
> > Is this all about headers as the second paragraph in the commit message
> > explains?
> > I would add a comment to explain it here, otherwise we might see false
> > patches to "make things consistent" in a wrong way.
>
> I've tried to come up with a kerneldoc comment now, similar to
> the one for the vsnprintf() function, and added a separate prototype
> in the header. Does this address your concern?
Yes, see one nit, though.
> -int __printf(3, 0) __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> +/**
> + * __vsnprintf - vsnprintf() wrapper without __printf() attribute
> + * @buf: The buffer to place the result into
> + * @size: The size of the buffer, including the trailing null space
> + * @fmt_str: The format string to use
> + * @args: Arguments for the format string
> + *
> + * This has the exact same behavior as vsnprintf() but can be used in call
> + * sites that are missing a __printf() annotation, e.g. because they
> + * get a 'va_format' argument instead of format and varargs.
> + *
> + * For this to work, the attribute is added to the declaration here but
> + * not in the header.
+ *
+ * Return: ...
> + */
> +int __printf(3, 0) __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args);
> +
> +int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
Something slipped here...
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox