Re: [PATCH 1/1] sparc64: unify thread stack sizing and add explicit 32KB stack

Nathaniel Roach <[email protected]> Tue, 19 May 2026 16:56:16 +0800
Newsgroups org.kernel.vger.sparclinux,dev.linux.lists.regressions,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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 <[email protected]>
Tested-by: Nathaniel Roach <[email protected]> # 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
>
>