diff mbox series

[v4,1/4] arm64: fpsimd: Drop unneeded 'busy' flag

Message ID 20231208113218.3001940-7-ardb@google.com
State New
Headers show
Series arm64: Run kernel mode NEON with preemption enabled | expand

Commit Message

Ard Biesheuvel Dec. 8, 2023, 11:32 a.m. UTC
From: Ard Biesheuvel <ardb@kernel.org>

Kernel mode NEON will preserve the user mode FPSIMD state by saving it
into the task struct before clobbering the registers. In order to avoid
the need for preserving kernel mode state too, we disallow nested use of
kernel mode NEON, i..e, use in softirq context while the interrupted
task context was using kernel mode NEON too.

Originally, this policy was implemented using a per-CPU flag which was
exposed via may_use_simd(), requiring the users of the kernel mode NEON
to deal with the possibility that it might return false, and having NEON
and non-NEON code paths. This policy was changed by commit
13150149aa6ded1 ("arm64: fpsimd: run kernel mode NEON with softirqs
disabled"), and now, softirq processing is disabled entirely instead,
and so may_use_simd() can never fail when called from task or softirq
context.

This means we can drop the fpsimd_context_busy flag entirely, and
instead, ensure that we disable softirq processing in places where we
formerly relied on the flag for preventing races in the FPSIMD preserve
routines.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/include/asm/simd.h | 11 +---
 arch/arm64/kernel/fpsimd.c    | 53 +++++---------------
 2 files changed, 13 insertions(+), 51 deletions(-)

Comments

Geert Uytterhoeven Dec. 12, 2023, 11:27 a.m. UTC | #1
Hi Ard,

On Fri, Dec 8, 2023 at 12:34 PM Ard Biesheuvel <ardb@google.com> wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
> Kernel mode NEON will preserve the user mode FPSIMD state by saving it
> into the task struct before clobbering the registers. In order to avoid
> the need for preserving kernel mode state too, we disallow nested use of
> kernel mode NEON, i..e, use in softirq context while the interrupted
> task context was using kernel mode NEON too.
>
> Originally, this policy was implemented using a per-CPU flag which was
> exposed via may_use_simd(), requiring the users of the kernel mode NEON
> to deal with the possibility that it might return false, and having NEON
> and non-NEON code paths. This policy was changed by commit
> 13150149aa6ded1 ("arm64: fpsimd: run kernel mode NEON with softirqs
> disabled"), and now, softirq processing is disabled entirely instead,
> and so may_use_simd() can never fail when called from task or softirq
> context.
>
> This means we can drop the fpsimd_context_busy flag entirely, and
> instead, ensure that we disable softirq processing in places where we
> formerly relied on the flag for preventing races in the FPSIMD preserve
> routines.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> Reviewed-by: Mark Brown <broonie@kernel.org>

Thanks for your patch, which is now commit e109130b0e5ec3fd
("arm64: fpsimd: Drop unneeded 'busy' flag") in arm64/for-next/core
and next-20231212.

I have bisected the following warning during boot (on Salvator-XS with
R-Car H3 ES2.0 and on White-Hawk with R-Car V4H) followed by a lock-up
(on Salvator-XS) to this commit:

Reverting commits 035262623959cbe1 ("arm64: fpsimd: Implement lazy
restore for kernel mode FPSIMD"), 1e3a3de1ff6ca6b1 ("arm64: fpsimd:
Preserve/restore kernel mode NEON at context switch"), and this commit
fixes the issue.

Gr{oetje,eeting}s,

                        Geert
Will Deacon Dec. 12, 2023, 12:29 p.m. UTC | #2
Hi Geert,

Cheers for the report.

On Tue, Dec 12, 2023 at 12:27:50PM +0100, Geert Uytterhoeven wrote:
> On Fri, Dec 8, 2023 at 12:34 PM Ard Biesheuvel <ardb@google.com> wrote:
> > From: Ard Biesheuvel <ardb@kernel.org>
> > Kernel mode NEON will preserve the user mode FPSIMD state by saving it
> > into the task struct before clobbering the registers. In order to avoid
> > the need for preserving kernel mode state too, we disallow nested use of
> > kernel mode NEON, i..e, use in softirq context while the interrupted
> > task context was using kernel mode NEON too.
> >
> > Originally, this policy was implemented using a per-CPU flag which was
> > exposed via may_use_simd(), requiring the users of the kernel mode NEON
> > to deal with the possibility that it might return false, and having NEON
> > and non-NEON code paths. This policy was changed by commit
> > 13150149aa6ded1 ("arm64: fpsimd: run kernel mode NEON with softirqs
> > disabled"), and now, softirq processing is disabled entirely instead,
> > and so may_use_simd() can never fail when called from task or softirq
> > context.
> >
> > This means we can drop the fpsimd_context_busy flag entirely, and
> > instead, ensure that we disable softirq processing in places where we
> > formerly relied on the flag for preventing races in the FPSIMD preserve
> > routines.
> >
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > Reviewed-by: Mark Brown <broonie@kernel.org>
> 
> Thanks for your patch, which is now commit e109130b0e5ec3fd
> ("arm64: fpsimd: Drop unneeded 'busy' flag") in arm64/for-next/core
> and next-20231212.
> 
> I have bisected the following warning during boot (on Salvator-XS with
> R-Car H3 ES2.0 and on White-Hawk with R-Car V4H) followed by a lock-up
> (on Salvator-XS) to this commit:

Please can you provide the output from the warning and, if possible, a
pointer to your .config?

Cheers,

Will
Geert Uytterhoeven Dec. 12, 2023, 12:34 p.m. UTC | #3
Hi Will,

On Tue, Dec 12, 2023 at 1:30 PM Will Deacon <will@kernel.org> wrote:
> On Tue, Dec 12, 2023 at 12:27:50PM +0100, Geert Uytterhoeven wrote:
> > On Fri, Dec 8, 2023 at 12:34 PM Ard Biesheuvel <ardb@google.com> wrote:
> > > From: Ard Biesheuvel <ardb@kernel.org>
> > > Kernel mode NEON will preserve the user mode FPSIMD state by saving it
> > > into the task struct before clobbering the registers. In order to avoid
> > > the need for preserving kernel mode state too, we disallow nested use of
> > > kernel mode NEON, i..e, use in softirq context while the interrupted
> > > task context was using kernel mode NEON too.
> > >
> > > Originally, this policy was implemented using a per-CPU flag which was
> > > exposed via may_use_simd(), requiring the users of the kernel mode NEON
> > > to deal with the possibility that it might return false, and having NEON
> > > and non-NEON code paths. This policy was changed by commit
> > > 13150149aa6ded1 ("arm64: fpsimd: run kernel mode NEON with softirqs
> > > disabled"), and now, softirq processing is disabled entirely instead,
> > > and so may_use_simd() can never fail when called from task or softirq
> > > context.
> > >
> > > This means we can drop the fpsimd_context_busy flag entirely, and
> > > instead, ensure that we disable softirq processing in places where we
> > > formerly relied on the flag for preventing races in the FPSIMD preserve
> > > routines.
> > >
> > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > > Reviewed-by: Mark Brown <broonie@kernel.org>
> >
> > Thanks for your patch, which is now commit e109130b0e5ec3fd
> > ("arm64: fpsimd: Drop unneeded 'busy' flag") in arm64/for-next/core
> > and next-20231212.
> >
> > I have bisected the following warning during boot (on Salvator-XS with
> > R-Car H3 ES2.0 and on White-Hawk with R-Car V4H) followed by a lock-up
> > (on Salvator-XS) to this commit:
>
> Please can you provide the output from the warning and, if possible, a

Oops, how did that log disappear?

------------[ cut here ]------------
WARNING: CPU: 0 PID: 0 at kernel/softirq.c:361 __local_bh_enable_ip+0x1a4/0x1c8
CPU: 0 PID: 0 Comm: swapper/0 Not tainted
6.7.0-rc3-arm64-renesas-00001-ge109130b0e5e #2383
Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
pstate: 400000c5 (nZcv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __local_bh_enable_ip+0x1a4/0x1c8
lr : fpsimd_save_and_flush_cpu_state+0x4c/0x58
sp : ffff800081703bb0
x29: ffff800081703bb0 x28: ffff80008171c6b0 x27: ffff8000800167fc
x26: 0000000000000000 x25: 0000000000000000 x24: ffff800081710a68
x23: ffff8000813c4008 x22: ffff800081703ca4 x21: 0000000000000000
x20: ffff8000800167c8 x19: 0000000000000200 x18: ffffffffffffffff
x17: ffff0004c27f2400 x16: 0000000000000001 x15: 0000000000000003
x14: 0000000000000000 x13: 0000000000000003 x12: 0000000000000000
x11: 071c71c71c71c71c x10: ffff800082086b88 x9 : 0000000000000000
x8 : ffff80008203ab50 x7 : 0000000000000bb0 x6 : ffff80008203b700
x5 : ffff80067e2ee000 x4 : 0000000000000202 x3 : ffff80067e2ee000
x2 : ffff80067e2ee000 x1 : ffff800081719fc0 x0 : 0000000100000202
Call trace:
 __local_bh_enable_ip+0x1a4/0x1c8
 fpsimd_save_and_flush_cpu_state+0x4c/0x58
 fpsimd_cpu_pm_notifier+0x1c/0x28
 notifier_call_chain+0x9c/0x174
 raw_notifier_call_chain_robust+0x40/0x98
 cpu_pm_enter+0x3c/0x70
 psci_enter_idle_state+0x28/0x78
 cpuidle_enter_state+0xe4/0x568
 cpuidle_enter+0x34/0x48
 do_idle+0x214/0x290
 cpu_startup_entry+0x34/0x38
 rest_init+0xf8/0x188
 arch_post_acpi_subsys_init+0x0/0x8
 start_kernel+0x4fc/0x5ec
 __primary_switched+0xb4/0xbc
irq event stamp: 15351
hardirqs last  enabled at (15349): [<ffff80008015d9bc>]
tick_nohz_idle_enter+0xcc/0x198
hardirqs last disabled at (15350): [<ffff8000800e27a8>] do_idle+0xc4/0x290
softirqs last  enabled at (15330): [<ffff800080010614>] __do_softirq+0x494/0x4dc
softirqs last disabled at (15351): [<ffff8000800167c8>]
fpsimd_save_and_flush_cpu_state+0x24/0x58
---[ end trace 0000000000000000 ]---

> pointer to your .config?

renesas-defconfig from
https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git/log/?h=topic/renesas-defconfig

Gr{oetje,eeting}s,

                        Geert
Ard Biesheuvel Dec. 12, 2023, 12:59 p.m. UTC | #4
On Tue, 12 Dec 2023 at 13:34, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Will,
>
> On Tue, Dec 12, 2023 at 1:30 PM Will Deacon <will@kernel.org> wrote:
> > On Tue, Dec 12, 2023 at 12:27:50PM +0100, Geert Uytterhoeven wrote:
> > > On Fri, Dec 8, 2023 at 12:34 PM Ard Biesheuvel <ardb@google.com> wrote:
> > > > From: Ard Biesheuvel <ardb@kernel.org>
> > > > Kernel mode NEON will preserve the user mode FPSIMD state by saving it
> > > > into the task struct before clobbering the registers. In order to avoid
> > > > the need for preserving kernel mode state too, we disallow nested use of
> > > > kernel mode NEON, i..e, use in softirq context while the interrupted
> > > > task context was using kernel mode NEON too.
> > > >
> > > > Originally, this policy was implemented using a per-CPU flag which was
> > > > exposed via may_use_simd(), requiring the users of the kernel mode NEON
> > > > to deal with the possibility that it might return false, and having NEON
> > > > and non-NEON code paths. This policy was changed by commit
> > > > 13150149aa6ded1 ("arm64: fpsimd: run kernel mode NEON with softirqs
> > > > disabled"), and now, softirq processing is disabled entirely instead,
> > > > and so may_use_simd() can never fail when called from task or softirq
> > > > context.
> > > >
> > > > This means we can drop the fpsimd_context_busy flag entirely, and
> > > > instead, ensure that we disable softirq processing in places where we
> > > > formerly relied on the flag for preventing races in the FPSIMD preserve
> > > > routines.
> > > >
> > > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > > > Reviewed-by: Mark Brown <broonie@kernel.org>
> > >
> > > Thanks for your patch, which is now commit e109130b0e5ec3fd
> > > ("arm64: fpsimd: Drop unneeded 'busy' flag") in arm64/for-next/core
> > > and next-20231212.
> > >
> > > I have bisected the following warning during boot (on Salvator-XS with
> > > R-Car H3 ES2.0 and on White-Hawk with R-Car V4H) followed by a lock-up
> > > (on Salvator-XS) to this commit:
> >
> > Please can you provide the output from the warning and, if possible, a
>
> Oops, how did that log disappear?
>
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 0 at kernel/softirq.c:361 __local_bh_enable_ip+0x1a4/0x1c8
> CPU: 0 PID: 0 Comm: swapper/0 Not tainted
> 6.7.0-rc3-arm64-renesas-00001-ge109130b0e5e #2383
> Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
> pstate: 400000c5 (nZcv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : __local_bh_enable_ip+0x1a4/0x1c8
> lr : fpsimd_save_and_flush_cpu_state+0x4c/0x58
> sp : ffff800081703bb0
> x29: ffff800081703bb0 x28: ffff80008171c6b0 x27: ffff8000800167fc
> x26: 0000000000000000 x25: 0000000000000000 x24: ffff800081710a68
> x23: ffff8000813c4008 x22: ffff800081703ca4 x21: 0000000000000000
> x20: ffff8000800167c8 x19: 0000000000000200 x18: ffffffffffffffff
> x17: ffff0004c27f2400 x16: 0000000000000001 x15: 0000000000000003
> x14: 0000000000000000 x13: 0000000000000003 x12: 0000000000000000
> x11: 071c71c71c71c71c x10: ffff800082086b88 x9 : 0000000000000000
> x8 : ffff80008203ab50 x7 : 0000000000000bb0 x6 : ffff80008203b700
> x5 : ffff80067e2ee000 x4 : 0000000000000202 x3 : ffff80067e2ee000
> x2 : ffff80067e2ee000 x1 : ffff800081719fc0 x0 : 0000000100000202
> Call trace:
>  __local_bh_enable_ip+0x1a4/0x1c8
>  fpsimd_save_and_flush_cpu_state+0x4c/0x58
>  fpsimd_cpu_pm_notifier+0x1c/0x28
>  notifier_call_chain+0x9c/0x174
>  raw_notifier_call_chain_robust+0x40/0x98
>  cpu_pm_enter+0x3c/0x70
>  psci_enter_idle_state+0x28/0x78
>  cpuidle_enter_state+0xe4/0x568
>  cpuidle_enter+0x34/0x48
>  do_idle+0x214/0x290

Thanks for the report. I missed the fact that this is called from the
idle path. The old code just set and cleared the 'busy' flag there

Could you please check whether this fixes the issue? Thanks.

--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1835,13 +1835,15 @@ static void fpsimd_flush_cpu_state(void)
  */
 void fpsimd_save_and_flush_cpu_state(void)
 {
+       unsigned long flags;
+
        if (!system_supports_fpsimd())
                return;
        WARN_ON(preemptible());
-       get_cpu_fpsimd_context();
+       local_irq_save(flags);
        fpsimd_save_user_state();
        fpsimd_flush_cpu_state();
-       put_cpu_fpsimd_context();
+       local_irq_restore(flags);
 }

 #ifdef CONFIG_KERNEL_MODE_NEON
Geert Uytterhoeven Dec. 12, 2023, 1:54 p.m. UTC | #5
Hi Ard,

On Tue, Dec 12, 2023 at 1:59 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> On Tue, 12 Dec 2023 at 13:34, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > On Tue, Dec 12, 2023 at 1:30 PM Will Deacon <will@kernel.org> wrote:
> > > On Tue, Dec 12, 2023 at 12:27:50PM +0100, Geert Uytterhoeven wrote:
> > > > On Fri, Dec 8, 2023 at 12:34 PM Ard Biesheuvel <ardb@google.com> wrote:
> > > > > From: Ard Biesheuvel <ardb@kernel.org>
> > > > > Kernel mode NEON will preserve the user mode FPSIMD state by saving it
> > > > > into the task struct before clobbering the registers. In order to avoid
> > > > > the need for preserving kernel mode state too, we disallow nested use of
> > > > > kernel mode NEON, i..e, use in softirq context while the interrupted
> > > > > task context was using kernel mode NEON too.
> > > > >
> > > > > Originally, this policy was implemented using a per-CPU flag which was
> > > > > exposed via may_use_simd(), requiring the users of the kernel mode NEON
> > > > > to deal with the possibility that it might return false, and having NEON
> > > > > and non-NEON code paths. This policy was changed by commit
> > > > > 13150149aa6ded1 ("arm64: fpsimd: run kernel mode NEON with softirqs
> > > > > disabled"), and now, softirq processing is disabled entirely instead,
> > > > > and so may_use_simd() can never fail when called from task or softirq
> > > > > context.
> > > > >
> > > > > This means we can drop the fpsimd_context_busy flag entirely, and
> > > > > instead, ensure that we disable softirq processing in places where we
> > > > > formerly relied on the flag for preventing races in the FPSIMD preserve
> > > > > routines.
> > > > >
> > > > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > > > > Reviewed-by: Mark Brown <broonie@kernel.org>
> > > >
> > > > Thanks for your patch, which is now commit e109130b0e5ec3fd
> > > > ("arm64: fpsimd: Drop unneeded 'busy' flag") in arm64/for-next/core
> > > > and next-20231212.
> > > >
> > > > I have bisected the following warning during boot (on Salvator-XS with
> > > > R-Car H3 ES2.0 and on White-Hawk with R-Car V4H) followed by a lock-up
> > > > (on Salvator-XS) to this commit:
> > >
> > > Please can you provide the output from the warning and, if possible, a
> >
> > Oops, how did that log disappear?
> >
> > ------------[ cut here ]------------
> > WARNING: CPU: 0 PID: 0 at kernel/softirq.c:361 __local_bh_enable_ip+0x1a4/0x1c8
> > CPU: 0 PID: 0 Comm: swapper/0 Not tainted
> > 6.7.0-rc3-arm64-renesas-00001-ge109130b0e5e #2383
> > Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
> > pstate: 400000c5 (nZcv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > pc : __local_bh_enable_ip+0x1a4/0x1c8
> > lr : fpsimd_save_and_flush_cpu_state+0x4c/0x58
> > sp : ffff800081703bb0
> > x29: ffff800081703bb0 x28: ffff80008171c6b0 x27: ffff8000800167fc
> > x26: 0000000000000000 x25: 0000000000000000 x24: ffff800081710a68
> > x23: ffff8000813c4008 x22: ffff800081703ca4 x21: 0000000000000000
> > x20: ffff8000800167c8 x19: 0000000000000200 x18: ffffffffffffffff
> > x17: ffff0004c27f2400 x16: 0000000000000001 x15: 0000000000000003
> > x14: 0000000000000000 x13: 0000000000000003 x12: 0000000000000000
> > x11: 071c71c71c71c71c x10: ffff800082086b88 x9 : 0000000000000000
> > x8 : ffff80008203ab50 x7 : 0000000000000bb0 x6 : ffff80008203b700
> > x5 : ffff80067e2ee000 x4 : 0000000000000202 x3 : ffff80067e2ee000
> > x2 : ffff80067e2ee000 x1 : ffff800081719fc0 x0 : 0000000100000202
> > Call trace:
> >  __local_bh_enable_ip+0x1a4/0x1c8
> >  fpsimd_save_and_flush_cpu_state+0x4c/0x58
> >  fpsimd_cpu_pm_notifier+0x1c/0x28
> >  notifier_call_chain+0x9c/0x174
> >  raw_notifier_call_chain_robust+0x40/0x98
> >  cpu_pm_enter+0x3c/0x70
> >  psci_enter_idle_state+0x28/0x78
> >  cpuidle_enter_state+0xe4/0x568
> >  cpuidle_enter+0x34/0x48
> >  do_idle+0x214/0x290
>
> Thanks for the report. I missed the fact that this is called from the
> idle path. The old code just set and cleared the 'busy' flag there
>
> Could you please check whether this fixes the issue? Thanks.

Thanks, that fixed the issue!

Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert
diff mbox series

Patch

diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h
index 6a75d7ecdcaa..8e86c9e70e48 100644
--- a/arch/arm64/include/asm/simd.h
+++ b/arch/arm64/include/asm/simd.h
@@ -12,8 +12,6 @@ 
 #include <linux/preempt.h>
 #include <linux/types.h>
 
-DECLARE_PER_CPU(bool, fpsimd_context_busy);
-
 #ifdef CONFIG_KERNEL_MODE_NEON
 
 /*
@@ -28,17 +26,10 @@  static __must_check inline bool may_use_simd(void)
 	/*
 	 * We must make sure that the SVE has been initialized properly
 	 * before using the SIMD in kernel.
-	 * fpsimd_context_busy is only set while preemption is disabled,
-	 * and is clear whenever preemption is enabled. Since
-	 * this_cpu_read() is atomic w.r.t. preemption, fpsimd_context_busy
-	 * cannot change under our feet -- if it's set we cannot be
-	 * migrated, and if it's clear we cannot be migrated to a CPU
-	 * where it is set.
 	 */
 	return !WARN_ON(!system_capabilities_finalized()) &&
 	       system_supports_fpsimd() &&
-	       !in_hardirq() && !irqs_disabled() && !in_nmi() &&
-	       !this_cpu_read(fpsimd_context_busy);
+	       !in_hardirq() && !irqs_disabled() && !in_nmi();
 }
 
 #else /* ! CONFIG_KERNEL_MODE_NEON */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 1559c706d32d..ccc4a78a70e4 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -85,13 +85,13 @@ 
  * softirq kicks in. Upon vcpu_put(), KVM will save the vcpu FP state and
  * flag the register state as invalid.
  *
- * In order to allow softirq handlers to use FPSIMD, kernel_neon_begin() may
- * save the task's FPSIMD context back to task_struct from softirq context.
- * To prevent this from racing with the manipulation of the task's FPSIMD state
- * from task context and thereby corrupting the state, it is necessary to
- * protect any manipulation of a task's fpsimd_state or TIF_FOREIGN_FPSTATE
- * flag with {, __}get_cpu_fpsimd_context(). This will still allow softirqs to
- * run but prevent them to use FPSIMD.
+ * In order to allow softirq handlers to use FPSIMD, kernel_neon_begin() may be
+ * called from softirq context, which will save the task's FPSIMD context back
+ * to task_struct. To prevent this from racing with the manipulation of the
+ * task's FPSIMD state from task context and thereby corrupting the state, it
+ * is necessary to protect any manipulation of a task's fpsimd_state or
+ * TIF_FOREIGN_FPSTATE flag with get_cpu_fpsimd_context(), which will suspend
+ * softirq servicing entirely until put_cpu_fpsimd_context() is called.
  *
  * For a certain task, the sequence may look something like this:
  * - the task gets scheduled in; if both the task's fpsimd_cpu field
@@ -209,27 +209,14 @@  static inline void sme_free(struct task_struct *t) { }
 
 #endif
 
-DEFINE_PER_CPU(bool, fpsimd_context_busy);
-EXPORT_PER_CPU_SYMBOL(fpsimd_context_busy);
-
 static void fpsimd_bind_task_to_cpu(void);
 
-static void __get_cpu_fpsimd_context(void)
-{
-	bool busy = __this_cpu_xchg(fpsimd_context_busy, true);
-
-	WARN_ON(busy);
-}
-
 /*
  * Claim ownership of the CPU FPSIMD context for use by the calling context.
  *
  * The caller may freely manipulate the FPSIMD context metadata until
  * put_cpu_fpsimd_context() is called.
  *
- * The double-underscore version must only be called if you know the task
- * can't be preempted.
- *
  * On RT kernels local_bh_disable() is not sufficient because it only
  * serializes soft interrupt related sections via a local lock, but stays
  * preemptible. Disabling preemption is the right choice here as bottom
@@ -242,14 +229,6 @@  static void get_cpu_fpsimd_context(void)
 		local_bh_disable();
 	else
 		preempt_disable();
-	__get_cpu_fpsimd_context();
-}
-
-static void __put_cpu_fpsimd_context(void)
-{
-	bool busy = __this_cpu_xchg(fpsimd_context_busy, false);
-
-	WARN_ON(!busy); /* No matching get_cpu_fpsimd_context()? */
 }
 
 /*
@@ -261,18 +240,12 @@  static void __put_cpu_fpsimd_context(void)
  */
 static void put_cpu_fpsimd_context(void)
 {
-	__put_cpu_fpsimd_context();
 	if (!IS_ENABLED(CONFIG_PREEMPT_RT))
 		local_bh_enable();
 	else
 		preempt_enable();
 }
 
-static bool have_cpu_fpsimd_context(void)
-{
-	return !preemptible() && __this_cpu_read(fpsimd_context_busy);
-}
-
 unsigned int task_get_vl(const struct task_struct *task, enum vec_type type)
 {
 	return task->thread.vl[type];
@@ -383,7 +356,7 @@  static void task_fpsimd_load(void)
 	bool restore_ffr;
 
 	WARN_ON(!system_supports_fpsimd());
-	WARN_ON(!have_cpu_fpsimd_context());
+	WARN_ON(preemptible());
 
 	if (system_supports_sve() || system_supports_sme()) {
 		switch (current->thread.fp_type) {
@@ -467,7 +440,7 @@  static void fpsimd_save(void)
 	unsigned int vl;
 
 	WARN_ON(!system_supports_fpsimd());
-	WARN_ON(!have_cpu_fpsimd_context());
+	WARN_ON(preemptible());
 
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
 		return;
@@ -1507,7 +1480,7 @@  void fpsimd_thread_switch(struct task_struct *next)
 	if (!system_supports_fpsimd())
 		return;
 
-	__get_cpu_fpsimd_context();
+	WARN_ON_ONCE(!irqs_disabled());
 
 	/* Save unsaved fpsimd state, if any: */
 	fpsimd_save();
@@ -1523,8 +1496,6 @@  void fpsimd_thread_switch(struct task_struct *next)
 
 	update_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE,
 			       wrong_task || wrong_cpu);
-
-	__put_cpu_fpsimd_context();
 }
 
 static void fpsimd_flush_thread_vl(enum vec_type type)
@@ -1829,10 +1800,10 @@  void fpsimd_save_and_flush_cpu_state(void)
 	if (!system_supports_fpsimd())
 		return;
 	WARN_ON(preemptible());
-	__get_cpu_fpsimd_context();
+	get_cpu_fpsimd_context();
 	fpsimd_save();
 	fpsimd_flush_cpu_state();
-	__put_cpu_fpsimd_context();
+	put_cpu_fpsimd_context();
 }
 
 #ifdef CONFIG_KERNEL_MODE_NEON