Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/alpha Eliminate race conditions in the FP-switch co...
details: https://anonhg.NetBSD.org/src/rev/b39a57116201
branches: trunk
changeset: 508793:b39a57116201
user: thorpej <thorpej%NetBSD.org@localhost>
date: Fri Apr 20 00:10:17 2001 +0000
description:
Eliminate race conditions in the FP-switch code. MP kernels get
much further on the way to multi-user now.
diffstat:
sys/arch/alpha/alpha/ipifuncs.c | 8 +++-
sys/arch/alpha/alpha/machdep.c | 73 ++++++++++++++++++++++++++++----------
sys/arch/alpha/alpha/trap.c | 23 +++--------
sys/arch/alpha/alpha/vm_machdep.c | 5 +-
sys/arch/alpha/include/cpu.h | 3 +-
sys/arch/alpha/include/pcb.h | 25 ++++++++++++-
6 files changed, 96 insertions(+), 41 deletions(-)
diffs (truncated from 323 to 300 lines):
diff -r dea4b683afaf -r b39a57116201 sys/arch/alpha/alpha/ipifuncs.c
--- a/sys/arch/alpha/alpha/ipifuncs.c Thu Apr 19 23:37:21 2001 +0000
+++ b/sys/arch/alpha/alpha/ipifuncs.c Fri Apr 20 00:10:17 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.24 2001/01/19 18:51:17 thorpej Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.25 2001/04/20 00:10:17 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.24 2001/01/19 18:51:17 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.25 2001/04/20 00:10:17 thorpej Exp $");
/*
* Interprocessor interrupt handlers.
@@ -293,6 +293,8 @@
alpha_ipi_synch_fpu(struct cpu_info *ci, struct trapframe *framep)
{
+ if (ci->ci_flags & CPUF_FPUSAVE)
+ return;
fpusave_cpu(ci, 1);
}
@@ -300,6 +302,8 @@
alpha_ipi_discard_fpu(struct cpu_info *ci, struct trapframe *framep)
{
+ if (ci->ci_flags & CPUF_FPUSAVE)
+ return;
fpusave_cpu(ci, 0);
}
diff -r dea4b683afaf -r b39a57116201 sys/arch/alpha/alpha/machdep.c
--- a/sys/arch/alpha/alpha/machdep.c Thu Apr 19 23:37:21 2001 +0000
+++ b/sys/arch/alpha/alpha/machdep.c Fri Apr 20 00:10:17 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.234 2001/04/19 17:48:46 thorpej Exp $ */
+/* $NetBSD: machdep.c,v 1.235 2001/04/20 00:10:17 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.234 2001/04/19 17:48:46 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.235 2001/04/20 00:10:17 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -663,6 +663,7 @@
(u_int64_t)proc0paddr + USPACE - sizeof(struct trapframe);
proc0.p_md.md_tf =
(struct trapframe *)proc0paddr->u_pcb.pcb_hw.apcb_ksp;
+ simple_lock_init(&proc0paddr->u_pcb.pcb_fpcpu_slock);
/*
* Initialize the primary CPU's idle PCB to proc0's. In a
@@ -1794,9 +1795,13 @@
KDASSERT(ci == curcpu());
+#if defined(MULTIPROCESSOR)
+ atomic_setbits_ulong(&ci->ci_flags, CPUF_FPUSAVE);
+#endif
+
p = ci->ci_fpcurproc;
if (p == NULL)
- return;
+ goto out;
if (save) {
alpha_pal_wrfen(1);
@@ -1805,15 +1810,18 @@
alpha_pal_wrfen(0);
-#if defined(MULTIPROCESSOR)
- s = splhigh();
-#endif
+ FPCPU_LOCK(&p->p_addr->u_pcb, s);
+
p->p_addr->u_pcb.pcb_fpcpu = NULL;
ci->ci_fpcurproc = NULL;
+
+ FPCPU_UNLOCK(&p->p_addr->u_pcb, s);
+
+ out:
#if defined(MULTIPROCESSOR)
- splx(s);
- alpha_mb();
+ atomic_clearbits_ulong(&ci->ci_flags, CPUF_FPUSAVE);
#endif
+ return;
}
/*
@@ -1824,32 +1832,59 @@
{
struct cpu_info *ci = curcpu();
struct cpu_info *oci;
+#if defined(MULTIPROCESSOR)
+ u_long ipi = save ? ALPHA_IPI_SYNCH_FPU : ALPHA_IPI_DISCARD_FPU;
+ int s, spincount, hold_count;
+#endif
KDASSERT(p->p_addr != NULL);
KDASSERT(p->p_flag & P_INMEM);
+ FPCPU_LOCK(&p->p_addr->u_pcb, s);
+
oci = p->p_addr->u_pcb.pcb_fpcpu;
- if (oci == NULL)
+ if (oci == NULL) {
+ FPCPU_UNLOCK(&p->p_addr->u_pcb, s);
return;
+ }
#if defined(MULTIPROCESSOR)
if (oci == ci) {
- int s;
KASSERT(ci->ci_fpcurproc == p);
- s = splhigh();
+ FPCPU_UNLOCK(&p->p_addr->u_pcb, s);
fpusave_cpu(ci, save);
- splx(s);
- } else {
- u_long ipi = save ? ALPHA_IPI_SYNCH_FPU :
- ALPHA_IPI_DISCARD_FPU;
+ return;
+ }
+
+ KASSERT(oci->ci_fpcurproc == p);
+ alpha_send_ipi(oci->ci_cpuid, ipi);
+ FPCPU_UNLOCK(&p->p_addr->u_pcb, s);
- KASSERT(oci->ci_fpcurproc == p);
- do {
- alpha_send_ipi(oci->ci_cpuid, ipi);
- } while (p->p_addr->u_pcb.pcb_fpcpu != NULL);
+ /*
+ * If we're holding the kernel lock, release it before
+ * spinning.
+ *
+ * XXX Why do we have to do this?! We shouldn't need to!
+ */
+ if (p->p_flag & P_BIGLOCK)
+ hold_count = spinlock_release_all(&kernel_lock);
+
+ spincount = 0;
+ while (p->p_addr->u_pcb.pcb_fpcpu != NULL) {
+ spincount++;
+ delay(1000); /* XXX */
+ if (spincount > 10000)
+ panic("fpsave ipi didn't");
}
+
+ /*
+ * ...and reacquire it.
+ */
+ if (p->p_flag & P_BIGLOCK)
+ spinlock_acquire_count(&kernel_lock, hold_count);
#else
KASSERT(ci->ci_fpcurproc == p);
+ FPCPU_UNLOCK(&p->p_addr->u_pcb, s);
fpusave_cpu(ci, save);
#endif /* MULTIPROCESSOR */
}
diff -r dea4b683afaf -r b39a57116201 sys/arch/alpha/alpha/trap.c
--- a/sys/arch/alpha/alpha/trap.c Thu Apr 19 23:37:21 2001 +0000
+++ b/sys/arch/alpha/alpha/trap.c Fri Apr 20 00:10:17 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.67 2001/03/15 06:10:33 chs Exp $ */
+/* $NetBSD: trap.c,v 1.68 2001/04/20 00:10:18 thorpej Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -100,7 +100,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.67 2001/03/15 06:10:33 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.68 2001/04/20 00:10:18 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -335,10 +335,6 @@
int s;
#endif
-#if defined(MULTIPROCESSOR)
- /* Block IPIs while we clean house. */
- s = splhigh();
-#endif
/*
* on exit from the kernel, if proc == fpcurproc,
* FP is enabled.
@@ -351,9 +347,7 @@
if (ci->ci_fpcurproc != NULL)
fpusave_cpu(ci, 1);
-#if defined(MULTIPROCESSOR)
- splx(s);
-#endif
+
KDASSERT(ci->ci_fpcurproc == NULL);
#if defined(MULTIPROCESSOR)
@@ -363,15 +357,12 @@
KDASSERT(p->p_addr->u_pcb.pcb_fpcpu == NULL);
#endif
-#if defined(MULTIPROCESSOR)
- s = splhigh();
-#endif
+ FPCPU_LOCK(&p->p_addr->u_pcb, s);
+
p->p_addr->u_pcb.pcb_fpcpu = ci;
ci->ci_fpcurproc = p;
-#if defined(MULTIPROCESSOR)
- splx(s);
- alpha_mb();
-#endif
+
+ FPCPU_UNLOCK(&p->p_addr->u_pcb, s);
alpha_pal_wrfen(1);
restorefpstate(&p->p_addr->u_pcb.pcb_fp);
diff -r dea4b683afaf -r b39a57116201 sys/arch/alpha/alpha/vm_machdep.c
--- a/sys/arch/alpha/alpha/vm_machdep.c Thu Apr 19 23:37:21 2001 +0000
+++ b/sys/arch/alpha/alpha/vm_machdep.c Fri Apr 20 00:10:17 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.65 2001/04/10 00:27:00 sommerfeld Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.66 2001/04/20 00:10:18 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.65 2001/04/10 00:27:00 sommerfeld Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.66 2001/04/20 00:10:18 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -163,6 +163,7 @@
*/
p2->p_addr->u_pcb = p1->p_addr->u_pcb;
p2->p_addr->u_pcb.pcb_hw.apcb_usp = alpha_pal_rdusp();
+ simple_lock_init(&p2->p_addr->u_pcb.pcb_fpcpu_slock);
/*
* Arrange for a non-local goto when the new process
diff -r dea4b683afaf -r b39a57116201 sys/arch/alpha/include/cpu.h
--- a/sys/arch/alpha/include/cpu.h Thu Apr 19 23:37:21 2001 +0000
+++ b/sys/arch/alpha/include/cpu.h Fri Apr 20 00:10:17 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.52 2001/02/27 22:00:19 mjacob Exp $ */
+/* $NetBSD: cpu.h,v 1.53 2001/04/20 00:10:18 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -139,6 +139,7 @@
#define CPUF_PRESENT 0x02 /* CPU is present */
#define CPUF_RUNNING 0x04 /* CPU is running */
#define CPUF_PAUSED 0x08 /* CPU is paused */
+#define CPUF_FPUSAVE 0x10 /* CPU is currently in fpusave_cpu() */
#if defined(MULTIPROCESSOR)
extern __volatile u_long cpus_running;
diff -r dea4b683afaf -r b39a57116201 sys/arch/alpha/include/pcb.h
--- a/sys/arch/alpha/include/pcb.h Thu Apr 19 23:37:21 2001 +0000
+++ b/sys/arch/alpha/include/pcb.h Fri Apr 20 00:10:17 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcb.h,v 1.7 2000/08/15 22:16:19 thorpej Exp $ */
+/* $NetBSD: pcb.h,v 1.8 2001/04/20 00:10:18 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -27,6 +27,8 @@
* rights to redistribute these changes.
*/
+#include <sys/lock.h>
+
#include <machine/frame.h>
#include <machine/reg.h>
@@ -52,8 +54,29 @@
unsigned long pcb_onfault; /* for copy faults [SW] */
unsigned long pcb_accessaddr; /* for [fs]uswintr [SW] */
struct cpu_info * __volatile pcb_fpcpu; /* CPU with our FP state[SW] */
+ struct simplelock pcb_fpcpu_slock; /* simple lock on fpcpu [SW] */
};
Home |
Main Index |
Thread Index |
Old Index