Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86/x86 Save fpu state at IPL_VM to exclude fpu_ker...
details: https://anonhg.NetBSD.org/src/rev/483dfcc16026
branches: trunk
changeset: 936180:483dfcc16026
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Jul 20 16:41:18 2020 +0000
description:
Save fpu state at IPL_VM to exclude fpu_kern_enter/leave.
This way fpu_kern_enter/leave cannot interrupt the transition, so the
transition from state-on-CPU to state-in-memory (with TS set) is
atomic whether in an interrupt or not.
(I am not 100% convinced that this is necessary, but it makes
reasoning about the transition simpler.)
diffstat:
sys/arch/x86/x86/fpu.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
diffs (65 lines):
diff -r c9da59bb1f71 -r 483dfcc16026 sys/arch/x86/x86/fpu.c
--- a/sys/arch/x86/x86/fpu.c Mon Jul 20 16:38:47 2020 +0000
+++ b/sys/arch/x86/x86/fpu.c Mon Jul 20 16:41:18 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.70 2020/07/20 16:38:47 riastradh Exp $ */
+/* $NetBSD: fpu.c,v 1.71 2020/07/20 16:41:18 riastradh Exp $ */
/*
* Copyright (c) 2008, 2019 The NetBSD Foundation, Inc. All
@@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.70 2020/07/20 16:38:47 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.71 2020/07/20 16:41:18 riastradh Exp $");
#include "opt_multiprocessor.h"
@@ -151,14 +151,15 @@
{
struct pcb *pcb = lwp_getpcb(l);
union savefpu *area = &pcb->pcb_savefpu;
+ int s;
- kpreempt_disable();
+ s = splvm();
if (l->l_md.md_flags & MDL_FPU_IN_CPU) {
KASSERT((l->l_flag & LW_SYSTEM) == 0);
fpu_area_save(area, x86_xsave_features);
l->l_md.md_flags &= ~MDL_FPU_IN_CPU;
}
- kpreempt_enable();
+ splx(s);
}
/*
@@ -299,8 +300,12 @@
void
fpu_switch(struct lwp *oldlwp, struct lwp *newlwp)
{
+ struct cpu_info *ci __diagused = curcpu();
struct pcb *pcb;
+ KASSERTMSG(ci->ci_ilevel >= IPL_SCHED, "cpu%d ilevel=%d",
+ cpu_index(ci), ci->ci_ilevel);
+
if (oldlwp->l_md.md_flags & MDL_FPU_IN_CPU) {
KASSERT(!(oldlwp->l_flag & LW_SYSTEM));
pcb = lwp_getpcb(oldlwp);
@@ -334,11 +339,13 @@
void
fpu_lwp_abandon(struct lwp *l)
{
+ int s;
+
KASSERT(l == curlwp);
- kpreempt_disable();
+ s = splvm();
l->l_md.md_flags &= ~MDL_FPU_IN_CPU;
stts();
- kpreempt_enable();
+ splx(s);
}
/* -------------------------------------------------------------------------- */
Home |
Main Index |
Thread Index |
Old Index