* [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
@ 2026-06-02 15:07 Arnd Bergmann
2026-06-02 15:07 ` [PATCH 2/2] tracing/osnoise: add printf attribute to osnoise_print Arnd Bergmann
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Arnd Bergmann @ 2026-06-02 15:07 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Petr Mladek,
Nathan Chancellor
Cc: 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
From: Arnd Bergmann <arnd@arndb.de>
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.
Aside from tracing, the same thing can be used in va_format(),
which is part of lib/vsprintf.c itself.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
This version is a fairly simplistic way to work around the warning
reliably. I have resent two more patches to address actually
missing annotations in device drivers, but with all of these
out of the way, we can move the warning from the 'make W=1'
into the default set.
I have also prototyped a variant of this patch that passes down
a 'struct va_format' throughout the tracing code. That patch is
a little more invasive and I have no idea if that actually works,
but the result looks simpler.
---
drivers/infiniband/hw/hfi1/trace_dbg.h | 7 -------
.../broadcom/brcm80211/brcmfmac/tracepoint.h | 7 -------
.../brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h | 7 -------
drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c | 3 ---
include/linux/sprintf.h | 1 +
include/linux/trace_events.h | 2 +-
include/trace/events/qla.h | 7 -------
include/trace/stages/stage6_event_callback.h | 2 +-
lib/vsprintf.c | 12 +++++++-----
samples/trace_events/trace-events-sample.c | 2 --
10 files changed, 10 insertions(+), 40 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/trace_dbg.h b/drivers/infiniband/hw/hfi1/trace_dbg.h
index 58304b91380f..05c4f1354269 100644
--- a/drivers/infiniband/hw/hfi1/trace_dbg.h
+++ b/drivers/infiniband/hw/hfi1/trace_dbg.h
@@ -22,11 +22,6 @@
#define MAX_MSG_LEN 512
-#pragma GCC diagnostic push
-#ifndef __clang__
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
-#endif
-
DECLARE_EVENT_CLASS(hfi1_trace_template,
TP_PROTO(const char *function, struct va_format *vaf),
TP_ARGS(function, vaf),
@@ -41,8 +36,6 @@ DECLARE_EVENT_CLASS(hfi1_trace_template,
__get_str(msg))
);
-#pragma GCC diagnostic pop
-
/*
* It may be nice to macroize the __hfi1_trace but the va_* stuff requires an
* actual function to work and can not be in a macro.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
index 96032322b165..6c4e00e9ccd1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
@@ -28,11 +28,6 @@ static inline void trace_ ## name(proto) {}
#define MAX_MSG_LEN 100
-#pragma GCC diagnostic push
-#ifndef __clang__
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
-#endif
-
TRACE_EVENT(brcmf_err,
TP_PROTO(const char *func, struct va_format *vaf),
TP_ARGS(func, vaf),
@@ -128,8 +123,6 @@ TRACE_EVENT(brcmf_sdpcm_hdr,
__entry->len, ((u8 *)__get_dynamic_array(hdr))[4])
);
-#pragma GCC diagnostic pop
-
#ifdef CONFIG_BRCM_TRACING
#undef TRACE_INCLUDE_PATH
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 908ce3c864fe..dc296d8bf775 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
@@ -24,11 +24,6 @@
#define MAX_MSG_LEN 100
-#pragma GCC diagnostic push
-#ifndef __clang__
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
-#endif
-
DECLARE_EVENT_CLASS(brcms_msg_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
@@ -77,8 +72,6 @@ TRACE_EVENT(brcms_dbg,
TP_printk("%s: %s", __get_str(func), __get_str(msg))
);
-#pragma GCC diagnostic pop
-
#endif /* __TRACE_BRCMSMAC_MSG_H */
#ifdef CONFIG_BRCM_TRACING
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
index 7e686297963d..49a8196430a7 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
@@ -12,9 +12,6 @@
#include "iwl-trans.h"
#define CREATE_TRACE_POINTS
-#ifdef CONFIG_CC_IS_GCC
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
-#endif
#include "iwl-devtrace.h"
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
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); \
diff --git a/include/trace/events/qla.h b/include/trace/events/qla.h
index 8800c35525a1..74a7534b99b6 100644
--- a/include/trace/events/qla.h
+++ b/include/trace/events/qla.h
@@ -9,11 +9,6 @@
#define QLA_MSG_MAX 256
-#pragma GCC diagnostic push
-#ifndef __clang__
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
-#endif
-
DECLARE_EVENT_CLASS(qla_log_event,
TP_PROTO(const char *buf,
struct va_format *vaf),
@@ -32,8 +27,6 @@ DECLARE_EVENT_CLASS(qla_log_event,
TP_printk("%s %s", __get_str(buf), __get_str(msg))
);
-#pragma GCC diagnostic pop
-
DEFINE_EVENT(qla_log_event, ql_dbg_log,
TP_PROTO(const char *buf, struct va_format *vaf),
TP_ARGS(buf, vaf)
diff --git a/include/trace/stages/stage6_event_callback.h b/include/trace/stages/stage6_event_callback.h
index 1691676fd858..7d6a6ca6e779 100644
--- a/include/trace/stages/stage6_event_callback.h
+++ b/include/trace/stages/stage6_event_callback.h
@@ -45,7 +45,7 @@
do { \
va_list __cp_va; \
va_copy(__cp_va, *(va)); \
- vsnprintf(__get_str(dst), TRACE_EVENT_STR_MAX, fmt, __cp_va); \
+ __vsnprintf(__get_str(dst), TRACE_EVENT_STR_MAX, fmt, __cp_va); \
va_end(__cp_va); \
} while (0)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index a3017bc58986..3caf0796f54d 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1702,9 +1702,6 @@ char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
return buf;
}
-__diag_push();
-__diag_ignore(GCC, all, "-Wsuggest-attribute=format",
- "Not a valid __printf() conversion candidate.");
static char *va_format(char *buf, char *end, struct va_format *va_fmt,
struct printf_spec spec)
{
@@ -1714,12 +1711,11 @@ static char *va_format(char *buf, char *end, struct va_format *va_fmt,
return buf;
va_copy(va, *va_fmt->va);
- buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
+ buf += __vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
va_end(va);
return buf;
}
-__diag_pop();
static noinline_for_stack
char *uuid_string(char *buf, char *end, const u8 *addr,
@@ -2979,6 +2975,12 @@ 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)
+{
+ return vsnprintf(buf, size, fmt_str, args);
+}
+EXPORT_SYMBOL(__vsnprintf);
+
/**
* vscnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c
index 9993fb5d5f98..ecc7db237f2e 100644
--- a/samples/trace_events/trace-events-sample.c
+++ b/samples/trace_events/trace-events-sample.c
@@ -9,8 +9,6 @@
* creates the handles for the trace points.
*/
#define CREATE_TRACE_POINTS
-__diag_ignore(GCC, all, "-Wsuggest-attribute=format",
- "trace_event_get_offsets_foo_bar can't easily be annotated as __printf");
#include "trace-events-sample.h"
static const char *random_strings[] = {
--
2.39.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/2] tracing/osnoise: add printf attribute to osnoise_print
2026-06-02 15:07 [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Arnd Bergmann
@ 2026-06-02 15:07 ` Arnd Bergmann
2026-06-02 15:40 ` [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Steven Rostedt
` (2 subsequent siblings)
3 siblings, 0 replies; 14+ messages in thread
From: Arnd Bergmann @ 2026-06-02 15:07 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Crystal Wood
Cc: Arnd Bergmann, Mathieu Desnoyers, Tomas Glozar, Wang Liang,
linux-kernel, linux-trace-kernel
From: Arnd Bergmann <arnd@arndb.de>
gcc points out that tne newly added function uses printf style arguments
and should get an attribute to allow verifying the format strings for
its callers:
kernel/trace/trace_osnoise.c: In function 'osnoise_print':
kernel/trace/trace_osnoise.c:96:17: error: function 'osnoise_print' might be a candidate for 'gnu_printf' format attribute [-Werror=suggest-attribute=format]
96 | trace_array_vprintk(tr, _RET_IP_, fmt, ap);
| ^~~~~~~~~~~~~~~~~~~
Add the attribute as suggested
Fixes: 9cb99c598643 ("tracing/osnoise: Array printk init and cleanup")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
kernel/trace/trace_osnoise.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
index 1fbd8525ab54..6fa015e57899 100644
--- a/kernel/trace/trace_osnoise.c
+++ b/kernel/trace/trace_osnoise.c
@@ -83,7 +83,7 @@ struct osnoise_instance {
static struct list_head osnoise_instances;
-static void osnoise_print(const char *fmt, ...)
+static __printf(1, 2) void osnoise_print(const char *fmt, ...)
{
struct osnoise_instance *inst;
struct trace_array *tr;
--
2.39.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-02 15:07 [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Arnd Bergmann
2026-06-02 15:07 ` [PATCH 2/2] tracing/osnoise: add printf attribute to osnoise_print Arnd Bergmann
@ 2026-06-02 15:40 ` Steven Rostedt
2026-06-02 18:59 ` Andy Shevchenko
2026-06-03 1:58 ` Masami Hiramatsu
3 siblings, 0 replies; 14+ messages in thread
From: Steven Rostedt @ 2026-06-02 15:40 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Masami Hiramatsu, 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
On Tue, 2 Jun 2026 17:07:05 +0200
Arnd Bergmann <arnd@kernel.org> wrote:
> @@ -2979,6 +2975,12 @@ int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> }
> EXPORT_SYMBOL(vsnprintf);
>
Should add a comment here for why this is needed.
-- Steve
> +int __printf(3, 0) __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> +{
> + return vsnprintf(buf, size, fmt_str, args);
> +}
> +EXPORT_SYMBOL(__vsnprintf);
> +
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-02 15:07 [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Arnd Bergmann
2026-06-02 15:07 ` [PATCH 2/2] tracing/osnoise: add printf attribute to osnoise_print Arnd Bergmann
2026-06-02 15:40 ` [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Steven Rostedt
@ 2026-06-02 18:59 ` Andy Shevchenko
2026-06-02 20:32 ` Arnd Bergmann
2026-06-03 1:58 ` Masami Hiramatsu
3 siblings, 1 reply; 14+ messages in thread
From: Andy Shevchenko @ 2026-06-02 18:59 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Steven Rostedt, Masami Hiramatsu, 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
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()
> Aside from tracing, the same thing can be used in va_format(),
> which is part of lib/vsprintf.c itself.
...
> --- 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);
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.
> __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, ...);
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-02 18:59 ` Andy Shevchenko
@ 2026-06-02 20:32 ` Arnd Bergmann
2026-06-02 21:05 ` Andy Shevchenko
2026-06-03 7:15 ` Rasmus Villemoes
0 siblings, 2 replies; 14+ messages in thread
From: Arnd Bergmann @ 2026-06-02 20:32 UTC (permalink / raw)
To: Andy Shevchenko, Arnd Bergmann
Cc: 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
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);
}
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-02 20:32 ` Arnd Bergmann
@ 2026-06-02 21:05 ` Andy Shevchenko
2026-06-03 7:15 ` Rasmus Villemoes
1 sibling, 0 replies; 14+ messages in thread
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
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 [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-02 15:07 [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Arnd Bergmann
` (2 preceding siblings ...)
2026-06-02 18:59 ` Andy Shevchenko
@ 2026-06-03 1:58 ` Masami Hiramatsu
2026-06-03 5:46 ` Andy Shevchenko
3 siblings, 1 reply; 14+ messages in thread
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
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 [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-03 1:58 ` Masami Hiramatsu
@ 2026-06-03 5:46 ` Andy Shevchenko
0 siblings, 0 replies; 14+ messages in thread
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
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 [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-02 20:32 ` Arnd Bergmann
2026-06-02 21:05 ` Andy Shevchenko
@ 2026-06-03 7:15 ` Rasmus Villemoes
2026-06-03 8:41 ` Arnd Bergmann
1 sibling, 1 reply; 14+ messages in thread
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
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 [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-03 7:15 ` Rasmus Villemoes
@ 2026-06-03 8:41 ` Arnd Bergmann
2026-06-03 12:49 ` Rasmus Villemoes
2026-06-03 13:03 ` David Laight
0 siblings, 2 replies; 14+ messages in thread
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
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 [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-03 8:41 ` Arnd Bergmann
@ 2026-06-03 12:49 ` Rasmus Villemoes
2026-06-03 13:10 ` Arnd Bergmann
2026-06-03 13:14 ` Rasmus Villemoes
2026-06-03 13:03 ` David Laight
1 sibling, 2 replies; 14+ messages in thread
From: Rasmus Villemoes @ 2026-06-03 12:49 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
On Wed, Jun 03 2026, "Arnd Bergmann" <arnd@arndb.de> wrote:
> 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);
>
Ah, I see. The documentation for the alias attribute does say that the
types have to match, but I didn't know that the nothrow and nonnull
attributes were considered part of the type identity. Oddly enough, if
one does
typeof(vsnprintf) __vsnprintf __alias(vsnprintf);
that still fails, but only complains about nothrow, not nonnull.
I don't remember what minimum gcc we currently require, but gcc 9
introduced another attribute that is apperently meant for cases like
this: 'copy'. This seems to build:
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 9f359b31c8d1..c1402d375429 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -2988,6 +2988,9 @@ int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
}
EXPORT_SYMBOL(vsnprintf);
+int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
+ __alias(vsnprintf) __attribute__((__copy__(vsnprintf)));
+
/**
* vscnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
That at least should handle any future "gcc knows this-or-that about the
vsnprintf function". But I don't know if clang supports that copy
mechanism or if the minimum supported gcc is too old.
Rasmus
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-03 8:41 ` Arnd Bergmann
2026-06-03 12:49 ` Rasmus Villemoes
@ 2026-06-03 13:03 ` David Laight
1 sibling, 0 replies; 14+ messages in thread
From: David Laight @ 2026-06-03 13:03 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Rasmus Villemoes, 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
On Wed, 03 Jun 2026 10:41:18 +0200
"Arnd Bergmann" <arnd@arndb.de> wrote:
> 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; \
This adds an extra snprintf call - non-trivial and more stack.
Can't you just use the old code with vf->fmt and vf->ap ?
And does the %pV" include the va_copy()?
It isn't normally needed.
Any scheme for avoiding doing the printf processing twice
is likely to be a gain.
-- David
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-03 12:49 ` Rasmus Villemoes
@ 2026-06-03 13:10 ` Arnd Bergmann
2026-06-03 13:14 ` Rasmus Villemoes
1 sibling, 0 replies; 14+ messages in thread
From: Arnd Bergmann @ 2026-06-03 13:10 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
On Wed, Jun 3, 2026, at 14:49, Rasmus Villemoes wrote:
> On Wed, Jun 03 2026, "Arnd Bergmann" <arnd@arndb.de> wrote:
>> On Wed, Jun 3, 2026, at 09:15, Rasmus Villemoes wrote:
> I don't remember what minimum gcc we currently require, but gcc 9
> introduced another attribute that is apperently meant for cases like
> this: 'copy'.
The minimum version is gcc-8.
> This seems to build:
>...
> +int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> + __alias(vsnprintf) __attribute__((__copy__(vsnprintf)));
> +
>
> That at least should handle any future "gcc knows this-or-that about the
> vsnprintf function". But I don't know if clang supports that copy
> mechanism or if the minimum supported gcc is too old.
clang-22 and gcc-8 don't like the attribute, but also don't complain
about the other mismatched attributes, so simply using the __copy()
macro we already have will work on all currently supported
compilers and likely all future ones as well.
Arnd
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
2026-06-03 12:49 ` Rasmus Villemoes
2026-06-03 13:10 ` Arnd Bergmann
@ 2026-06-03 13:14 ` Rasmus Villemoes
1 sibling, 0 replies; 14+ messages in thread
From: Rasmus Villemoes @ 2026-06-03 13:14 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
On Wed, Jun 03 2026, Rasmus Villemoes <ravi@prevas.dk> wrote:
> On Wed, Jun 03 2026, "Arnd Bergmann" <arnd@arndb.de> wrote:
>
>> 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);
>>
>
> Ah, I see. The documentation for the alias attribute does say that the
> types have to match, but I didn't know that the nothrow and nonnull
> attributes were considered part of the type identity. Oddly enough, if
> one does
>
> typeof(vsnprintf) __vsnprintf __alias(vsnprintf);
>
> that still fails, but only complains about nothrow, not nonnull.
>
> I don't remember what minimum gcc we currently require, but gcc 9
> introduced another attribute that is apperently meant for cases like
> this: 'copy'. This seems to build:
>
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 9f359b31c8d1..c1402d375429 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -2988,6 +2988,9 @@ int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> }
> EXPORT_SYMBOL(vsnprintf);
>
> +int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> + __alias(vsnprintf) __attribute__((__copy__(vsnprintf)));
> +
> /**
> * vscnprintf - Format a string and place it in a buffer
> * @buf: The buffer to place the result into
>
> That at least should handle any future "gcc knows this-or-that about the
> vsnprintf function". But I don't know if clang supports that copy
> mechanism or if the minimum supported gcc is too old.
Ah, so we already have __copy in compiler-attributes.h, stating that
it's not supported by clang. Our current minimum gcc version is 8. But
judging from the commit message for c0d9782f5, perhaps it's not actually
a problem that it just expands to nothing for gcc 8, as the "less
restrictive attribute" warning was also introduced with gcc 9, and the
__copy macro is already used for module init/exit functions. Which also
suggests that it might not be a problem that clang doesn't support it.
Rasmus
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-06-03 13:14 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-02 15:07 [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Arnd Bergmann
2026-06-02 15:07 ` [PATCH 2/2] tracing/osnoise: add printf attribute to osnoise_print Arnd Bergmann
2026-06-02 15:40 ` [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning Steven Rostedt
2026-06-02 18:59 ` Andy Shevchenko
2026-06-02 20:32 ` Arnd Bergmann
2026-06-02 21:05 ` Andy Shevchenko
2026-06-03 7:15 ` Rasmus Villemoes
2026-06-03 8:41 ` Arnd Bergmann
2026-06-03 12:49 ` Rasmus Villemoes
2026-06-03 13:10 ` Arnd Bergmann
2026-06-03 13:14 ` Rasmus Villemoes
2026-06-03 13:03 ` David Laight
2026-06-03 1:58 ` Masami Hiramatsu
2026-06-03 5:46 ` Andy Shevchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox