mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
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>
28 lines
448 B
C
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 */
|