* [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®