* [PATCH] kernel/panic: increase buffer size for verbose taint logging
@ 2026-02-20 15:15 Rio
2026-02-20 21:06 ` Andrew Morton
2026-02-22 14:08 ` [PATCHv2] kernel/panic: allocate taint string buffer dynamically Rio
0 siblings, 2 replies; 8+ messages in thread
From: Rio @ 2026-02-20 15:15 UTC (permalink / raw)
To: Andrew Morton
Cc: Feng Tang, Petr Mladek, Jinchao Wang, Joel Granados, Pnina Feder,
linux-kernel, Rio
The verbose 'Tainted: ...' string in print_tainted_seq
can total to 327 characters while the buffer defined in
_print_tainted is 320 bytes. Increase its size to 350
characters to hold all flags, along with some headroom.
Signed-off-by: Rio <rioo.tsukatsukii@gmail.com>
---
kernel/panic.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/panic.c b/kernel/panic.c
index c78600212b6c..42b03fdd6ffa 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -854,10 +854,12 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose)
}
}
+/* 350 can accomadate all taint flags in verbose mode, with some headroom */
+#define TAINT_BUF_MAX 350
+
static const char *_print_tainted(bool verbose)
{
- /* FIXME: what should the size be? */
- static char buf[sizeof(taint_flags)];
+ static char buf[TAINT_BUF_MAX];
struct seq_buf s;
BUILD_BUG_ON(ARRAY_SIZE(taint_flags) != TAINT_FLAGS_COUNT);
--
2.52.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] kernel/panic: increase buffer size for verbose taint logging
2026-02-20 15:15 [PATCH] kernel/panic: increase buffer size for verbose taint logging Rio
@ 2026-02-20 21:06 ` Andrew Morton
2026-02-21 6:56 ` Rio
2026-02-22 14:08 ` [PATCHv2] kernel/panic: allocate taint string buffer dynamically Rio
1 sibling, 1 reply; 8+ messages in thread
From: Andrew Morton @ 2026-02-20 21:06 UTC (permalink / raw)
To: Rio
Cc: Feng Tang, Petr Mladek, Jinchao Wang, Joel Granados, Pnina Feder,
linux-kernel
On Fri, 20 Feb 2026 20:45:00 +0530 Rio <rioo.tsukatsukii@gmail.com> wrote:
> The verbose 'Tainted: ...' string in print_tainted_seq
> can total to 327 characters while the buffer defined in
> _print_tainted is 320 bytes. Increase its size to 350
> characters to hold all flags, along with some headroom.
>
> ...
>
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -854,10 +854,12 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose)
> }
> }
>
> +/* 350 can accomadate all taint flags in verbose mode, with some headroom */
"accommodate". I'll fix this.
> +#define TAINT_BUF_MAX 350
> +
> static const char *_print_tainted(bool verbose)
> {
> - /* FIXME: what should the size be? */
> - static char buf[sizeof(taint_flags)];
Well that was weird.
> + static char buf[TAINT_BUF_MAX];
Can you think of a way to do this more flexibly? Something which
scales as we add more flags?
Probably not, as it's dependent upon the length of the various
taint_flags.desc strings.
> struct seq_buf s;
>
> BUILD_BUG_ON(ARRAY_SIZE(taint_flags) != TAINT_FLAGS_COUNT);
How does this look?
--- a/kernel/panic.c~kernel-panic-increase-buffer-size-for-verbose-taint-logging-fix
+++ a/kernel/panic.c
@@ -801,6 +801,8 @@ EXPORT_SYMBOL(panic);
* Documentation/admin-guide/tainted-kernels.rst, including its
* small shell script that prints the TAINT_FLAGS_COUNT bits of
* /proc/sys/kernel/tainted.
+ *
+ * Also, update TAINT_BUF_MAX below.
*/
const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
TAINT_FLAG(PROPRIETARY_MODULE, 'P', 'G'),
@@ -854,7 +856,7 @@ static void print_tainted_seq(struct seq
}
}
-/* 350 can accomadate all taint flags in verbose mode, with some headroom */
+/* 350 can accommodate all taint flags in verbose mode, with some headroom */
#define TAINT_BUF_MAX 350
static const char *_print_tainted(bool verbose)
_
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] kernel/panic: increase buffer size for verbose taint logging
2026-02-20 21:06 ` Andrew Morton
@ 2026-02-21 6:56 ` Rio
2026-02-21 20:03 ` Andrew Morton
0 siblings, 1 reply; 8+ messages in thread
From: Rio @ 2026-02-21 6:56 UTC (permalink / raw)
To: akpm
Cc: feng.tang, joel.granados, linux-kernel, pmladek, pnina.feder,
rioo.tsukatsukii, wangjinchao600
> "accommodate". I'll fix this.
Thanks
> How does this look?
> + *
> + * Also, update TAINT_BUF_MAX below.
> */
> ...
> -/* 350 can accomadate all taint flags in verbose mode, with some headroom */
> +/* 350 can accommodate all taint flags in verbose mode, with some headroom */
> #define TAINT_BUF_MAX 350
Looks good, though it might help future maintainers if we document the current
maximum length of the verbose string (excluding the trailing NULL). Happy to
send a small follow-up patch if needed.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] kernel/panic: increase buffer size for verbose taint logging
2026-02-21 6:56 ` Rio
@ 2026-02-21 20:03 ` Andrew Morton
0 siblings, 0 replies; 8+ messages in thread
From: Andrew Morton @ 2026-02-21 20:03 UTC (permalink / raw)
To: Rio
Cc: feng.tang, joel.granados, linux-kernel, pmladek, pnina.feder,
wangjinchao600
On Sat, 21 Feb 2026 12:26:03 +0530 Rio <rioo.tsukatsukii@gmail.com> wrote:
> > "accommodate". I'll fix this.
>
> Thanks
>
> > How does this look?
>
> > + *
> > + * Also, update TAINT_BUF_MAX below.
> > */
> > ...
> > -/* 350 can accomadate all taint flags in verbose mode, with some headroom */
> > +/* 350 can accommodate all taint flags in verbose mode, with some headroom */
> > #define TAINT_BUF_MAX 350
>
> Looks good, though it might help future maintainers if we document the current
> maximum length of the verbose string (excluding the trailing NULL). Happy to
> send a small follow-up patch if needed.
OK, how about this idea.
- Allocating static storage is annoying: dynamic allocation is better
- Now knowing how large to make the storage is also annoying.
So:
- define a static buffer, mark it __initdata so it gets released
later in boot. Make print_tainted() use that, initially, so
print_tainted() is available at initial bootup time.
- write a new __init function which adds up all string lengths in
taint_flags[] and calculates the precise maximum needed buffer size.
Allocate that much memory (kmalloc) and switch print_tainted() over
to using that buffer.
- When __init data gets released, the initial static buffer and the
new __init function get thrown away.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2] kernel/panic: allocate taint string buffer dynamically
2026-02-20 15:15 [PATCH] kernel/panic: increase buffer size for verbose taint logging Rio
2026-02-20 21:06 ` Andrew Morton
@ 2026-02-22 14:08 ` Rio
2026-02-22 15:23 ` Rio
` (2 more replies)
1 sibling, 3 replies; 8+ messages in thread
From: Rio @ 2026-02-22 14:08 UTC (permalink / raw)
To: akpm
Cc: feng.tang, joel.granados, linux-kernel, pmladek, pnina.feder,
wangjinchao600, Rio
The buffer used to hold the taint string is statically allocated, which
requires updating whenever a new taint flag is added.
Instead, allocate the exact required length at boot once the allocator is
available in an init function. The allocation sums the string lengths in
taint_flags[], along with space for separators and formatting.
print_tainted() is switched to use this dynamically allocated buffer.
If allocation fails, print_tainted() warns about the failure and continues
to use the original static buffer as a fallback.
Signed-off-by: Rio <rioo.tsukatsukii@gmail.com>
---
V1 -> V2: Allocate taint string buffer dynamically during init
v1: https://lore.kernel.org/all/20260220151500.13585-1-rioo.tsukatsukii@gmail.com/
kernel/panic.c | 51 +++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 5 deletions(-)
diff --git a/kernel/panic.c b/kernel/panic.c
index 75368738d32d..5d498ff8a18b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -802,7 +802,7 @@ EXPORT_SYMBOL(panic);
* small shell script that prints the TAINT_FLAGS_COUNT bits of
* /proc/sys/kernel/tainted.
*
- * Also, update TAINT_BUF_MAX below.
+ * Also, update INIT_TAINT_BUF_MAX below.
*/
const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
TAINT_FLAG(PROPRIETARY_MODULE, 'P', 'G'),
@@ -856,17 +856,58 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose)
}
}
-/* 350 can accommodate all taint flags in verbose mode, with some headroom */
-#define TAINT_BUF_MAX 350
+/* The initial buffer can accommodate all taint flags in verbose
+ * mode, with some headroom. Once the allocator is available, the
+ * exact size is allocated dynamically; the initial buffer remains
+ * as a fallback if allocation fails.
+ *
+ * The verbose taint string currently requires up to 327 characters.
+ */
+#define INIT_TAINT_BUF_MAX 350
+
+static char init_taint_buf[INIT_TAINT_BUF_MAX];
+static char *taint_buf = init_taint_buf;
+static size_t taint_buf_size = INIT_TAINT_BUF_MAX;
+
+static __init int alloc_taint_buf(void)
+{
+ int i;
+ char *buf;
+ size_t size = 0;
+
+ size += sizeof("Tainted: ") - 1;
+ for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
+ size += 2; /* For ", " */
+ size += 4; /* For "[%c]=" */
+ size += strlen(taint_flags[i].desc);
+ }
+
+ size += 1; /* For NULL terminator */
+
+ buf = kmalloc(size, GFP_KERNEL);
+
+ if (!buf) {
+ /* Allocation may fail; this warning explains possibly
+ * truncated taint strings
+ */
+ pr_warn_once("taint string buffer allocation failed, using fallback buffer\n");
+ return 0;
+ }
+
+ taint_buf = buf;
+ taint_buf_size = size;
+
+ return 0;
+}
+postcore_initcall(alloc_taint_buf);
static const char *_print_tainted(bool verbose)
{
- static char buf[TAINT_BUF_MAX];
struct seq_buf s;
BUILD_BUG_ON(ARRAY_SIZE(taint_flags) != TAINT_FLAGS_COUNT);
- seq_buf_init(&s, buf, sizeof(buf));
+ seq_buf_init(&s, taint_buf, taint_buf_size);
print_tainted_seq(&s, verbose);
--
2.52.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCHv2] kernel/panic: allocate taint string buffer dynamically
2026-02-22 14:08 ` [PATCHv2] kernel/panic: allocate taint string buffer dynamically Rio
@ 2026-02-22 15:23 ` Rio
2026-02-22 19:25 ` Andrew Morton
2026-02-23 3:59 ` [PATCHv3] kernel/panic: mark init_taint_buf as __initdata and panic instead of warning in alloc_taint_buf() Rio
2 siblings, 0 replies; 8+ messages in thread
From: Rio @ 2026-02-22 15:23 UTC (permalink / raw)
To: rioo.tsukatsukii
Cc: akpm, feng.tang, joel.granados, linux-kernel, pmladek,
pnina.feder, wangjinchao600
This follow-up provides some tradeoffs between v1 and v2
- v1 used a fixed-size static buffer, requiring manual updates whenever
new strings are added to taint_flags[].
- v2 uses a fixed-size static buffer only for initial boot. Once kmalloc
is available, it allocates a dynamically sized buffer based on the total
length of strings in taint_flags[].
- v1 needs an update every time taint_flags[] is updated.
- v2 relies on the initial buffer as a fallback mechanism in case kmalloc
fails. The initial buffer is currently large enough for all taint strings,
but future updates to taint_flags[] may require adjustments.
- v1 is more predictable, but requires more manual maintenance.
- v2 is more convenient, but introduces subtle edge cases and potential
allocation issues.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCHv2] kernel/panic: allocate taint string buffer dynamically
2026-02-22 14:08 ` [PATCHv2] kernel/panic: allocate taint string buffer dynamically Rio
2026-02-22 15:23 ` Rio
@ 2026-02-22 19:25 ` Andrew Morton
2026-02-23 3:59 ` [PATCHv3] kernel/panic: mark init_taint_buf as __initdata and panic instead of warning in alloc_taint_buf() Rio
2 siblings, 0 replies; 8+ messages in thread
From: Andrew Morton @ 2026-02-22 19:25 UTC (permalink / raw)
To: Rio
Cc: feng.tang, joel.granados, linux-kernel, pmladek, pnina.feder,
wangjinchao600
On Sun, 22 Feb 2026 19:38:04 +0530 Rio <rioo.tsukatsukii@gmail.com> wrote:
> The buffer used to hold the taint string is statically allocated, which
> requires updating whenever a new taint flag is added.
>
> Instead, allocate the exact required length at boot once the allocator is
> available in an init function. The allocation sums the string lengths in
> taint_flags[], along with space for separators and formatting.
> print_tainted() is switched to use this dynamically allocated buffer.
>
> If allocation fails, print_tainted() warns about the failure and continues
> to use the original static buffer as a fallback.
>
Lovely, thanks.
>
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -802,7 +802,7 @@ EXPORT_SYMBOL(panic);
> * small shell script that prints the TAINT_FLAGS_COUNT bits of
> * /proc/sys/kernel/tainted.
> *
> - * Also, update TAINT_BUF_MAX below.
> + * Also, update INIT_TAINT_BUF_MAX below.
> */
> const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
> TAINT_FLAG(PROPRIETARY_MODULE, 'P', 'G'),
> @@ -856,17 +856,58 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose)
> }
> }
>
> -/* 350 can accommodate all taint flags in verbose mode, with some headroom */
> -#define TAINT_BUF_MAX 350
> +/* The initial buffer can accommodate all taint flags in verbose
> + * mode, with some headroom. Once the allocator is available, the
> + * exact size is allocated dynamically; the initial buffer remains
> + * as a fallback if allocation fails.
> + *
> + * The verbose taint string currently requires up to 327 characters.
> + */
> +#define INIT_TAINT_BUF_MAX 350
> +
> +static char init_taint_buf[INIT_TAINT_BUF_MAX];
OK, this cannot be __initdata because
> +static char *taint_buf = init_taint_buf;
> +static size_t taint_buf_size = INIT_TAINT_BUF_MAX;
> +
> +static __init int alloc_taint_buf(void)
> +{
> + int i;
> + char *buf;
> + size_t size = 0;
> +
> + size += sizeof("Tainted: ") - 1;
> + for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
> + size += 2; /* For ", " */
> + size += 4; /* For "[%c]=" */
> + size += strlen(taint_flags[i].desc);
> + }
> +
> + size += 1; /* For NULL terminator */
> +
> + buf = kmalloc(size, GFP_KERNEL);
> +
> + if (!buf) {
> + /* Allocation may fail; this warning explains possibly
> + * truncated taint strings
> + */
> + pr_warn_once("taint string buffer allocation failed, using fallback buffer\n");
> + return 0;
We may end up using it after boot time.
> + }
> +
> + taint_buf = buf;
> + taint_buf_size = size;
> +
> + return 0;
> +}
> +postcore_initcall(alloc_taint_buf);
However there's a convention of assuming that __init-time allocations
cannot fail. Because if a kmalloc() were to fail at this time, the
kernel is hopelessly messed up anyway.
So we could simply panic() if that kmalloc failed, then make that
350-byte buffer __initdata.
That saves about $100 per machine with current DRAM prices ;)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv3] kernel/panic: mark init_taint_buf as __initdata and panic instead of warning in alloc_taint_buf()
2026-02-22 14:08 ` [PATCHv2] kernel/panic: allocate taint string buffer dynamically Rio
2026-02-22 15:23 ` Rio
2026-02-22 19:25 ` Andrew Morton
@ 2026-02-23 3:59 ` Rio
2 siblings, 0 replies; 8+ messages in thread
From: Rio @ 2026-02-23 3:59 UTC (permalink / raw)
To: akpm
Cc: feng.tang, joel.granados, linux-kernel, pmladek, pnina.feder,
wangjinchao600, Rio
On Sun, Feb 22, 2026 at 11:25:52AM -0800, Andrew Morton wrote:
> However there's a convention of assuming that __init-time allocations
> cannot fail. Because if a kmalloc() were to fail at this time, the
> kernel is hopelessly messed up anyway.
> So we could simply panic() if that kmalloc failed, then make that
> 350-byte buffer __initdata.
Ah, got it. I made it __initdata, and replaced the warn with panic.
> That saves about $100 per machine with current DRAM prices ;)
Haha, saving every bit counts huh
Signed-off-by: Rio <rioo.tsukatsukii@gmail.com>
---
V2 -> V3: Mark initial buffer as __initdata and panic if allocation
fails
V1 -> V2: Allocate taint string buffer dynamically during init
v2: https://lore.kernel.org/all/20260222140804.22225-1-rioo.tsukatsukii@gmail.com/
v1: https://lore.kernel.org/all/20260220151500.13585-1-rioo.tsukatsukii@gmail.com/
kernel/panic.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/kernel/panic.c b/kernel/panic.c
index 5d498ff8a18b..20feada5319d 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -865,8 +865,8 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose)
*/
#define INIT_TAINT_BUF_MAX 350
-static char init_taint_buf[INIT_TAINT_BUF_MAX];
-static char *taint_buf = init_taint_buf;
+static char init_taint_buf[INIT_TAINT_BUF_MAX] __initdata;
+static char *taint_buf __refdata = init_taint_buf;
static size_t taint_buf_size = INIT_TAINT_BUF_MAX;
static __init int alloc_taint_buf(void)
@@ -887,11 +887,7 @@ static __init int alloc_taint_buf(void)
buf = kmalloc(size, GFP_KERNEL);
if (!buf) {
- /* Allocation may fail; this warning explains possibly
- * truncated taint strings
- */
- pr_warn_once("taint string buffer allocation failed, using fallback buffer\n");
- return 0;
+ panic("Failed to allocate taint string buffer");
}
taint_buf = buf;
--
2.52.0
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-02-23 4:00 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-20 15:15 [PATCH] kernel/panic: increase buffer size for verbose taint logging Rio
2026-02-20 21:06 ` Andrew Morton
2026-02-21 6:56 ` Rio
2026-02-21 20:03 ` Andrew Morton
2026-02-22 14:08 ` [PATCHv2] kernel/panic: allocate taint string buffer dynamically Rio
2026-02-22 15:23 ` Rio
2026-02-22 19:25 ` Andrew Morton
2026-02-23 3:59 ` [PATCHv3] kernel/panic: mark init_taint_buf as __initdata and panic instead of warning in alloc_taint_buf() Rio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®