linux/arch/arm64/include/asm/fpu.h
Ard Biesheuvel 4fa617cc68 arm64/fpsimd: Allocate kernel mode FP/SIMD buffers on the stack
Commit aefbab8e77

  ("arm64: fpsimd: Preserve/restore kernel mode NEON at context switch")

added a 'kernel_fpsimd_state' field to struct thread_struct, which is
the arch-specific portion of struct task_struct, and is allocated for
each task in the system. The size of this field is 528 bytes, resulting
in non-negligible bloat of task_struct, and the resulting memory
overhead may impact performance on systems with many processes.

This allocation is only used if the task is scheduled out or interrupted
by a softirq while using the FP/SIMD unit in kernel mode, and so it is
possible to transparently allocate this buffer on the caller's stack
instead.

So tweak the 'ksimd' scoped guard implementation so that a stack buffer
is allocated and passed to both kernel_neon_begin() and
kernel_neon_end(), and either record it in the task struct, or use it
directly to preserve the task mode kernel FP/SIMD when running in
softirq context. Passing the address to both functions, and checking the
addresses for consistency ensures that callers of the updated bare
begin/end API use it in a manner that is consistent with the new context
switch semantics.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2025-11-12 09:52:03 +01:00

28 lines
448 B
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2023 SiFive
*/
#ifndef __ASM_FPU_H
#define __ASM_FPU_H
#include <linux/preempt.h>
#include <asm/neon.h>
#define kernel_fpu_available() cpu_has_neon()
static inline void kernel_fpu_begin(void)
{
BUG_ON(!in_task());
preempt_disable();
kernel_neon_begin(NULL);
}
static inline void kernel_fpu_end(void)
{
kernel_neon_end(NULL);
preempt_enable();
}
#endif /* ! __ASM_FPU_H */