Fix page prezeroing for SMP, and fix some potential paging-in-progress
hangs. The paging-in-progress diagnosis was a result of Tor Egge's excellent detective work. Submitted by: Partially from Tor Egge.
This commit is contained in:
parent
ff694902b3
commit
014146c040
@ -38,7 +38,7 @@
|
||||
*
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $Id: vm_machdep.c,v 1.99 1998/02/06 12:13:11 eivind Exp $
|
||||
* $Id: vm_machdep.c,v 1.100 1998/02/13 05:30:18 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -53,6 +53,8 @@
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
@ -913,6 +915,11 @@ grow(p, sp)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int cnt_prezero;
|
||||
|
||||
SYSCTL_INT(_machdep, OID_AUTO, cnt_prezero, CTLFLAG_RD, &cnt_prezero, 0, "");
|
||||
|
||||
/*
|
||||
* Implement the pre-zeroed page mechanism.
|
||||
* This routine is called from the idle loop.
|
||||
@ -924,10 +931,6 @@ vm_page_zero_idle()
|
||||
vm_page_t m;
|
||||
int s;
|
||||
|
||||
#ifdef WRONG
|
||||
if (cnt.v_free_count <= cnt.v_interrupt_free_min)
|
||||
return (0);
|
||||
#endif
|
||||
/*
|
||||
* XXX
|
||||
* We stop zeroing pages when there are sufficent prezeroed pages.
|
||||
@ -944,36 +947,39 @@ vm_page_zero_idle()
|
||||
if (cnt.v_free_count - vm_page_zero_count <= cnt.v_free_reserved / 2)
|
||||
return (0);
|
||||
#ifdef SMP
|
||||
get_mplock();
|
||||
if (try_mplock()) {
|
||||
#endif
|
||||
s = splvm();
|
||||
enable_intr();
|
||||
m = vm_page_list_find(PQ_FREE, free_rover);
|
||||
if (m != NULL) {
|
||||
--(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
|
||||
m->queue = PQ_NONE;
|
||||
s = splvm();
|
||||
enable_intr();
|
||||
m = vm_page_list_find(PQ_FREE, free_rover);
|
||||
if (m != NULL) {
|
||||
--(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
|
||||
m->queue = PQ_NONE;
|
||||
splx(s);
|
||||
#if 0
|
||||
rel_mplock();
|
||||
#endif
|
||||
pmap_zero_page(VM_PAGE_TO_PHYS(m));
|
||||
#ifdef 0
|
||||
get_mplock();
|
||||
#endif
|
||||
(void)splvm();
|
||||
m->queue = PQ_ZERO + m->pc;
|
||||
++(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_INSERT_HEAD(vm_page_queues[m->queue].pl, m, pageq);
|
||||
free_rover = (free_rover + PQ_PRIME3) & PQ_L2_MASK;
|
||||
++vm_page_zero_count;
|
||||
++cnt_prezero;
|
||||
}
|
||||
splx(s);
|
||||
disable_intr();
|
||||
#ifdef SMP
|
||||
rel_mplock();
|
||||
#endif
|
||||
pmap_zero_page(VM_PAGE_TO_PHYS(m));
|
||||
#ifdef SMP
|
||||
get_mplock();
|
||||
#endif
|
||||
(void)splvm();
|
||||
m->queue = PQ_ZERO + m->pc;
|
||||
++(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_INSERT_HEAD(vm_page_queues[m->queue].pl, m, pageq);
|
||||
free_rover = (free_rover + PQ_PRIME3) & PQ_L2_MASK;
|
||||
++vm_page_zero_count;
|
||||
return (1);
|
||||
}
|
||||
splx(s);
|
||||
disable_intr();
|
||||
#ifdef SMP
|
||||
rel_mplock();
|
||||
#endif
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.33 1997/12/08 22:56:44 fsmp Exp $
|
||||
* $Id: smp.h,v 1.34 1998/01/01 08:47:12 bde Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -67,11 +67,11 @@ extern u_int mpintr_lock;
|
||||
/* functions in mplock.s */
|
||||
void get_mplock __P((void));
|
||||
void rel_mplock __P((void));
|
||||
void try_mplock __P((void));
|
||||
int try_mplock __P((void));
|
||||
#ifdef RECURSIVE_MPINTRLOCK
|
||||
void get_mpintrlock __P((void));
|
||||
void rel_mpintrlock __P((void));
|
||||
void try_mpintrlock __P((void));
|
||||
int try_mpintrlock __P((void));
|
||||
#endif /* RECURSIVE_MPINTRLOCK */
|
||||
|
||||
/* global data in apic_vector.s */
|
||||
|
@ -38,7 +38,7 @@
|
||||
*
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $Id: vm_machdep.c,v 1.99 1998/02/06 12:13:11 eivind Exp $
|
||||
* $Id: vm_machdep.c,v 1.100 1998/02/13 05:30:18 bde Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -53,6 +53,8 @@
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
@ -913,6 +915,11 @@ grow(p, sp)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int cnt_prezero;
|
||||
|
||||
SYSCTL_INT(_machdep, OID_AUTO, cnt_prezero, CTLFLAG_RD, &cnt_prezero, 0, "");
|
||||
|
||||
/*
|
||||
* Implement the pre-zeroed page mechanism.
|
||||
* This routine is called from the idle loop.
|
||||
@ -924,10 +931,6 @@ vm_page_zero_idle()
|
||||
vm_page_t m;
|
||||
int s;
|
||||
|
||||
#ifdef WRONG
|
||||
if (cnt.v_free_count <= cnt.v_interrupt_free_min)
|
||||
return (0);
|
||||
#endif
|
||||
/*
|
||||
* XXX
|
||||
* We stop zeroing pages when there are sufficent prezeroed pages.
|
||||
@ -944,36 +947,39 @@ vm_page_zero_idle()
|
||||
if (cnt.v_free_count - vm_page_zero_count <= cnt.v_free_reserved / 2)
|
||||
return (0);
|
||||
#ifdef SMP
|
||||
get_mplock();
|
||||
if (try_mplock()) {
|
||||
#endif
|
||||
s = splvm();
|
||||
enable_intr();
|
||||
m = vm_page_list_find(PQ_FREE, free_rover);
|
||||
if (m != NULL) {
|
||||
--(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
|
||||
m->queue = PQ_NONE;
|
||||
s = splvm();
|
||||
enable_intr();
|
||||
m = vm_page_list_find(PQ_FREE, free_rover);
|
||||
if (m != NULL) {
|
||||
--(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
|
||||
m->queue = PQ_NONE;
|
||||
splx(s);
|
||||
#if 0
|
||||
rel_mplock();
|
||||
#endif
|
||||
pmap_zero_page(VM_PAGE_TO_PHYS(m));
|
||||
#ifdef 0
|
||||
get_mplock();
|
||||
#endif
|
||||
(void)splvm();
|
||||
m->queue = PQ_ZERO + m->pc;
|
||||
++(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_INSERT_HEAD(vm_page_queues[m->queue].pl, m, pageq);
|
||||
free_rover = (free_rover + PQ_PRIME3) & PQ_L2_MASK;
|
||||
++vm_page_zero_count;
|
||||
++cnt_prezero;
|
||||
}
|
||||
splx(s);
|
||||
disable_intr();
|
||||
#ifdef SMP
|
||||
rel_mplock();
|
||||
#endif
|
||||
pmap_zero_page(VM_PAGE_TO_PHYS(m));
|
||||
#ifdef SMP
|
||||
get_mplock();
|
||||
#endif
|
||||
(void)splvm();
|
||||
m->queue = PQ_ZERO + m->pc;
|
||||
++(*vm_page_queues[m->queue].lcnt);
|
||||
TAILQ_INSERT_HEAD(vm_page_queues[m->queue].pl, m, pageq);
|
||||
free_rover = (free_rover + PQ_PRIME3) & PQ_L2_MASK;
|
||||
++vm_page_zero_count;
|
||||
return (1);
|
||||
}
|
||||
splx(s);
|
||||
disable_intr();
|
||||
#ifdef SMP
|
||||
rel_mplock();
|
||||
#endif
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.33 1997/12/08 22:56:44 fsmp Exp $
|
||||
* $Id: smp.h,v 1.34 1998/01/01 08:47:12 bde Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -67,11 +67,11 @@ extern u_int mpintr_lock;
|
||||
/* functions in mplock.s */
|
||||
void get_mplock __P((void));
|
||||
void rel_mplock __P((void));
|
||||
void try_mplock __P((void));
|
||||
int try_mplock __P((void));
|
||||
#ifdef RECURSIVE_MPINTRLOCK
|
||||
void get_mpintrlock __P((void));
|
||||
void rel_mpintrlock __P((void));
|
||||
void try_mpintrlock __P((void));
|
||||
int try_mpintrlock __P((void));
|
||||
#endif /* RECURSIVE_MPINTRLOCK */
|
||||
|
||||
/* global data in apic_vector.s */
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.33 1997/12/08 22:56:44 fsmp Exp $
|
||||
* $Id: smp.h,v 1.34 1998/01/01 08:47:12 bde Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -67,11 +67,11 @@ extern u_int mpintr_lock;
|
||||
/* functions in mplock.s */
|
||||
void get_mplock __P((void));
|
||||
void rel_mplock __P((void));
|
||||
void try_mplock __P((void));
|
||||
int try_mplock __P((void));
|
||||
#ifdef RECURSIVE_MPINTRLOCK
|
||||
void get_mpintrlock __P((void));
|
||||
void rel_mpintrlock __P((void));
|
||||
void try_mpintrlock __P((void));
|
||||
int try_mpintrlock __P((void));
|
||||
#endif /* RECURSIVE_MPINTRLOCK */
|
||||
|
||||
/* global data in apic_vector.s */
|
||||
|
@ -39,7 +39,7 @@
|
||||
* from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
|
||||
*
|
||||
* @(#)swap_pager.c 8.9 (Berkeley) 3/21/94
|
||||
* $Id: swap_pager.c,v 1.88 1998/02/09 06:11:20 eivind Exp $
|
||||
* $Id: swap_pager.c,v 1.89 1998/02/23 08:22:24 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -144,7 +144,6 @@ static boolean_t
|
||||
int *before, int *after));
|
||||
static int swap_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
|
||||
static void swap_pager_init __P((void));
|
||||
static void swap_pager_sync __P((void));
|
||||
static void spc_free __P((swp_clean_t));
|
||||
|
||||
struct pagerops swappagerops = {
|
||||
@ -1550,7 +1549,7 @@ swap_pager_putpages(object, m, count, sync, rtvals)
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
swap_pager_sync()
|
||||
{
|
||||
swp_clean_t spc;
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)swap_pager.h 7.1 (Berkeley) 12/5/90
|
||||
* $Id: swap_pager.h,v 1.18 1997/02/22 09:48:08 peter Exp $
|
||||
* $Id: swap_pager.h,v 1.19 1998/02/23 08:22:27 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -78,6 +78,7 @@ void swap_pager_copy __P((vm_object_t, vm_pindex_t, vm_object_t,
|
||||
void swap_pager_freespace __P((vm_object_t, vm_pindex_t, vm_size_t));
|
||||
void swap_pager_dmzspace __P((vm_object_t, vm_pindex_t, vm_size_t));
|
||||
void swap_pager_swap_init __P((void));
|
||||
void swap_pager_sync __P((void));
|
||||
#endif
|
||||
|
||||
#endif /* _SWAP_PAGER_ */
|
||||
|
@ -61,7 +61,7 @@
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*
|
||||
* $Id: vm_map.c,v 1.115 1998/02/20 13:11:54 bde Exp $
|
||||
* $Id: vm_map.c,v 1.116 1998/02/23 08:22:33 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -2632,12 +2632,7 @@ vm_freeze_copyopts(object, froma, toa)
|
||||
|
||||
vm_object_reference(robject);
|
||||
|
||||
s = splvm();
|
||||
while (robject->paging_in_progress) {
|
||||
robject->flags |= OBJ_PIPWNT;
|
||||
tsleep(robject, PVM, "objfrz", 0);
|
||||
}
|
||||
splx(s);
|
||||
vm_object_pip_wait(robject, "objfrz");
|
||||
|
||||
if (robject->ref_count == 1) {
|
||||
vm_object_deallocate(robject);
|
||||
|
@ -61,7 +61,7 @@
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*
|
||||
* $Id: vm_object.c,v 1.112 1998/02/06 12:14:26 eivind Exp $
|
||||
* $Id: vm_object.c,v 1.113 1998/02/09 06:11:30 eivind Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -334,21 +334,23 @@ vm_object_deallocate(object)
|
||||
robject->ref_count++;
|
||||
|
||||
retry:
|
||||
s = splvm();
|
||||
if (robject->paging_in_progress) {
|
||||
robject->flags |= OBJ_PIPWNT;
|
||||
tsleep(robject, PVM, "objde1", 0);
|
||||
splx(s);
|
||||
goto retry;
|
||||
}
|
||||
if (robject->paging_in_progress || object->paging_in_progress) {
|
||||
vm_object_pip_sleep(robject, "objde1");
|
||||
if (robject->paging_in_progress) {
|
||||
if (robject->type == OBJT_SWAP) {
|
||||
swap_pager_sync();
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
if (object->paging_in_progress) {
|
||||
object->flags |= OBJ_PIPWNT;
|
||||
tsleep(object, PVM, "objde2", 0);
|
||||
splx(s);
|
||||
vm_object_pip_sleep(object, "objde2");
|
||||
if (object->paging_in_progress) {
|
||||
if (object->type == OBJT_SWAP) {
|
||||
swap_pager_sync();
|
||||
}
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
splx(s);
|
||||
|
||||
if( robject->ref_count == 1) {
|
||||
robject->ref_count--;
|
||||
@ -408,12 +410,7 @@ vm_object_terminate(object)
|
||||
/*
|
||||
* wait for the pageout daemon to be done with the object
|
||||
*/
|
||||
s = splvm();
|
||||
while (object->paging_in_progress) {
|
||||
object->flags |= OBJ_PIPWNT;
|
||||
tsleep(object, PVM, "objtrm", 0);
|
||||
}
|
||||
splx(s);
|
||||
vm_object_pip_wait(object, "objtrm");
|
||||
|
||||
#if defined(DIAGNOSTIC)
|
||||
if (object->paging_in_progress != 0)
|
||||
|
@ -61,7 +61,7 @@
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*
|
||||
* $Id: vm_object.h,v 1.44 1998/01/31 11:56:43 dyson Exp $
|
||||
* $Id: vm_object.h,v 1.45 1998/02/05 03:32:45 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -164,6 +164,28 @@ vm_object_pip_wakeup(vm_object_t object)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void
|
||||
vm_object_pip_sleep(vm_object_t object, char *waitid)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (object->paging_in_progress) {
|
||||
s = splvm();
|
||||
if (object->paging_in_progress) {
|
||||
object->flags |= OBJ_PIPWNT;
|
||||
tsleep(object, PVM, waitid, 0);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void
|
||||
vm_object_pip_wait(vm_object_t object, char *waitid)
|
||||
{
|
||||
while (object->paging_in_progress)
|
||||
vm_object_pip_sleep(object, waitid);
|
||||
}
|
||||
|
||||
vm_object_t vm_object_allocate __P((objtype_t, vm_size_t));
|
||||
void _vm_object_allocate __P((objtype_t, vm_size_t, vm_object_t));
|
||||
boolean_t vm_object_coalesce __P((vm_object_t, vm_pindex_t, vm_size_t, vm_size_t));
|
||||
|
@ -38,7 +38,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
|
||||
* $Id: vnode_pager.c,v 1.84 1998/02/06 12:14:30 eivind Exp $
|
||||
* $Id: vnode_pager.c,v 1.85 1998/02/23 08:22:48 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -169,14 +169,7 @@ vnode_pager_dealloc(object)
|
||||
if (vp == NULL)
|
||||
panic("vnode_pager_dealloc: pager already dealloced");
|
||||
|
||||
if (object->paging_in_progress) {
|
||||
int s = splvm();
|
||||
while (object->paging_in_progress) {
|
||||
object->flags |= OBJ_PIPWNT;
|
||||
tsleep(object, PVM, "vnpdea", 0);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
vm_object_pip_wait(object, "vnpdea");
|
||||
|
||||
object->handle = NULL;
|
||||
object->type = OBJT_DEAD;
|
||||
|
Loading…
Reference in New Issue
Block a user