[PATCH v3 1/2] sparc64: increase kernel thread stack size to 32K

From: Stian Halseth

Date: Sun Sep 27 2026 - 17:29:37 EST


From: Tony Rodriguez <unixpro1970@xxxxxxxxx>

Kernel stacks on sparc64 are 16K and this is no longer enough:
several machines (SPARC T5-2, Sun Ultra 45) panic early in boot
during USB hub enumeration with "corrupted stack end detected inside
scheduler". sparc has not been converted to THREAD_INFO_IN_TASK, so
thread_info sits at the bottom of the kernel stack and a marginal
overflow corrupts it first; CONFIG_SCHED_STACK_END_CHECK then fires
from __schedule long after the deep path has unwound, which is why
the reported backtraces look shallow.

Measurements with CONFIG_STACK_TRACER show the problem is frame
count, not any single large frame. On an UltraSPARC T4-1 the
high-water mark of an ordinary successful boot is 12616 of 16384
bytes (77%), reached in hub_probe() with a printk console flush and
a timer interrupt (which runs on the task stack) stacked on top. Of
the 66 frames in that path the largest is 408 bytes, and ~85% of
them are 176-224 bytes - at or just above the SPARC V9 ABI minimum
frame. An equivalent call chain on x86-64 costs roughly a third of
the stack, so a 16K stack on sparc64 provides far less effective
call depth than on other 64-bit architectures. On a Sun Ultra 45
(sun4u), which panics on 10 out of 10 boots with 16K stacks and USB
devices attached, a forced hub rebind peaks at 15832 bytes.

Double THREAD_SIZE to 32K (four 8K pages). Kernel stacks become
order-2 allocations; sparc64 has no VMAP_STACK, but stacks are
allocated once per thread and the trade against boot-time panics is
a good one.

Link: https://lore.kernel.org/all/20260519075809.8993-1-unixpro1970@xxxxxxxxx/
Tested-by: Imre Kaloz <kaloz@xxxxxxxxxx> # Sun Ultra 45
Signed-off-by: Tony Rodriguez <unixpro1970@xxxxxxxxx>
[stian: reduced to the minimal value change, measured stack usage]
Signed-off-by: Stian Halseth <stian@xxxxxx>
---
v3:
- split per Andreas' review of v1: this patch is now only the size
change (minimal diff as posted by Imre Kaloz); the removal of the
dead non-8K-page branches moves to patch 2/2 with a Fixes: tag
for 15b9350a177b
- added Imre's Tested-by and Ultra 45 (sun4u) measurements
v2: https://lore.kernel.org/all/20260831172928.3082853-1-stian@xxxxxx/

arch/sparc/include/asm/thread_info_64.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -100,8 +100,8 @@
#define FAULT_CODE_BAD_RA 0x20 /* Bad RA for sun4v */

#if PAGE_SHIFT == 13
-#define THREAD_SIZE (2*PAGE_SIZE)
-#define THREAD_SHIFT (PAGE_SHIFT + 1)
+#define THREAD_SIZE (4*PAGE_SIZE)
+#define THREAD_SHIFT (PAGE_SHIFT + 2)
#else /* PAGE_SHIFT == 13 */
#define THREAD_SIZE PAGE_SIZE
#define THREAD_SHIFT PAGE_SHIFT
@@ -129,7 +129,7 @@

/* thread information allocation */
#if PAGE_SHIFT == 13
-#define THREAD_SIZE_ORDER 1
+#define THREAD_SIZE_ORDER 2
#else /* PAGE_SHIFT == 13 */
#define THREAD_SIZE_ORDER 0
#endif /* PAGE_SHIFT == 13 */
--
2.53.0