summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1998-02-25 03:56:15 +0000
committerdyson <dyson@FreeBSD.org>1998-02-25 03:56:15 +0000
commit014146c040ed6640e606b46e58c066fc3a1c442c (patch)
tree58ba9b01b799e946135e458cf791510488f813df
parentff694902b34f411a83d04c782b9310e79c3701e9 (diff)
downloadFreeBSD-src-014146c040ed6640e606b46e58c066fc3a1c442c.zip
FreeBSD-src-014146c040ed6640e606b46e58c066fc3a1c442c.tar.gz
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.
-rw-r--r--sys/amd64/amd64/vm_machdep.c64
-rw-r--r--sys/amd64/include/smp.h6
-rw-r--r--sys/i386/i386/vm_machdep.c64
-rw-r--r--sys/i386/include/smp.h6
-rw-r--r--sys/sys/smp.h6
-rw-r--r--sys/vm/swap_pager.c5
-rw-r--r--sys/vm/swap_pager.h3
-rw-r--r--sys/vm/vm_map.c9
-rw-r--r--sys/vm/vm_object.c37
-rw-r--r--sys/vm/vm_object.h24
-rw-r--r--sys/vm/vnode_pager.c11
11 files changed, 127 insertions, 108 deletions
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 17c587b..c28ad33 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -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;
+ splx(s);
+#if 0
+ rel_mplock();
+#endif
+ pmap_zero_page(VM_PAGE_TO_PHYS(m));
+#ifdef 0
+ get_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;
+ (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);
}
/*
diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h
index 4d31598..7867fce 100644
--- a/sys/amd64/include/smp.h
+++ b/sys/amd64/include/smp.h
@@ -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 */
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 17c587b..c28ad33 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -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;
+ splx(s);
+#if 0
+ rel_mplock();
+#endif
+ pmap_zero_page(VM_PAGE_TO_PHYS(m));
+#ifdef 0
+ get_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;
+ (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);
}
/*
diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h
index 4d31598..7867fce 100644
--- a/sys/i386/include/smp.h
+++ b/sys/i386/include/smp.h
@@ -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 */
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index 4d31598..7867fce 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -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 */
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index a4befb0..05d8a327 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -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;
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index 0fa5845..8755547 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -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_ */
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index cb4b22f..930d687 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -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);
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 22b3f7a..ad339d4 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -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 (object->paging_in_progress) {
- object->flags |= OBJ_PIPWNT;
- tsleep(object, PVM, "objde2", 0);
- splx(s);
+ 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;
+ }
+ }
+
+ 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)
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index fe41881..76cb4d2 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -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));
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index e7a9efb..98b57b0 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -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;
OpenPOWER on IntegriCloud