diff options
author | Thomas Nordin <nordin@cvs.openbsd.org> | 2003-11-08 06:11:12 +0000 |
---|---|---|
committer | Thomas Nordin <nordin@cvs.openbsd.org> | 2003-11-08 06:11:12 +0000 |
commit | 883cc1a3f7a35ae6e376bcc22dafbdc49b59f3e9 (patch) | |
tree | e3deb100f216367200009dc56fcc73e2a5a926b6 /sys | |
parent | 9d836f49cb5c11632d725128e9d14a4fcf89e50d (diff) |
Avoid a race condition while swapping in a process.
Tested by mickey@, henning@, ericj@, and beck@.
ok mickey@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/alpha/alpha/machdep.c | 3 | ||||
-rw-r--r-- | sys/sys/proc.h | 3 | ||||
-rw-r--r-- | sys/uvm/uvm_glue.c | 31 |
3 files changed, 25 insertions, 12 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 5d5688589db..1c4f30c35c9 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.83 2003/08/10 00:03:21 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.84 2003/11/08 06:11:11 nordin Exp $ */ /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- @@ -1891,7 +1891,6 @@ fpusave_proc(struct proc *p, int save) #endif KDASSERT(p->p_addr != NULL); - KDASSERT(p->p_flag & P_INMEM); oci = p->p_addr->u_pcb.pcb_fpcpu; if (oci == NULL) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index c7a01a41188..5f3e766c566 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.67 2003/08/21 18:56:07 tedu Exp $ */ +/* $OpenBSD: proc.h,v 1.68 2003/11/08 06:11:11 nordin Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -263,6 +263,7 @@ struct proc { #define P_INEXEC 0x200000 /* Process is doing an exec right now */ #define P_SYSTRACE 0x400000 /* Process system call tracing active*/ #define P_CONTINUED 0x800000 /* Proc has continued from a stopped state. */ +#define P_SWAPIN 0x1000000 /* Swapping in right now */ #define P_BITS \ ("\20\01ADVLOCK\02CTTY\03INMEM\04NOCLDSTOP\05PPWAIT\06PROFIL\07SELECT" \ diff --git a/sys/uvm/uvm_glue.c b/sys/uvm/uvm_glue.c index f0136230b12..883f8e602ec 100644 --- a/sys/uvm/uvm_glue.c +++ b/sys/uvm/uvm_glue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_glue.c,v 1.35 2003/08/10 00:04:50 miod Exp $ */ +/* $OpenBSD: uvm_glue.c,v 1.36 2003/11/08 06:11:10 nordin Exp $ */ /* $NetBSD: uvm_glue.c,v 1.44 2001/02/06 19:54:44 eeh Exp $ */ /* @@ -352,6 +352,14 @@ uvm_swapin(p) vaddr_t addr; int rv, s; + s = splstatclock(); + if (p->p_flag & P_SWAPIN) { + splx(s); + return; + } + p->p_flag |= P_SWAPIN; + splx(s); + addr = (vaddr_t)p->p_addr; /* make P_INMEM true */ if ((rv = uvm_fault_wire(kernel_map, addr, addr + USPACE, @@ -367,6 +375,7 @@ uvm_swapin(p) if (p->p_stat == SRUN) setrunqueue(p); p->p_flag |= P_INMEM; + p->p_flag &= ~P_SWAPIN; splx(s); p->p_swtime = 0; ++uvmexp.swapins; @@ -552,20 +561,18 @@ uvm_swapout(p) #ifdef DEBUG if (swapdebug & SDB_SWAPOUT) printf("swapout: pid %d(%s)@%p, stat %x pri %d free %d\n", - p->p_pid, p->p_comm, p->p_addr, p->p_stat, - p->p_slptime, uvmexp.free); + p->p_pid, p->p_comm, p->p_addr, p->p_stat, + p->p_slptime, uvmexp.free); #endif /* - * Do any machine-specific actions necessary before swapout. - * This can include saving floating point state, etc. - */ - cpu_swapout(p); - - /* * Mark it as (potentially) swapped out. */ s = splstatclock(); + if (!(p->p_flag & P_INMEM)) { + splx(s); + return; + } p->p_flag &= ~P_INMEM; if (p->p_stat == SRUN) remrunqueue(p); @@ -574,6 +581,12 @@ uvm_swapout(p) ++uvmexp.swapouts; /* + * Do any machine-specific actions necessary before swapout. + * This can include saving floating point state, etc. + */ + cpu_swapout(p); + + /* * Unwire the to-be-swapped process's user struct and kernel stack. */ addr = (vaddr_t)p->p_addr; |