* [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack
@ 2026-05-19 7:57 Tony Rodriguez
2026-05-19 7:57 ` [PATCH 1/1] " Tony Rodriguez
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: Tony Rodriguez @ 2026-05-19 7:57 UTC (permalink / raw)
To: davem, sparclinux
Cc: linux-kernel, andreas, thuth, regressions, glaubitz, unixpro1970
This patch fixes a reproducible stack exhaustion issue on SPARC64
that occurs during USB hub enumeration. This regression may have
started sometime after kernel v6.12. With the default 16KB kernel
stack, the following panic is triggered early in boot:
[ 25.528399] Call Trace:
[ 25.528403] [<0000000000433cd4>] dump_stack+0x8/0x18
[ 25.528419] [<00000000004297ac>] vpanic+0xdc/0x318
[ 25.528429] [<0000000000429a0c>] panic+0x24/0x30
[ 25.528436] [<0000000000be2280>] __schedule+0xa8/0x7bc
[ 25.528445] [<0000000000be2b60>] schedule+0x24/0x4c
[ 25.528452] [<0000000000be6970>] schedule_timeout+0xc8/0xe4
[ 25.528459] [<0000000000be3318>] __wait_for_common+0x78/0xf0
[ 25.528466] [<0000000000be3550>] wait_for_completion_timeout+0x1c/0x2c
[ 25.528473] [<000000001005e2f4>] usb_start_wait_urb+0x68/0x128 [usbcore]
[ 25.528502] [<000000001005e468>] usb_control_msg+0xb4/0xf8 [usbcore]
[ 25.528518] [<0000000010051180>] set_port_feature+0x44/0x54 [usbcore]
[ 25.528530] [<00000000100530f0>] hub_power_on+0xc8/0xe8 [usbcore]
[ 25.528543] [<0000000010054fd8>] hub_activate+0x12c/0x644 [usbcore]
[ 25.528557] [<0000000010059438>] hub_probe+0xdd4/0xeb0 [usbcore]
[ 25.528570] [<0000000010062360>] usb_probe_interface+0x234/0x26c [usbcore]
[ 25.528585] [<0000000000a10a40>] really_probe+0x1ac/0x3b0
This is caused by large SPARC64 trapframes, register-window spills,
and deep call paths in usbcore. A 16KB stack is insufficient for
this workload.
The new logic is:
SPARC64:
THREAD_SIZE = 4 * PAGE_SIZE (32KB)
THREAD_SHIFT = PAGE_SHIFT + 2
THREAD_SIZE_ORDER = 2
Non‑SPARC64 with PAGE_SHIFT == 13:
Retains the existing 16KB stack behavior
Fallback:
Retains the existing 8KB stack behavior
Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com>
Tony Rodriguez (1):
sparc64: unify thread stack sizing and add explicit 32KB stack
arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++-------------
1 file changed, 14 insertions(+), 14 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-05-19 7:57 [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack Tony Rodriguez @ 2026-05-19 7:57 ` Tony Rodriguez 2026-05-19 8:56 ` Nathaniel Roach 2026-06-16 14:18 ` Andreas Larsson 2026-05-19 10:02 ` [PATCH 0/1] " David Laight 2026-08-31 17:29 ` [PATCH v2] sparc64: increase kernel thread stack size to 32K Stian Halseth 2 siblings, 2 replies; 19+ messages in thread From: Tony Rodriguez @ 2026-05-19 7:57 UTC (permalink / raw) To: davem, sparclinux Cc: linux-kernel, andreas, thuth, regressions, glaubitz, unixpro1970 This patch restructures the thread‑stack sizing logic into a single if / elif / else chain and introduces an explicit 32KB kernel stack for SPARC64. The previous implementation relied on nested conditionals and PAGE_SHIFT‑dependent behavior, which produced 8KB or 16KB stacks depending on configuration. SPARC64 requires a larger, architecture‑specific stack due to its trapframe size, register‑window behavior, and deeper call paths. A reproducible failure case occurs when usbcore is enabled: USB hub enumeration (usb_new_device(), hub_port_connect(), PM/QoS helpers) allocates large on‑stack structures and recurses through several layers of device‑model code. Combined with SPARC64’s trapframe and register‑window overhead, this reliably exhausts a 16KB stack and results in early‑boot panics. A 32KB stack eliminates these failures. The new logic is: SPARC64: THREAD_SIZE = 4 * PAGE_SIZE (32KB) THREAD_SHIFT = PAGE_SHIFT + 2 (log₂(32KB)) THREAD_SIZE_ORDER = 2 (4 contiguous pages) Non‑SPARC64 with PAGE_SHIFT == 13: Retains the existing 16KB stack behavior Fallback: Retains the existing 8KB stack behavior Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> --- arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index c8a73dff27f8..6b12a2b66385 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -99,13 +99,20 @@ struct thread_info { #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ #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) -#else /* PAGE_SHIFT == 13 */ -#define THREAD_SIZE PAGE_SIZE -#define THREAD_SHIFT PAGE_SHIFT -#endif /* PAGE_SHIFT == 13 */ +/* thread information allocation */ +#ifdef CONFIG_SPARC64 + #define THREAD_SIZE (4 * PAGE_SIZE) + #define THREAD_SHIFT (PAGE_SHIFT + 2) + #define THREAD_SIZE_ORDER 2 +#elif PAGE_SHIFT == 13 + #define THREAD_SIZE (2 * PAGE_SIZE) + #define THREAD_SHIFT (PAGE_SHIFT + 1) + #define THREAD_SIZE_ORDER 1 +#else + #define THREAD_SIZE PAGE_SIZE + #define THREAD_SHIFT PAGE_SHIFT + #define THREAD_SIZE_ORDER 0 +#endif /* * macros/functions for gaining access to the thread information structure @@ -127,13 +134,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); extern struct thread_info *current_thread_info(void); #endif -/* thread information allocation */ -#if PAGE_SHIFT == 13 -#define THREAD_SIZE_ORDER 1 -#else /* PAGE_SHIFT == 13 */ -#define THREAD_SIZE_ORDER 0 -#endif /* PAGE_SHIFT == 13 */ - #define __thread_flag_byte_ptr(ti) \ ((unsigned char *)(&((ti)->flags))) #define __cur_thread_flag_byte_ptr __thread_flag_byte_ptr(current_thread_info()) -- 2.53.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-05-19 7:57 ` [PATCH 1/1] " Tony Rodriguez @ 2026-05-19 8:56 ` Nathaniel Roach 2026-06-16 14:18 ` Andreas Larsson 1 sibling, 0 replies; 19+ messages in thread From: Nathaniel Roach @ 2026-05-19 8:56 UTC (permalink / raw) To: Tony Rodriguez, davem, sparclinux Cc: linux-kernel, andreas, thuth, regressions, glaubitz On 19/5/26 15:57, Tony Rodriguez wrote: > This patch restructures the thread‑stack sizing logic into a single > if / elif / else chain and introduces an explicit 32KB kernel stack > for SPARC64. The previous implementation relied on nested conditionals > and PAGE_SHIFT‑dependent behavior, which produced 8KB or 16KB stacks > depending on configuration. SPARC64 requires a larger, > architecture‑specific stack due to its trapframe size, register‑window > behavior, and deeper call paths. > > A reproducible failure case occurs when usbcore is enabled: USB hub > enumeration (usb_new_device(), hub_port_connect(), PM/QoS helpers) > allocates large on‑stack structures and recurses through several > layers of device‑model code. Combined with SPARC64’s trapframe and > register‑window overhead, this reliably exhausts a 16KB stack and > results in early‑boot panics. A 32KB stack eliminates these failures. > > The new logic is: > SPARC64: > THREAD_SIZE = 4 * PAGE_SIZE (32KB) > THREAD_SHIFT = PAGE_SHIFT + 2 (log₂(32KB)) > THREAD_SIZE_ORDER = 2 (4 contiguous pages) > Non‑SPARC64 with PAGE_SHIFT == 13: > Retains the existing 16KB stack behavior > Fallback: > Retains the existing 8KB stack behavior > > Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> Tested-by: Nathaniel Roach <nroach44@nroach44.id.au> # SPARC T5-2 > --- > arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- > 1 file changed, 14 insertions(+), 14 deletions(-) > > diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h > index c8a73dff27f8..6b12a2b66385 100644 > --- a/arch/sparc/include/asm/thread_info_64.h > +++ b/arch/sparc/include/asm/thread_info_64.h > @@ -99,13 +99,20 @@ struct thread_info { > #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ > #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) > -#else /* PAGE_SHIFT == 13 */ > -#define THREAD_SIZE PAGE_SIZE > -#define THREAD_SHIFT PAGE_SHIFT > -#endif /* PAGE_SHIFT == 13 */ > +/* thread information allocation */ > +#ifdef CONFIG_SPARC64 > + #define THREAD_SIZE (4 * PAGE_SIZE) > + #define THREAD_SHIFT (PAGE_SHIFT + 2) > + #define THREAD_SIZE_ORDER 2 > +#elif PAGE_SHIFT == 13 > + #define THREAD_SIZE (2 * PAGE_SIZE) > + #define THREAD_SHIFT (PAGE_SHIFT + 1) > + #define THREAD_SIZE_ORDER 1 > +#else > + #define THREAD_SIZE PAGE_SIZE > + #define THREAD_SHIFT PAGE_SHIFT > + #define THREAD_SIZE_ORDER 0 > +#endif > > /* > * macros/functions for gaining access to the thread information structure > @@ -127,13 +134,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); > extern struct thread_info *current_thread_info(void); > #endif > > -/* thread information allocation */ > -#if PAGE_SHIFT == 13 > -#define THREAD_SIZE_ORDER 1 > -#else /* PAGE_SHIFT == 13 */ > -#define THREAD_SIZE_ORDER 0 > -#endif /* PAGE_SHIFT == 13 */ > - > #define __thread_flag_byte_ptr(ti) \ > ((unsigned char *)(&((ti)->flags))) > #define __cur_thread_flag_byte_ptr __thread_flag_byte_ptr(current_thread_info()) > -- > 2.53.0 > > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-05-19 7:57 ` [PATCH 1/1] " Tony Rodriguez 2026-05-19 8:56 ` Nathaniel Roach @ 2026-06-16 14:18 ` Andreas Larsson 2026-06-16 19:58 ` David Laight 1 sibling, 1 reply; 19+ messages in thread From: Andreas Larsson @ 2026-06-16 14:18 UTC (permalink / raw) To: Tony Rodriguez, davem, sparclinux Cc: linux-kernel, andreas, thuth, regressions, glaubitz, David Laight On 2026-05-19 09:57, Tony Rodriguez wrote: > This patch restructures the thread‑stack sizing logic into a single > if / elif / else chain and introduces an explicit 32KB kernel stack > for SPARC64. The previous implementation relied on nested conditionals > and PAGE_SHIFT‑dependent behavior, which produced 8KB or 16KB stacks > depending on configuration. SPARC64 requires a larger, > architecture‑specific stack due to its trapframe size, register‑window > behavior, and deeper call paths. > > A reproducible failure case occurs when usbcore is enabled: USB hub > enumeration (usb_new_device(), hub_port_connect(), PM/QoS helpers) > allocates large on‑stack structures and recurses through several > layers of device‑model code. Combined with SPARC64’s trapframe and > register‑window overhead, this reliably exhausts a 16KB stack and > results in early‑boot panics. A 32KB stack eliminates these failures. > > The new logic is: > SPARC64: > THREAD_SIZE = 4 * PAGE_SIZE (32KB) > THREAD_SHIFT = PAGE_SHIFT + 2 (log₂(32KB)) > THREAD_SIZE_ORDER = 2 (4 contiguous pages) Yes > Non‑SPARC64 with PAGE_SHIFT == 13: > Retains the existing 16KB stack behavior > Fallback: > Retains the existing 8KB stack behavior No, not to my understanding, see comments below. > > Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> > --- > arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- > 1 file changed, 14 insertions(+), 14 deletions(-) > > diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h > index c8a73dff27f8..6b12a2b66385 100644 > --- a/arch/sparc/include/asm/thread_info_64.h > +++ b/arch/sparc/include/asm/thread_info_64.h > @@ -99,13 +99,20 @@ struct thread_info { > #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ > #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) > -#else /* PAGE_SHIFT == 13 */ > -#define THREAD_SIZE PAGE_SIZE > -#define THREAD_SHIFT PAGE_SHIFT > -#endif /* PAGE_SHIFT == 13 */ > +/* thread information allocation */ > +#ifdef CONFIG_SPARC64 > + #define THREAD_SIZE (4 * PAGE_SIZE) > + #define THREAD_SHIFT (PAGE_SHIFT + 2) > + #define THREAD_SIZE_ORDER 2 As far as I can see, given that this header is included by #if defined(__sparc__) && defined(__arch64__) #include <asm/thread_info_64.h> #else #include <asm/thread_info_32.h> #endif the code above is the only code that will ever be compiled, while leaving... > +#elif PAGE_SHIFT == 13 > + #define THREAD_SIZE (2 * PAGE_SIZE) > + #define THREAD_SHIFT (PAGE_SHIFT + 1) > + #define THREAD_SIZE_ORDER 1 > +#else > + #define THREAD_SIZE PAGE_SIZE > + #define THREAD_SHIFT PAGE_SHIFT > + #define THREAD_SIZE_ORDER 0 > +#endif ...this code dead, where the else branch code already was dead (but then in two separate else braches). I'd rather see the else branch here and the else branch below cleaned up by a separate patch with a fixup tag for commit 15b9350a177b ("sparc64: Only support 4MB huge pages and 8KB base pages.") that as far as I can see should have removed the else branch. The else branches was to use only one page when the page size was _larger_ than 8 KiB when that was an option. > > /* > * macros/functions for gaining access to the thread information structure > @@ -127,13 +134,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); > extern struct thread_info *current_thread_info(void); > #endif > > -/* thread information allocation */ > -#if PAGE_SHIFT == 13 > -#define THREAD_SIZE_ORDER 1 > -#else /* PAGE_SHIFT == 13 */ > -#define THREAD_SIZE_ORDER 0 > -#endif /* PAGE_SHIFT == 13 */ > - > #define __thread_flag_byte_ptr(ti) \ > ((unsigned char *)(&((ti)->flags))) > #define __cur_thread_flag_byte_ptr __thread_flag_byte_ptr(current_thread_info()) > -- > 2.53.0 > Apart from the above I agree with David Laight that more investigation of the situation that leads to this problem would be good. Granted, sparc and sparc64 in particular is a bit special with its stack frames, but among other arches it seems to be uncommon with 32 KiB of thread stack unless KASAN is enabled. Cheers, Andreas ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-06-16 14:18 ` Andreas Larsson @ 2026-06-16 19:58 ` David Laight 2026-06-18 5:53 ` Andreas Larsson 0 siblings, 1 reply; 19+ messages in thread From: David Laight @ 2026-06-16 19:58 UTC (permalink / raw) To: Andreas Larsson Cc: Tony Rodriguez, davem, sparclinux, linux-kernel, andreas, thuth, regressions, glaubitz On Tue, 16 Jun 2026 16:18:33 +0200 Andreas Larsson <andreas.larsson@gaisler.com> wrote: > On 2026-05-19 09:57, Tony Rodriguez wrote: > > This patch restructures the thread‑stack sizing logic into a single > > if / elif / else chain and introduces an explicit 32KB kernel stack > > for SPARC64. The previous implementation relied on nested conditionals > > and PAGE_SHIFT‑dependent behavior, which produced 8KB or 16KB stacks > > depending on configuration. SPARC64 requires a larger, > > architecture‑specific stack due to its trapframe size, register‑window > > behavior, and deeper call paths. > > > > A reproducible failure case occurs when usbcore is enabled: USB hub > > enumeration (usb_new_device(), hub_port_connect(), PM/QoS helpers) > > allocates large on‑stack structures and recurses through several > > layers of device‑model code. Combined with SPARC64’s trapframe and > > register‑window overhead, this reliably exhausts a 16KB stack and > > results in early‑boot panics. A 32KB stack eliminates these failures. > > > > The new logic is: > > SPARC64: > > THREAD_SIZE = 4 * PAGE_SIZE (32KB) > > THREAD_SHIFT = PAGE_SHIFT + 2 (log₂(32KB)) > > THREAD_SIZE_ORDER = 2 (4 contiguous pages) > > Yes > > > Non‑SPARC64 with PAGE_SHIFT == 13: > > Retains the existing 16KB stack behavior > > Fallback: > > Retains the existing 8KB stack behavior > > No, not to my understanding, see comments below. > > > > > Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> > > --- > > arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- > > 1 file changed, 14 insertions(+), 14 deletions(-) > > > > diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h > > index c8a73dff27f8..6b12a2b66385 100644 > > --- a/arch/sparc/include/asm/thread_info_64.h > > +++ b/arch/sparc/include/asm/thread_info_64.h > > @@ -99,13 +99,20 @@ struct thread_info { > > #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ > > #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) > > -#else /* PAGE_SHIFT == 13 */ > > -#define THREAD_SIZE PAGE_SIZE > > -#define THREAD_SHIFT PAGE_SHIFT > > -#endif /* PAGE_SHIFT == 13 */ > > +/* thread information allocation */ > > +#ifdef CONFIG_SPARC64 > > + #define THREAD_SIZE (4 * PAGE_SIZE) > > + #define THREAD_SHIFT (PAGE_SHIFT + 2) > > + #define THREAD_SIZE_ORDER 2 > > As far as I can see, given that this header is included by > > #if defined(__sparc__) && defined(__arch64__) > #include <asm/thread_info_64.h> > #else > #include <asm/thread_info_32.h> > #endif > > the code above is the only code that will ever be compiled, while leaving... > > > +#elif PAGE_SHIFT == 13 > > + #define THREAD_SIZE (2 * PAGE_SIZE) > > + #define THREAD_SHIFT (PAGE_SHIFT + 1) > > + #define THREAD_SIZE_ORDER 1 > > +#else > > + #define THREAD_SIZE PAGE_SIZE > > + #define THREAD_SHIFT PAGE_SHIFT > > + #define THREAD_SIZE_ORDER 0 > > +#endif > > ...this code dead, where the else branch code already was dead (but then > in two separate else braches). > > I'd rather see the else branch here and the else branch below cleaned up > by a separate patch with a fixup tag for commit 15b9350a177b ("sparc64: > Only support 4MB huge pages and 8KB base pages.") that as far as I can > see should have removed the else branch. The else branches was to use > only one page when the page size was _larger_ than 8 KiB when that was > an option. That whole logic is impenetrable. Why not set the 'desired thread size' in kB, then work out how many pages that ends up being based on the page size, and finally get the actual stack size. I'm not sure, but with vmalloc()ed stacks and 8k pages can't you have 24kB? David > > > > > /* > > * macros/functions for gaining access to the thread information structure > > @@ -127,13 +134,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); > > extern struct thread_info *current_thread_info(void); > > #endif > > > > -/* thread information allocation */ > > -#if PAGE_SHIFT == 13 > > -#define THREAD_SIZE_ORDER 1 > > -#else /* PAGE_SHIFT == 13 */ > > -#define THREAD_SIZE_ORDER 0 > > -#endif /* PAGE_SHIFT == 13 */ > > - > > #define __thread_flag_byte_ptr(ti) \ > > ((unsigned char *)(&((ti)->flags))) > > #define __cur_thread_flag_byte_ptr __thread_flag_byte_ptr(current_thread_info()) > > -- > > 2.53.0 > > > > Apart from the above I agree with David Laight that more investigation > of the situation that leads to this problem would be good. Granted, > sparc and sparc64 in particular is a bit special with its stack frames, > but among other arches it seems to be uncommon with 32 KiB of thread > stack unless KASAN is enabled. > > Cheers, > Andreas > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-06-16 19:58 ` David Laight @ 2026-06-18 5:53 ` Andreas Larsson 2026-06-18 7:29 ` Tony Rodriguez 2026-06-18 10:32 ` David Laight 0 siblings, 2 replies; 19+ messages in thread From: Andreas Larsson @ 2026-06-18 5:53 UTC (permalink / raw) To: David Laight, Andreas Larsson Cc: Tony Rodriguez, davem, sparclinux, linux-kernel, thuth, regressions, glaubitz On 2026-06-16 21:58, David Laight wrote: > On Tue, 16 Jun 2026 16:18:33 +0200 > Andreas Larsson <andreas.larsson@gaisler.com> wrote: > >> On 2026-05-19 09:57, Tony Rodriguez wrote: >>> This patch restructures the thread‑stack sizing logic into a single >>> if / elif / else chain and introduces an explicit 32KB kernel stack >>> for SPARC64. The previous implementation relied on nested conditionals >>> and PAGE_SHIFT‑dependent behavior, which produced 8KB or 16KB stacks >>> depending on configuration. SPARC64 requires a larger, >>> architecture‑specific stack due to its trapframe size, register‑window >>> behavior, and deeper call paths. >>> >>> A reproducible failure case occurs when usbcore is enabled: USB hub >>> enumeration (usb_new_device(), hub_port_connect(), PM/QoS helpers) >>> allocates large on‑stack structures and recurses through several >>> layers of device‑model code. Combined with SPARC64’s trapframe and >>> register‑window overhead, this reliably exhausts a 16KB stack and >>> results in early‑boot panics. A 32KB stack eliminates these failures. >>> >>> The new logic is: >>> SPARC64: >>> THREAD_SIZE = 4 * PAGE_SIZE (32KB) >>> THREAD_SHIFT = PAGE_SHIFT + 2 (log₂(32KB)) >>> THREAD_SIZE_ORDER = 2 (4 contiguous pages) >> >> Yes >> >>> Non‑SPARC64 with PAGE_SHIFT == 13: >>> Retains the existing 16KB stack behavior >>> Fallback: >>> Retains the existing 8KB stack behavior >> >> No, not to my understanding, see comments below. >> >>> >>> Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> >>> --- >>> arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- >>> 1 file changed, 14 insertions(+), 14 deletions(-) >>> >>> diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h >>> index c8a73dff27f8..6b12a2b66385 100644 >>> --- a/arch/sparc/include/asm/thread_info_64.h >>> +++ b/arch/sparc/include/asm/thread_info_64.h >>> @@ -99,13 +99,20 @@ struct thread_info { >>> #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ >>> #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) >>> -#else /* PAGE_SHIFT == 13 */ >>> -#define THREAD_SIZE PAGE_SIZE >>> -#define THREAD_SHIFT PAGE_SHIFT >>> -#endif /* PAGE_SHIFT == 13 */ >>> +/* thread information allocation */ >>> +#ifdef CONFIG_SPARC64 >>> + #define THREAD_SIZE (4 * PAGE_SIZE) >>> + #define THREAD_SHIFT (PAGE_SHIFT + 2) >>> + #define THREAD_SIZE_ORDER 2 >> >> As far as I can see, given that this header is included by >> >> #if defined(__sparc__) && defined(__arch64__) >> #include <asm/thread_info_64.h> >> #else >> #include <asm/thread_info_32.h> >> #endif >> >> the code above is the only code that will ever be compiled, while leaving... >> >>> +#elif PAGE_SHIFT == 13 >>> + #define THREAD_SIZE (2 * PAGE_SIZE) >>> + #define THREAD_SHIFT (PAGE_SHIFT + 1) >>> + #define THREAD_SIZE_ORDER 1 >>> +#else >>> + #define THREAD_SIZE PAGE_SIZE >>> + #define THREAD_SHIFT PAGE_SHIFT >>> + #define THREAD_SIZE_ORDER 0 >>> +#endif >> >> ...this code dead, where the else branch code already was dead (but then >> in two separate else braches). >> >> I'd rather see the else branch here and the else branch below cleaned up >> by a separate patch with a fixup tag for commit 15b9350a177b ("sparc64: >> Only support 4MB huge pages and 8KB base pages.") that as far as I can >> see should have removed the else branch. The else branches was to use >> only one page when the page size was _larger_ than 8 KiB when that was >> an option. > > That whole logic is impenetrable. > Why not set the 'desired thread size' in kB, then work out how many > pages that ends up being based on the page size, and finally get the actual > stack size. > I'm not sure, but with vmalloc()ed stacks and 8k pages can't you have 24kB? No, the next step up is 32 KiB as the stack allocation is sized by THREAD_SIZE_ORDER. Cheers, Andreas ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-06-18 5:53 ` Andreas Larsson @ 2026-06-18 7:29 ` Tony Rodriguez 2026-06-18 8:57 ` David Laight 2026-06-18 10:32 ` David Laight 1 sibling, 1 reply; 19+ messages in thread From: Tony Rodriguez @ 2026-06-18 7:29 UTC (permalink / raw) To: Andreas Larsson, David Laight, Andreas Larsson Cc: davem, sparclinux, linux-kernel, thuth, regressions, glaubitz On 6/17/26 10:53 PM, Andreas Larsson wrote: > On 2026-06-16 21:58, David Laight wrote: >> On Tue, 16 Jun 2026 16:18:33 +0200 >> Andreas Larsson <andreas.larsson@gaisler.com> wrote: >> >>> On 2026-05-19 09:57, Tony Rodriguez wrote: >>>> This patch restructures the thread‑stack sizing logic into a single >>>> if / elif / else chain and introduces an explicit 32KB kernel stack >>>> for SPARC64. The previous implementation relied on nested conditionals >>>> and PAGE_SHIFT‑dependent behavior, which produced 8KB or 16KB stacks >>>> depending on configuration. SPARC64 requires a larger, >>>> architecture‑specific stack due to its trapframe size, register‑window >>>> behavior, and deeper call paths. >>>> >>>> A reproducible failure case occurs when usbcore is enabled: USB hub >>>> enumeration (usb_new_device(), hub_port_connect(), PM/QoS helpers) >>>> allocates large on‑stack structures and recurses through several >>>> layers of device‑model code. Combined with SPARC64’s trapframe and >>>> register‑window overhead, this reliably exhausts a 16KB stack and >>>> results in early‑boot panics. A 32KB stack eliminates these failures. >>>> >>>> The new logic is: >>>> SPARC64: >>>> THREAD_SIZE = 4 * PAGE_SIZE (32KB) >>>> THREAD_SHIFT = PAGE_SHIFT + 2 (log₂(32KB)) >>>> THREAD_SIZE_ORDER = 2 (4 contiguous pages) >>> Yes >>> >>>> Non‑SPARC64 with PAGE_SHIFT == 13: >>>> Retains the existing 16KB stack behavior >>>> Fallback: >>>> Retains the existing 8KB stack behavior >>> No, not to my understanding, see comments below. >>> >>>> Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> >>>> --- >>>> arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- >>>> 1 file changed, 14 insertions(+), 14 deletions(-) >>>> >>>> diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h >>>> index c8a73dff27f8..6b12a2b66385 100644 >>>> --- a/arch/sparc/include/asm/thread_info_64.h >>>> +++ b/arch/sparc/include/asm/thread_info_64.h >>>> @@ -99,13 +99,20 @@ struct thread_info { >>>> #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ >>>> #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) >>>> -#else /* PAGE_SHIFT == 13 */ >>>> -#define THREAD_SIZE PAGE_SIZE >>>> -#define THREAD_SHIFT PAGE_SHIFT >>>> -#endif /* PAGE_SHIFT == 13 */ >>>> +/* thread information allocation */ >>>> +#ifdef CONFIG_SPARC64 >>>> + #define THREAD_SIZE (4 * PAGE_SIZE) >>>> + #define THREAD_SHIFT (PAGE_SHIFT + 2) >>>> + #define THREAD_SIZE_ORDER 2 >>> As far as I can see, given that this header is included by >>> >>> #if defined(__sparc__) && defined(__arch64__) >>> #include <asm/thread_info_64.h> >>> #else >>> #include <asm/thread_info_32.h> >>> #endif >>> >>> the code above is the only code that will ever be compiled, while leaving... >>> >>>> +#elif PAGE_SHIFT == 13 >>>> + #define THREAD_SIZE (2 * PAGE_SIZE) >>>> + #define THREAD_SHIFT (PAGE_SHIFT + 1) >>>> + #define THREAD_SIZE_ORDER 1 >>>> +#else >>>> + #define THREAD_SIZE PAGE_SIZE >>>> + #define THREAD_SHIFT PAGE_SHIFT >>>> + #define THREAD_SIZE_ORDER 0 >>>> +#endif >>> ...this code dead, where the else branch code already was dead (but then >>> in two separate else braches). >>> >>> I'd rather see the else branch here and the else branch below cleaned up >>> by a separate patch with a fixup tag for commit 15b9350a177b ("sparc64: >>> Only support 4MB huge pages and 8KB base pages.") that as far as I can >>> see should have removed the else branch. The else branches was to use >>> only one page when the page size was _larger_ than 8 KiB when that was >>> an option. >> That whole logic is impenetrable. >> Why not set the 'desired thread size' in kB, then work out how many >> pages that ends up being based on the page size, and finally get the actual >> stack size. >> I'm not sure, but with vmalloc()ed stacks and 8k pages can't you have 24kB? > No, the next step up is 32 KiB as the stack allocation is sized by > THREAD_SIZE_ORDER. > > Cheers, > Andreas > After additional testing and debugging on a SPARC64 S7-2 system running kernel v7.1-mainline, I've made several important observations regarding the USB core stack overflow issue. 1. The Stack Overflow is Real and Consistent My initial patch (increasing kernel stack to 32KB) appears to work with v7.1-mainline as well. However, the underlying problem remains: the USB core's stack usage consistently exceeds the default 16KB limit during hub enumeration. 2. The "Static Analysis vs. Runtime Reality" Contradiction When I compile the kernel with -fstack-usage to generate .su files, the static analysis shows small stack frames for all USB core functions. For example: hub_event: 2457 bytes (static) hub_activate: 1892 bytes (static) usb_control_msg: 1248 bytes (static) However, my runtime stack tracing shows a dramatically different picture: STACKTRACE: hub_event():entry: 31856 bytes used STACKTRACE: hub_activate():entry: 31680 bytes used STACKTRACE: usb_control_msg():entry: 30768 bytes used Please see: https://github.com/unixpro1970/Sparc64-Kernel-Debugging-Dumps/blob/main/usbcore-stacktrace.txt Perhaps the issue is the accumulation of register window spills across multiple nested function calls? 3. The 32KB Limit is Also at Risk I've observed that stack usage can approach the 32K limit as well. 4. Testing: TO DO: I will try adding a stack flush at the entry and exit of hub_event() . Hopefully it will prevent the accumulation of register windows. The theory is that flushing register windows between work items may prevent the stack growth from carrying over from one event to the next. If the flush helps, I may also look into "stack_trace_flush" David Miller's stack_trace_flush() implementation. Unsure if stack_trace_flush is supported with v7.1. Regards, Tony ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-06-18 7:29 ` Tony Rodriguez @ 2026-06-18 8:57 ` David Laight 0 siblings, 0 replies; 19+ messages in thread From: David Laight @ 2026-06-18 8:57 UTC (permalink / raw) To: Tony Rodriguez Cc: Andreas Larsson, Andreas Larsson, davem, sparclinux, linux-kernel, thuth, regressions, glaubitz On Thu, 18 Jun 2026 00:29:59 -0700 Tony Rodriguez <unixpro1970@gmail.com> wrote: > On 6/17/26 10:53 PM, Andreas Larsson wrote: > > On 2026-06-16 21:58, David Laight wrote: > >> On Tue, 16 Jun 2026 16:18:33 +0200 > >> Andreas Larsson <andreas.larsson@gaisler.com> wrote: > >> > >>> On 2026-05-19 09:57, Tony Rodriguez wrote: > >>>> This patch restructures the thread‑stack sizing logic into a single > >>>> if / elif / else chain and introduces an explicit 32KB kernel stack > >>>> for SPARC64. The previous implementation relied on nested conditionals > >>>> and PAGE_SHIFT‑dependent behavior, which produced 8KB or 16KB stacks > >>>> depending on configuration. SPARC64 requires a larger, > >>>> architecture‑specific stack due to its trapframe size, register‑window > >>>> behavior, and deeper call paths. > >>>> > >>>> A reproducible failure case occurs when usbcore is enabled: USB hub > >>>> enumeration (usb_new_device(), hub_port_connect(), PM/QoS helpers) > >>>> allocates large on‑stack structures and recurses through several > >>>> layers of device‑model code. Combined with SPARC64’s trapframe and > >>>> register‑window overhead, this reliably exhausts a 16KB stack and > >>>> results in early‑boot panics. A 32KB stack eliminates these failures. > >>>> > >>>> The new logic is: > >>>> SPARC64: > >>>> THREAD_SIZE = 4 * PAGE_SIZE (32KB) > >>>> THREAD_SHIFT = PAGE_SHIFT + 2 (log₂(32KB)) > >>>> THREAD_SIZE_ORDER = 2 (4 contiguous pages) > >>> Yes > >>> > >>>> Non‑SPARC64 with PAGE_SHIFT == 13: > >>>> Retains the existing 16KB stack behavior > >>>> Fallback: > >>>> Retains the existing 8KB stack behavior > >>> No, not to my understanding, see comments below. > >>> > >>>> Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> > >>>> --- > >>>> arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- > >>>> 1 file changed, 14 insertions(+), 14 deletions(-) > >>>> > >>>> diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h > >>>> index c8a73dff27f8..6b12a2b66385 100644 > >>>> --- a/arch/sparc/include/asm/thread_info_64.h > >>>> +++ b/arch/sparc/include/asm/thread_info_64.h > >>>> @@ -99,13 +99,20 @@ struct thread_info { > >>>> #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ > >>>> #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) > >>>> -#else /* PAGE_SHIFT == 13 */ > >>>> -#define THREAD_SIZE PAGE_SIZE > >>>> -#define THREAD_SHIFT PAGE_SHIFT > >>>> -#endif /* PAGE_SHIFT == 13 */ > >>>> +/* thread information allocation */ > >>>> +#ifdef CONFIG_SPARC64 > >>>> + #define THREAD_SIZE (4 * PAGE_SIZE) > >>>> + #define THREAD_SHIFT (PAGE_SHIFT + 2) > >>>> + #define THREAD_SIZE_ORDER 2 > >>> As far as I can see, given that this header is included by > >>> > >>> #if defined(__sparc__) && defined(__arch64__) > >>> #include <asm/thread_info_64.h> > >>> #else > >>> #include <asm/thread_info_32.h> > >>> #endif > >>> > >>> the code above is the only code that will ever be compiled, while leaving... > >>> > >>>> +#elif PAGE_SHIFT == 13 > >>>> + #define THREAD_SIZE (2 * PAGE_SIZE) > >>>> + #define THREAD_SHIFT (PAGE_SHIFT + 1) > >>>> + #define THREAD_SIZE_ORDER 1 > >>>> +#else > >>>> + #define THREAD_SIZE PAGE_SIZE > >>>> + #define THREAD_SHIFT PAGE_SHIFT > >>>> + #define THREAD_SIZE_ORDER 0 > >>>> +#endif > >>> ...this code dead, where the else branch code already was dead (but then > >>> in two separate else braches). > >>> > >>> I'd rather see the else branch here and the else branch below cleaned up > >>> by a separate patch with a fixup tag for commit 15b9350a177b ("sparc64: > >>> Only support 4MB huge pages and 8KB base pages.") that as far as I can > >>> see should have removed the else branch. The else branches was to use > >>> only one page when the page size was _larger_ than 8 KiB when that was > >>> an option. > >> That whole logic is impenetrable. > >> Why not set the 'desired thread size' in kB, then work out how many > >> pages that ends up being based on the page size, and finally get the actual > >> stack size. > >> I'm not sure, but with vmalloc()ed stacks and 8k pages can't you have 24kB? > > No, the next step up is 32 KiB as the stack allocation is sized by > > THREAD_SIZE_ORDER. > > > > Cheers, > > Andreas > > > > After additional testing and debugging on a SPARC64 S7-2 system running > kernel v7.1-mainline, I've made several important observations regarding > the USB core stack overflow issue. > > 1. The Stack Overflow is Real and Consistent > > My initial patch (increasing kernel stack to 32KB) appears to work with > v7.1-mainline as well. However, the underlying problem remains: the USB > core's stack usage consistently exceeds the default 16KB limit during > hub enumeration. > > 2. The "Static Analysis vs. Runtime Reality" Contradiction > > When I compile the kernel with -fstack-usage to generate .su files, the > static analysis shows small stack frames for all USB core functions. > > For example: > > hub_event: 2457 bytes (static) > hub_activate: 1892 bytes (static) > usb_control_msg: 1248 bytes (static) Those aren't that small. The stack frame for a minimal function seems to be 176 bytes. While there might be other places that allocate stack, most will be allocated by the 'save %sp, -nnn, %sp' instruction that rotates the register window (so the %sp it writes to is different from the one it reads from). Should be easy so find in the output of 'objdump -d vmlinux.o'. (search for function_name.: to find the start of a function) > > However, my runtime stack tracing shows a dramatically different picture: > > STACKTRACE: hub_event():entry: 31856 bytes used > STACKTRACE: hub_activate():entry: 31680 bytes used > STACKTRACE: usb_control_msg():entry: 30768 bytes used 31856 - 31680 = 176 31680 - 30768 = 912 Those might match the code being run. That makes it look like a lot of the problem is much earlier in the call stack. David ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-06-18 5:53 ` Andreas Larsson 2026-06-18 7:29 ` Tony Rodriguez @ 2026-06-18 10:32 ` David Laight 1 sibling, 0 replies; 19+ messages in thread From: David Laight @ 2026-06-18 10:32 UTC (permalink / raw) To: Andreas Larsson Cc: Andreas Larsson, Tony Rodriguez, davem, sparclinux, linux-kernel, thuth, regressions, glaubitz On Thu, 18 Jun 2026 07:53:02 +0200 Andreas Larsson <andreas@gaisler.com> wrote: > On 2026-06-16 21:58, David Laight wrote: ... > > That whole logic is impenetrable. > > Why not set the 'desired thread size' in kB, then work out how many > > pages that ends up being based on the page size, and finally get the actual > > stack size. > > I'm not sure, but with vmalloc()ed stacks and 8k pages can't you have 24kB? > > No, the next step up is 32 KiB as the stack allocation is sized by > THREAD_SIZE_ORDER. Maybe, but there is probably no reason why that has to be the case. I'm sure I've seem other architectures increasing the stack size by 4k. David > > Cheers, > Andreas > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-05-19 7:57 [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack Tony Rodriguez 2026-05-19 7:57 ` [PATCH 1/1] " Tony Rodriguez @ 2026-05-19 10:02 ` David Laight 2026-05-19 23:57 ` Tony Rodriguez 2026-08-31 17:29 ` [PATCH v2] sparc64: increase kernel thread stack size to 32K Stian Halseth 2 siblings, 1 reply; 19+ messages in thread From: David Laight @ 2026-05-19 10:02 UTC (permalink / raw) To: Tony Rodriguez Cc: davem, sparclinux, linux-kernel, andreas, thuth, regressions, glaubitz On Tue, 19 May 2026 00:57:54 -0700 Tony Rodriguez <unixpro1970@gmail.com> wrote: > This patch fixes a reproducible stack exhaustion issue on SPARC64 > that occurs during USB hub enumeration. This regression may have > started sometime after kernel v6.12. With the default 16KB kernel > stack, the following panic is triggered early in boot: > > [ 25.528399] Call Trace: > [ 25.528403] [<0000000000433cd4>] dump_stack+0x8/0x18 > [ 25.528419] [<00000000004297ac>] vpanic+0xdc/0x318 > [ 25.528429] [<0000000000429a0c>] panic+0x24/0x30 > [ 25.528436] [<0000000000be2280>] __schedule+0xa8/0x7bc > [ 25.528445] [<0000000000be2b60>] schedule+0x24/0x4c > [ 25.528452] [<0000000000be6970>] schedule_timeout+0xc8/0xe4 > [ 25.528459] [<0000000000be3318>] __wait_for_common+0x78/0xf0 > [ 25.528466] [<0000000000be3550>] wait_for_completion_timeout+0x1c/0x2c > [ 25.528473] [<000000001005e2f4>] usb_start_wait_urb+0x68/0x128 [usbcore] > [ 25.528502] [<000000001005e468>] usb_control_msg+0xb4/0xf8 [usbcore] > [ 25.528518] [<0000000010051180>] set_port_feature+0x44/0x54 [usbcore] > [ 25.528530] [<00000000100530f0>] hub_power_on+0xc8/0xe8 [usbcore] > [ 25.528543] [<0000000010054fd8>] hub_activate+0x12c/0x644 [usbcore] > [ 25.528557] [<0000000010059438>] hub_probe+0xdd4/0xeb0 [usbcore] > [ 25.528570] [<0000000010062360>] usb_probe_interface+0x234/0x26c [usbcore] > [ 25.528585] [<0000000000a10a40>] really_probe+0x1ac/0x3b0 > > This is caused by large SPARC64 trapframes, register-window spills, > and deep call paths in usbcore. A 16KB stack is insufficient for > this workload. Increasing the stack size for all threads seems overkill. That stack doesn't even look deep. I suspect there are large on-stack buffers in there. Unfortunately the traceback doesn't print the stack pointers making debugging hard. -- David > > The new logic is: > > SPARC64: > THREAD_SIZE = 4 * PAGE_SIZE (32KB) > THREAD_SHIFT = PAGE_SHIFT + 2 > THREAD_SIZE_ORDER = 2 > > Non‑SPARC64 with PAGE_SHIFT == 13: > Retains the existing 16KB stack behavior > > Fallback: > Retains the existing 8KB stack behavior > > Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> > > > Tony Rodriguez (1): > sparc64: unify thread stack sizing and add explicit 32KB stack > > arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- > 1 file changed, 14 insertions(+), 14 deletions(-) > > -- > 2.53.0 > > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-05-19 10:02 ` [PATCH 0/1] " David Laight @ 2026-05-19 23:57 ` Tony Rodriguez 2026-05-20 13:41 ` David Laight 0 siblings, 1 reply; 19+ messages in thread From: Tony Rodriguez @ 2026-05-19 23:57 UTC (permalink / raw) To: David Laight Cc: davem, sparclinux, linux-kernel, andreas, thuth, regressions, glaubitz On 5/19/26 3:02 AM, David Laight wrote: > On Tue, 19 May 2026 00:57:54 -0700 > Tony Rodriguez <unixpro1970@gmail.com> wrote: > >> This patch fixes a reproducible stack exhaustion issue on SPARC64 >> that occurs during USB hub enumeration. This regression may have >> started sometime after kernel v6.12. With the default 16KB kernel >> stack, the following panic is triggered early in boot: >> >> [ 25.528399] Call Trace: >> [ 25.528403] [<0000000000433cd4>] dump_stack+0x8/0x18 >> [ 25.528419] [<00000000004297ac>] vpanic+0xdc/0x318 >> [ 25.528429] [<0000000000429a0c>] panic+0x24/0x30 >> [ 25.528436] [<0000000000be2280>] __schedule+0xa8/0x7bc >> [ 25.528445] [<0000000000be2b60>] schedule+0x24/0x4c >> [ 25.528452] [<0000000000be6970>] schedule_timeout+0xc8/0xe4 >> [ 25.528459] [<0000000000be3318>] __wait_for_common+0x78/0xf0 >> [ 25.528466] [<0000000000be3550>] wait_for_completion_timeout+0x1c/0x2c >> [ 25.528473] [<000000001005e2f4>] usb_start_wait_urb+0x68/0x128 [usbcore] >> [ 25.528502] [<000000001005e468>] usb_control_msg+0xb4/0xf8 [usbcore] >> [ 25.528518] [<0000000010051180>] set_port_feature+0x44/0x54 [usbcore] >> [ 25.528530] [<00000000100530f0>] hub_power_on+0xc8/0xe8 [usbcore] >> [ 25.528543] [<0000000010054fd8>] hub_activate+0x12c/0x644 [usbcore] >> [ 25.528557] [<0000000010059438>] hub_probe+0xdd4/0xeb0 [usbcore] >> [ 25.528570] [<0000000010062360>] usb_probe_interface+0x234/0x26c [usbcore] >> [ 25.528585] [<0000000000a10a40>] really_probe+0x1ac/0x3b0 >> >> This is caused by large SPARC64 trapframes, register-window spills, >> and deep call paths in usbcore. A 16KB stack is insufficient for >> this workload. > Increasing the stack size for all threads seems overkill. > That stack doesn't even look deep. > I suspect there are large on-stack buffers in there. > > Unfortunately the traceback doesn't print the stack pointers making > debugging hard. > > -- David Hi David. Any specific grub command line keywords and values, and functions you recommend for debugging this? I would be happy to share Trace Calls, etc. so it is easier to reconfirm and zero in on the issue. -- Tony >> The new logic is: >> >> SPARC64: >> THREAD_SIZE = 4 * PAGE_SIZE (32KB) >> THREAD_SHIFT = PAGE_SHIFT + 2 >> THREAD_SIZE_ORDER = 2 >> >> Non‑SPARC64 with PAGE_SHIFT == 13: >> Retains the existing 16KB stack behavior >> >> Fallback: >> Retains the existing 8KB stack behavior >> >> Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> >> >> >> Tony Rodriguez (1): >> sparc64: unify thread stack sizing and add explicit 32KB stack >> >> arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- >> 1 file changed, 14 insertions(+), 14 deletions(-) >> >> -- >> 2.53.0 >> >> ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-05-19 23:57 ` Tony Rodriguez @ 2026-05-20 13:41 ` David Laight 2026-08-31 17:27 ` Stian Halseth 0 siblings, 1 reply; 19+ messages in thread From: David Laight @ 2026-05-20 13:41 UTC (permalink / raw) To: Tony Rodriguez Cc: davem, sparclinux, linux-kernel, andreas, thuth, regressions, glaubitz On Tue, 19 May 2026 16:57:04 -0700 Tony Rodriguez <unixpro1970@gmail.com> wrote: > On 5/19/26 3:02 AM, David Laight wrote: > > On Tue, 19 May 2026 00:57:54 -0700 > > Tony Rodriguez <unixpro1970@gmail.com> wrote: > > > >> This patch fixes a reproducible stack exhaustion issue on SPARC64 > >> that occurs during USB hub enumeration. This regression may have > >> started sometime after kernel v6.12. With the default 16KB kernel > >> stack, the following panic is triggered early in boot: > >> > >> [ 25.528399] Call Trace: > >> [ 25.528403] [<0000000000433cd4>] dump_stack+0x8/0x18 > >> [ 25.528419] [<00000000004297ac>] vpanic+0xdc/0x318 > >> [ 25.528429] [<0000000000429a0c>] panic+0x24/0x30 > >> [ 25.528436] [<0000000000be2280>] __schedule+0xa8/0x7bc > >> [ 25.528445] [<0000000000be2b60>] schedule+0x24/0x4c > >> [ 25.528452] [<0000000000be6970>] schedule_timeout+0xc8/0xe4 > >> [ 25.528459] [<0000000000be3318>] __wait_for_common+0x78/0xf0 > >> [ 25.528466] [<0000000000be3550>] wait_for_completion_timeout+0x1c/0x2c > >> [ 25.528473] [<000000001005e2f4>] usb_start_wait_urb+0x68/0x128 [usbcore] > >> [ 25.528502] [<000000001005e468>] usb_control_msg+0xb4/0xf8 [usbcore] > >> [ 25.528518] [<0000000010051180>] set_port_feature+0x44/0x54 [usbcore] > >> [ 25.528530] [<00000000100530f0>] hub_power_on+0xc8/0xe8 [usbcore] > >> [ 25.528543] [<0000000010054fd8>] hub_activate+0x12c/0x644 [usbcore] > >> [ 25.528557] [<0000000010059438>] hub_probe+0xdd4/0xeb0 [usbcore] > >> [ 25.528570] [<0000000010062360>] usb_probe_interface+0x234/0x26c [usbcore] > >> [ 25.528585] [<0000000000a10a40>] really_probe+0x1ac/0x3b0 > >> > >> This is caused by large SPARC64 trapframes, register-window spills, > >> and deep call paths in usbcore. A 16KB stack is insufficient for > >> this workload. > > Increasing the stack size for all threads seems overkill. > > That stack doesn't even look deep. > > I suspect there are large on-stack buffers in there. > > > > Unfortunately the traceback doesn't print the stack pointers making > > debugging hard. > > > > -- David > > Hi David. Any specific grub command line keywords and values, and > functions you recommend for debugging this? I would be happy to share > Trace Calls, etc. so it is easier to reconfirm and zero in on the issue. Without the stack offsets from the dump, look at the stack frame sizes for the functions in that traceback. I suspect there are too many that get near the compile-time threshold. -- David > -- Tony > > >> The new logic is: > >> > >> SPARC64: > >> THREAD_SIZE = 4 * PAGE_SIZE (32KB) > >> THREAD_SHIFT = PAGE_SHIFT + 2 > >> THREAD_SIZE_ORDER = 2 > >> > >> Non‑SPARC64 with PAGE_SHIFT == 13: > >> Retains the existing 16KB stack behavior > >> > >> Fallback: > >> Retains the existing 8KB stack behavior > >> > >> Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> > >> > >> > >> Tony Rodriguez (1): > >> sparc64: unify thread stack sizing and add explicit 32KB stack > >> > >> arch/sparc/include/asm/thread_info_64.h | 28 ++++++++++++------------- > >> 1 file changed, 14 insertions(+), 14 deletions(-) > >> > >> -- > >> 2.53.0 > >> > >> > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack 2026-05-20 13:41 ` David Laight @ 2026-08-31 17:27 ` Stian Halseth 0 siblings, 0 replies; 19+ messages in thread From: Stian Halseth @ 2026-08-31 17:27 UTC (permalink / raw) To: David Laight, Tony Rodriguez Cc: Stian Halseth, davem, sparclinux, linux-kernel, andreas, thuth, regressions, glaubitz On Wed, 20 May 2026 14:41:04 +0100, David Laight wrote: > Without the stack offsets from the dump, look at the stack frame sizes > for the functions in that traceback. > I suspect there are too many that get near the compile-time threshold. I measured this on an UltraSPARC T4-1 (sun4v, onboard NEC OHCI/EHCI, internal hub chain) running 7.2.0 with CONFIG_STACK_TRACER, booted with "stacktrace" so the tracer was armed before the hcd drivers probed. It is the opposite: no frame comes near the warning threshold - the largest in any capture is 408 bytes - but ~85% of frames are 176-224 bytes, i.e. at or just above the SPARC V9 ABI minimum (128-byte window save area + 48-byte argument save area, paid by every non-leaf call). The stack goes to frame count, not frame size. The high-water mark of an ordinary successful boot was 12616 of 16384 bytes, and the maximum path is exactly the contested one - hub_probe, with a printk and then a timer interrupt on top: 0) 12600 208 arch_ftrace_ops_list_func+0x130/0x1c0 1) 12392 176 hypervisor_xcall_deliver+0x4/0x320 2) 12216 208 xcall_deliver+0x128/0x140 3) 12008 176 arch_send_call_function_single_ipi+0x3c/0x60 [...] 7) 11304 176 sched_balance_trigger+0x39c/0x4e0 8) 11128 224 sched_tick+0xf0/0x2c0 [...] 13) 10168 176 timer_interrupt+0x78/0xc0 14) 9992 384 tl0_irq14+0x14/0x20 15) 9608 144 console_flush_one_record+0x2c4/0x4a0 [...] 21) 8424 176 _dev_info+0x38/0x48 22) 8248 208 hub_probe+0xe8/0x92c [23-49: usb_probe_interface -> device_add -> usb_set_configuration -> usb_new_device -> register_root_hub -> usb_add_hcd -> ohci_pci_probe, all frames 176-336 bytes] 50) 2968 176 pci_device_probe+0x7c/0x120 [51-64: driver core / initcall, 176-240 bytes each] 65) 400 400 0x0 (66 entries total; full trace on request) Re-running enumeration alone (zero stack_max_size, unbind/rebind the hcd PCI functions) reached 12168 bytes over 60 frames, same shape. So the margin is compositional: the USB probe path alone is ~9.6K, a printk with console flush adds ~1K, and one timer interrupt whose tick does load balancing and IPI delivery adds ~2.6K. Note the timer interrupt runs on the task stack, not the hardirq stack. The 3.7K that remains is ~20 more minimum frames; a deeper USB topology or a storage stack under the console plausibly closes that gap on the machines that panic. It also explains why Tony's backtrace looked shallow: sparc still keeps thread_info at the bottom of the kernel stack, so marginal overflow corrupts it first and CONFIG_SCHED_STACK_END_CHECK fires later from inside __schedule, after the deep path has unwound. The posted trace shows the detection point, not the overflow path. Caveat: the tracer samples at function entry and adds its own ~208 byte frame, so the real worst case is somewhat higher than measured; this box did not panic. The data says 16K is structurally tight on sparc64 - ordinary boot uses 77% of it on a minimal USB topology - not that it always overflows. So I think the direction of the patch is right, but the diff should be minimal: thread_info_64.h is only compiled on sparc64, so the CONFIG_SPARC64 / PAGE_SHIFT == 13 / fallback chain is mostly dead code. All that is needed is #define THREAD_SIZE (4 * PAGE_SIZE) #define THREAD_SHIFT (PAGE_SHIFT + 2) #define THREAD_SIZE_ORDER 2 at the cost of kernel stacks becoming order-2 allocations (no VMAP_STACK on sparc64). Since this has been sitting since May, I've respun it with the reduced diff and the measurements in the changelog, keeping Tony as author - v2 follows. Tested on the T4-1: the boot high-water mark is 12616 bytes on both kernels (the worst path is deterministic), i.e. 77% of a 16K stack vs 38% of 32K. Stian ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2] sparc64: increase kernel thread stack size to 32K 2026-05-19 7:57 [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack Tony Rodriguez 2026-05-19 7:57 ` [PATCH 1/1] " Tony Rodriguez 2026-05-19 10:02 ` [PATCH 0/1] " David Laight @ 2026-08-31 17:29 ` Stian Halseth 2026-08-31 18:25 ` Tony Rodriguez 2 siblings, 1 reply; 19+ messages in thread From: Stian Halseth @ 2026-08-31 17:29 UTC (permalink / raw) To: andreas, davem, sparclinux Cc: Tony Rodriguez, linux-kernel, david.laight.linux, glaubitz, thuth, regressions, nroach44, Stian Halseth From: Tony Rodriguez <unixpro1970@gmail.com> Kernel stacks on sparc64 are 16K and this is no longer enough: several machines (SPARC T5-2 among them) 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 on an UltraSPARC T4-1 show the problem is frame count, not any single large frame. 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 then a timer interrupt (which runs on the task stack, and whose scheduler tick performs load balancing and IPI delivery) 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 (128-byte register window save area plus 48-byte argument save area). 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. Double THREAD_SIZE to 32K (four 8K pages). The PAGE_SHIFT conditionals are dropped: sparc64 only supports 8K base pages, so the other branches were dead code. 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@gmail.com/ Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> [stian: reduced the diff to the THREAD_* defines, measured stack usage with CONFIG_STACK_TRACER and rewrote the changelog] Signed-off-by: Stian Halseth <stian@itx.no> --- v2: - drop the CONFIG_SPARC64 / PAGE_SHIFT conditional chain from v1; thread_info_64.h is only built on sparc64 and only 8K pages are supported, so define the three constants unconditionally - replace the panic backtrace in the changelog with stack tracer measurements answering David Laight's review comments: https://lore.kernel.org/all/20260520144104.618c75ca@pumpkin/ - retitled from "unify thread stack sizing and add explicit 32KB stack"; the sizing logic for other configurations is unchanged Tested on an UltraSPARC T4-1, booted with the stack tracer armed ("stacktrace") before and after this patch. The boot high-water mark is 12616 bytes on both kernels - the worst path (hub_probe with a printk and a timer interrupt on top) is deterministic - i.e. 77% of the 16K stack before, 38% of the 32K stack after. DEBUG_STACK_USAGE agrees: the peak boot-time task shows 9208 bytes left of 16K before vs 25592 bytes left of 32K after (7176 bytes used in both). arch/sparc/include/asm/thread_info_64.h | 15 +++------------ 1 file changed, 3 insertions(+), 12 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 @@ -99,13 +99,8 @@ #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ #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) -#else /* PAGE_SHIFT == 13 */ -#define THREAD_SIZE PAGE_SIZE -#define THREAD_SHIFT PAGE_SHIFT -#endif /* PAGE_SHIFT == 13 */ +#define THREAD_SIZE (4 * PAGE_SIZE) +#define THREAD_SHIFT (PAGE_SHIFT + 2) /* * macros/functions for gaining access to the thread information structure @@ -128,11 +123,7 @@ #endif /* thread information allocation */ -#if PAGE_SHIFT == 13 -#define THREAD_SIZE_ORDER 1 -#else /* PAGE_SHIFT == 13 */ -#define THREAD_SIZE_ORDER 0 -#endif /* PAGE_SHIFT == 13 */ +#define THREAD_SIZE_ORDER 2 #define __thread_flag_byte_ptr(ti) \ ((unsigned char *)(&((ti)->flags))) -- 2.53.0 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2] sparc64: increase kernel thread stack size to 32K 2026-08-31 17:29 ` [PATCH v2] sparc64: increase kernel thread stack size to 32K Stian Halseth @ 2026-08-31 18:25 ` Tony Rodriguez 2026-08-31 18:54 ` Stian Halseth 0 siblings, 1 reply; 19+ messages in thread From: Tony Rodriguez @ 2026-08-31 18:25 UTC (permalink / raw) To: Stian Halseth, andreas, davem, sparclinux Cc: linux-kernel, david.laight.linux, glaubitz, thuth, regressions, nroach44 Hi Stian, Thanks for following up regarding this, I am currently busy with other tasks. Back in May/June 2026, I also mentioned the following to Andreas: The combined stack usage is already very close to the 32K limit. If you need an immediate workaround, increasing the stack to 64 K may be the better option. That should provide enough headroom to avoid the stack overflow panics we are seeing. As of kernel 7.1, I haven't noticed any panics using a 32K stack, but once again a stack size that is so close to the 32K boundary is a concern. But once again, sparc64 definitely crashes with a 16K stack. The Nvidia/Mellonox mlx5 driver also allocates a big stack on sparc64, which pushes it to the 32K boundary. There may be other drivers that may do so as well. The 64K stack is more ideal. When I compile the kernel with -fstack-usage to generate .su files, on 7.1 kerner, the static analysis shows small stack frames for all USB core functions. For example: hub_event: 2457 bytes (static) hub_activate: 1892 bytes (static) usb_control_msg: 1248 bytes (static) However, my runtime stack tracing shows a dramatically different picture: STACKTRACE: hub_event():entry: 31856 bytes used STACKTRACE: hub_activate():entry: 31680 bytes used STACKTRACE: usb_control_msg():entry: 30768 bytes used PS - I have not tested a 64K stack yet, only 32K, and this is a heads-up recommendation. Tony On 8/31/26 10:29 AM, Stian Halseth wrote: > From: Tony Rodriguez <unixpro1970@gmail.com> > > Kernel stacks on sparc64 are 16K and this is no longer enough: > several machines (SPARC T5-2 among them) 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 on an UltraSPARC T4-1 show the > problem is frame count, not any single large frame. 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 then a timer > interrupt (which runs on the task stack, and whose scheduler tick > performs load balancing and IPI delivery) 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 > (128-byte register window save area plus 48-byte argument save > area). 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. > > Double THREAD_SIZE to 32K (four 8K pages). The PAGE_SHIFT > conditionals are dropped: sparc64 only supports 8K base pages, so > the other branches were dead code. 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@gmail.com/ > Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> > [stian: reduced the diff to the THREAD_* defines, measured stack > usage with CONFIG_STACK_TRACER and rewrote the changelog] > Signed-off-by: Stian Halseth <stian@itx.no> > --- > v2: > - drop the CONFIG_SPARC64 / PAGE_SHIFT conditional chain from v1; > thread_info_64.h is only built on sparc64 and only 8K pages are > supported, so define the three constants unconditionally > - replace the panic backtrace in the changelog with stack tracer > measurements answering David Laight's review comments: > https://lore.kernel.org/all/20260520144104.618c75ca@pumpkin/ > - retitled from "unify thread stack sizing and add explicit 32KB > stack"; the sizing logic for other configurations is unchanged > > Tested on an UltraSPARC T4-1, booted with the stack tracer armed > ("stacktrace") before and after this patch. The boot high-water mark > is 12616 bytes on both kernels - the worst path (hub_probe with a > printk and a timer interrupt on top) is deterministic - i.e. 77% of > the 16K stack before, 38% of the 32K stack after. DEBUG_STACK_USAGE > agrees: the peak boot-time task shows 9208 bytes left of 16K before > vs 25592 bytes left of 32K after (7176 bytes used in both). > > arch/sparc/include/asm/thread_info_64.h | 15 +++------------ > 1 file changed, 3 insertions(+), 12 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 > @@ -99,13 +99,8 @@ > #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */ > #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) > -#else /* PAGE_SHIFT == 13 */ > -#define THREAD_SIZE PAGE_SIZE > -#define THREAD_SHIFT PAGE_SHIFT > -#endif /* PAGE_SHIFT == 13 */ > +#define THREAD_SIZE (4 * PAGE_SIZE) > +#define THREAD_SHIFT (PAGE_SHIFT + 2) > > /* > * macros/functions for gaining access to the thread information structure > @@ -128,11 +123,7 @@ > #endif > > /* thread information allocation */ > -#if PAGE_SHIFT == 13 > -#define THREAD_SIZE_ORDER 1 > -#else /* PAGE_SHIFT == 13 */ > -#define THREAD_SIZE_ORDER 0 > -#endif /* PAGE_SHIFT == 13 */ > +#define THREAD_SIZE_ORDER 2 > > #define __thread_flag_byte_ptr(ti) \ > ((unsigned char *)(&((ti)->flags))) > -- > 2.53.0 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2] sparc64: increase kernel thread stack size to 32K 2026-08-31 18:25 ` Tony Rodriguez @ 2026-08-31 18:54 ` Stian Halseth 2026-08-31 20:18 ` Tony Rodriguez 0 siblings, 1 reply; 19+ messages in thread From: Stian Halseth @ 2026-08-31 18:54 UTC (permalink / raw) To: Tony Rodriguez, andreas, davem, sparclinux Cc: linux-kernel, david.laight.linux, glaubitz, thuth, regressions, nroach44 Hi Tony, You're welcome. I saw it was stuck, and wanted to push it along. Looks to me like a proper fix that should be included. PS: Don't want to take any credit, this is 100% your fix. If you rather want to handle it yourself, let me know :) -- Best regards Stian Halseth On Mon, 2026-08-31 at 11:25 -0700, Tony Rodriguez wrote: > > When I compile the kernel with -fstack-usage to generate .su files, > on > 7.1 kerner, the static analysis shows small stack frames for all USB > core functions. > For example: > > hub_event: 2457 bytes (static) > hub_activate: 1892 bytes (static) > usb_control_msg: 1248 bytes (static) > > However, my runtime stack tracing shows a dramatically different > picture: > > STACKTRACE: hub_event():entry: 31856 bytes used > STACKTRACE: hub_activate():entry: 31680 bytes used > STACKTRACE: usb_control_msg():entry: 30768 bytes used > I'm not quite sure what I'm looking at. Stack usage must _increase_ with call depth, but looks like it's decreasing? That shouldn't be possible, but maybe I'm misreading something? It kinda looks like you're showing sp - stack_base (space left). CONFIG_STACK_TRACER on the T4-1 measures 12.6K worst-case against 32K. Could you re-measure with stacktrace on the kernel command line? Happy to share the exact config/procedure. > > PS - I have not tested a 64K stack yet, only 32K, and this is a > heads-up > recommendation. > > > Tony > > On 8/31/26 10:29 AM, Stian Halseth wrote: > > From: Tony Rodriguez <unixpro1970@gmail.com> > > > > Kernel stacks on sparc64 are 16K and this is no longer enough: > > several machines (SPARC T5-2 among them) 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 on an UltraSPARC T4-1 show > > the > > problem is frame count, not any single large frame. 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 then a timer > > interrupt (which runs on the task stack, and whose scheduler tick > > performs load balancing and IPI delivery) 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 > > (128-byte register window save area plus 48-byte argument save > > area). 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. > > > > Double THREAD_SIZE to 32K (four 8K pages). The PAGE_SHIFT > > conditionals are dropped: sparc64 only supports 8K base pages, so > > the other branches were dead code. 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@gmail.com/ > > Signed-off-by: Tony Rodriguez <unixpro1970@gmail.com> > > [stian: reduced the diff to the THREAD_* defines, measured stack > > usage with CONFIG_STACK_TRACER and rewrote the changelog] > > Signed-off-by: Stian Halseth <stian@itx.no> > > --- > > v2: > > - drop the CONFIG_SPARC64 / PAGE_SHIFT conditional chain from v1; > > thread_info_64.h is only built on sparc64 and only 8K pages are > > supported, so define the three constants unconditionally > > - replace the panic backtrace in the changelog with stack tracer > > measurements answering David Laight's review comments: > > https://lore.kernel.org/all/20260520144104.618c75ca@pumpkin/ > > - retitled from "unify thread stack sizing and add explicit 32KB > > stack"; the sizing logic for other configurations is unchanged > > > > Tested on an UltraSPARC T4-1, booted with the stack tracer armed > > ("stacktrace") before and after this patch. The boot high-water > > mark > > is 12616 bytes on both kernels - the worst path (hub_probe with a > > printk and a timer interrupt on top) is deterministic - i.e. 77% of > > the 16K stack before, 38% of the 32K stack after. DEBUG_STACK_USAGE > > agrees: the peak boot-time task shows 9208 bytes left of 16K before > > vs 25592 bytes left of 32K after (7176 bytes used in both). > > > > arch/sparc/include/asm/thread_info_64.h | 15 +++------------ > > 1 file changed, 3 insertions(+), 12 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 > > @@ -99,13 +99,8 @@ > > #define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in > > copy_page */ > > #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) > > -#else /* PAGE_SHIFT == 13 */ > > -#define THREAD_SIZE PAGE_SIZE > > -#define THREAD_SHIFT PAGE_SHIFT > > -#endif /* PAGE_SHIFT == 13 */ > > +#define THREAD_SIZE (4 * PAGE_SIZE) > > +#define THREAD_SHIFT (PAGE_SHIFT + 2) > > > > /* > > * macros/functions for gaining access to the thread information > > structure > > @@ -128,11 +123,7 @@ > > #endif > > > > /* thread information allocation */ > > -#if PAGE_SHIFT == 13 > > -#define THREAD_SIZE_ORDER 1 > > -#else /* PAGE_SHIFT == 13 */ > > -#define THREAD_SIZE_ORDER 0 > > -#endif /* PAGE_SHIFT == 13 */ > > +#define THREAD_SIZE_ORDER 2 > > > > #define __thread_flag_byte_ptr(ti) \ > > ((unsigned char *)(&((ti)->flags))) > > -- > > 2.53.0 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2] sparc64: increase kernel thread stack size to 32K 2026-08-31 18:54 ` Stian Halseth @ 2026-08-31 20:18 ` Tony Rodriguez 2026-08-31 21:05 ` Stian Halseth 0 siblings, 1 reply; 19+ messages in thread From: Tony Rodriguez @ 2026-08-31 20:18 UTC (permalink / raw) To: Stian Halseth, andreas, davem, sparclinux Cc: linux-kernel, david.laight.linux, glaubitz, thuth, regressions, nroach44 Hi Stian, No problem at all, and I appreciate your honesty and for reaching out. It’s best to get this addressed as soon as possible if you have the time to work on it—I’m currently swamped with other tasks. Overall, I don’t mind if you take over these patches, and truly appreciate your assistance to the sparc64 community. Just please continue to give me a mention in any patches related to this work, since I spent a considerable amount of time debugging, researching, and validating the fixes. When I last tested on 7.0 and 7.1, both of my patches worked: A) sparc64: increase kernel thread stack size to 32K B) sparc64: Fix comparator problem with timer interrupts I was able to debug and validate these issues on S7‑2 and T7‑1 hardware. I’m not sure if others have reported similar problems on T4 or T5 systems. Regarding: STACKTRACE: hub_event():entry: 31856 bytes used STACKTRACE: hub_activate():entry: 31680 bytes used STACKTRACE: usb_control_msg():entry: 30768 bytes used This was a set of debugging code inserted into function hot spots and scripts to measure stack usage at runtime. It helped me identify trouble spots and gave me a better idea of where stack consumption was highest. At the time, I wondered whether it might be possible to reduce the stack size of usbcore and the Nvidia mlx5 functions on sparc64, but that would be a significantly more time‑consuming task. I may have updated my stack monitoring script since then as well. It’s also been a few months, so I’d need to refresh my memory on the details. If you have a quicker or better methodology for reviewing stack usage—or any general suggestions—I’m definitely open to seeing them, along with your config and exact procedure. And if you need help validating against S7‑2 and T7‑1 hardware, I can try to allocate some time to assist. Best regards, Tony On 8/31/26 11:54 AM, Stian Halseth wrote: > Hi Tony, > > You're welcome. > > I saw it was stuck, and wanted to push it along. Looks to me like a > proper fix that should be included. > > PS: Don't want to take any credit, this is 100% your fix. If you rather > want to handle it yourself, let me know :) > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2] sparc64: increase kernel thread stack size to 32K 2026-08-31 20:18 ` Tony Rodriguez @ 2026-08-31 21:05 ` Stian Halseth 2026-09-02 3:30 ` Tony Rodriguez 0 siblings, 1 reply; 19+ messages in thread From: Stian Halseth @ 2026-08-31 21:05 UTC (permalink / raw) To: Tony Rodriguez, andreas, davem, sparclinux Cc: linux-kernel, david.laight.linux, glaubitz, thuth, regressions, nroach44 Hi Tony, On Mon, 2026-08-31 at 13:18 -0700, Tony Rodriguez wrote: > Hi Stian, > > Just please continue to give me a > mention in any patches related to this work, since I spent a > considerable amount of time debugging, researching, and validating > the fixes. Sure. For now, no real changes have been made to your patches, so as far as I'm concerned, this is entirely your work. Will try help with the last mile, alongside some other patches I've submitted. And yes, the debugging, researching and validation is the hard part. Writing a fix is often _relatively_ easy, when you have all the facts. > > When I last tested on 7.0 and 7.1, both of my patches worked: > > A) sparc64: increase kernel thread stack size to 32K > > B) sparc64: Fix comparator problem with timer interrupts > > I was able to debug and validate these issues on S7‑2 and T7‑1 > hardware. Yes, and that's a very important data point. My analyzis is based on the change itself, _and_ your validation/testing. > I’m not sure if others have reported similar problems on T4 or T5 > systems. Not that I'm aware of, and I haven't seen it on my T4-1. > > If you have a quicker or better methodology for reviewing stack > usage—or > any general suggestions—I’m definitely open to seeing them, along > with > your config and exact procedure. And if you need help validating > against > S7‑2 and T7‑1 hardware, I can try to allocate some time to assist. I think that would be very helpful. Let's try to settle the 32K-vs-64K question with more data. The kernel has stack measurement built in. The in-kernel method: CONFIG_STACK_TRACER=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_SCHED_STACK_END_CHECK=y Boot with "stacktrace" on the kernel command line (arms the tracer before built-in drivers probe). Then: cat /sys/kernel/tracing/stack_max_size # worst case seen, bytes cat /sys/kernel/tracing/stack_trace # that path, frame by frame Reset with "echo 0 > stack_max_size" before a workload to isolate it. For the 32K-vs-64K question, the most valuable data you could gather is a stack_trace snapshot on the S7-2/T7-1 under your real workload with mlx5 active, on a 32K kernel. On our T4-1 the worst case is 12616 bytes, but doesn't have mlx5. If your machines stay well under 32K, we have comfortable margin. But if something approaches the limit, the trace will name the exact frames, and we can judge whether the right answer is 64K or a targeted fix in that driver. > Thanks! -- Best regards Stian Halseth ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2] sparc64: increase kernel thread stack size to 32K 2026-08-31 21:05 ` Stian Halseth @ 2026-09-02 3:30 ` Tony Rodriguez 0 siblings, 0 replies; 19+ messages in thread From: Tony Rodriguez @ 2026-09-02 3:30 UTC (permalink / raw) To: Stian Halseth, andreas, davem, sparclinux Cc: linux-kernel, david.laight.linux, glaubitz, thuth, regressions, nroach44 Thanks again for the details, but I already had those CONFIG and stacktrace options defined based on previous debugging sessions. 32K should be fine based on the output (see the link below), and I have not noticed any crashes with a 32K stack). These results are against kernel v7.1.0-rc3 using my original patches on the S7-2. https://github.com/unixpro1970/Sparc64-Kernel-Debugging-Dumps/blob/main/kernel-v7.1.0-rc3-depth-stack-trace-sparc64-s7-2.txt Should I try your revised 32k stack and timer patches on the S7-2 and T7-1? If so, which kernel version did you validate against 7.2 or 7.3? Regards, Tony On 8/31/26 2:05 PM, Stian Halseth wrote: > Hi Tony, > > On Mon, 2026-08-31 at 13:18 -0700, Tony Rodriguez wrote: >> Hi Stian, >> >> Just please continue to give me a >> mention in any patches related to this work, since I spent a >> considerable amount of time debugging, researching, and validating >> the fixes. > Sure. For now, no real changes have been made to your patches, so as > far as I'm concerned, this is entirely your work. > Will try help with the last mile, alongside some other patches I've > submitted. > And yes, the debugging, researching and validation is the hard part. > Writing a fix is often _relatively_ easy, when you have all the facts. >> When I last tested on 7.0 and 7.1, both of my patches worked: >> >> A) sparc64: increase kernel thread stack size to 32K >> >> B) sparc64: Fix comparator problem with timer interrupts >> >> I was able to debug and validate these issues on S7‑2 and T7‑1 >> hardware. > Yes, and that's a very important data point. My analyzis is based on > the change itself, _and_ your validation/testing. >> I’m not sure if others have reported similar problems on T4 or T5 >> systems. > Not that I'm aware of, and I haven't seen it on my T4-1. >> If you have a quicker or better methodology for reviewing stack >> usage—or >> any general suggestions—I’m definitely open to seeing them, along >> with >> your config and exact procedure. And if you need help validating >> against >> S7‑2 and T7‑1 hardware, I can try to allocate some time to assist. > I think that would be very helpful. Let's try to settle the 32K-vs-64K > question with more data. > > The kernel has stack measurement built in. > > The in-kernel method: > CONFIG_STACK_TRACER=y > CONFIG_DEBUG_STACK_USAGE=y > CONFIG_SCHED_STACK_END_CHECK=y > > Boot with "stacktrace" on the kernel command line (arms the tracer > before built-in drivers probe). Then: > > cat /sys/kernel/tracing/stack_max_size # worst case seen, bytes > cat /sys/kernel/tracing/stack_trace # that path, frame by frame > > Reset with "echo 0 > stack_max_size" before a workload to isolate it. > > For the 32K-vs-64K question, the most valuable data you could gather > is a stack_trace snapshot on the S7-2/T7-1 under your real workload > with mlx5 active, on a 32K kernel. > > On our T4-1 the worst case is 12616 bytes, but doesn't have mlx5. If > your machines stay well under 32K, we have comfortable margin. But if > something approaches the limit, the trace will name the exact frames, > and we can judge whether the right answer is 64K or a targeted fix in > that driver. > Thanks! > ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-09-02 3:30 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-05-19 7:57 [PATCH 0/1] sparc64: unify thread stack sizing and add explicit 32KB stack Tony Rodriguez 2026-05-19 7:57 ` [PATCH 1/1] " Tony Rodriguez 2026-05-19 8:56 ` Nathaniel Roach 2026-06-16 14:18 ` Andreas Larsson 2026-06-16 19:58 ` David Laight 2026-06-18 5:53 ` Andreas Larsson 2026-06-18 7:29 ` Tony Rodriguez 2026-06-18 8:57 ` David Laight 2026-06-18 10:32 ` David Laight 2026-05-19 10:02 ` [PATCH 0/1] " David Laight 2026-05-19 23:57 ` Tony Rodriguez 2026-05-20 13:41 ` David Laight 2026-08-31 17:27 ` Stian Halseth 2026-08-31 17:29 ` [PATCH v2] sparc64: increase kernel thread stack size to 32K Stian Halseth 2026-08-31 18:25 ` Tony Rodriguez 2026-08-31 18:54 ` Stian Halseth 2026-08-31 20:18 ` Tony Rodriguez 2026-08-31 21:05 ` Stian Halseth 2026-09-02 3:30 ` Tony Rodriguez
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.