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:
dyson 1998-02-25 03:56:15 +00:00
parent ff694902b3
commit 014146c040
11 changed files with 126 additions and 107 deletions

View File

@ -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);
}
/*

View File

@ -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 */

View File

@ -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);
}
/*

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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_ */

View File

@ -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);

View File

@ -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)

View File

@ -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));

View File

@ -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;