From 6390d0aecac09912beb617f9e153d72b86e0cb63 Mon Sep 17 00:00:00 2001 From: chs Date: Sun, 30 Jan 2005 17:23:05 +0000 Subject: [PATCH] hack around a UVM problem that causes hangs when large processes fork. see PR 26908 for details. --- sys/uvm/uvm_amap.c | 15 +++++++++++++-- sys/uvm/uvm_pdaemon.c | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c index f43567a22b37..68bd6b4c2bb4 100644 --- a/sys/uvm/uvm_amap.c +++ b/sys/uvm/uvm_amap.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_amap.c,v 1.56 2005/01/01 21:00:06 yamt Exp $ */ +/* $NetBSD: uvm_amap.c,v 1.57 2005/01/30 17:23:05 chs Exp $ */ /* * @@ -42,7 +42,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.56 2005/01/01 21:00:06 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.57 2005/01/30 17:23:05 chs Exp $"); #undef UVM_AMAP_INLINE /* enable/disable amap inlines */ @@ -204,6 +204,17 @@ fail2: free(amap->am_slots, M_UVMAMAP); fail1: pool_put(&uvm_amap_pool, amap); + + /* + * XXX hack to tell the pagedaemon how many pages we need, + * since we can need more than it would normally free. + */ + if (waitf == M_NOWAIT) { + extern int uvm_extrapages; + uvm_extrapages += ((sizeof(int) * 2 + + sizeof(struct vm_anon *)) * + totalslots) >> PAGE_SHIFT; + } return (NULL); } diff --git a/sys/uvm/uvm_pdaemon.c b/sys/uvm/uvm_pdaemon.c index f58b2f2e23dd..e5a6bbd7d08d 100644 --- a/sys/uvm/uvm_pdaemon.c +++ b/sys/uvm/uvm_pdaemon.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_pdaemon.c,v 1.60 2004/10/03 08:47:48 enami Exp $ */ +/* $NetBSD: uvm_pdaemon.c,v 1.61 2005/01/30 17:23:05 chs Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.60 2004/10/03 08:47:48 enami Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.61 2005/01/30 17:23:05 chs Exp $"); #include "opt_uvmhist.h" @@ -103,6 +103,11 @@ void uvmpd_scan(void); void uvmpd_scan_inactive(struct pglist *); void uvmpd_tune(void); +/* + * XXX hack to avoid hangs when large processes fork. + */ +int uvm_extrapages; + /* * uvm_wait: wait (sleep) for the page daemon to free some pages * @@ -183,6 +188,9 @@ uvmpd_tune(void) if (uvmexp.freetarg <= uvmexp.freemin) uvmexp.freetarg = uvmexp.freemin + 1; + uvmexp.freetarg += uvm_extrapages; + uvm_extrapages = 0; + /* uvmexp.inactarg: computed in main daemon loop */ uvmexp.wiredmax = uvmexp.npages / 3; @@ -198,6 +206,7 @@ void uvm_pageout(void *arg) { int bufcnt, npages = 0; + int extrapages = 0; UVMHIST_FUNC("uvm_pageout"); UVMHIST_CALLED(pdhist); UVMHIST_LOG(pdhist,"", 0, 0, 0, 0); @@ -230,8 +239,9 @@ uvm_pageout(void *arg) */ uvm_lock_pageq(); - if (npages != uvmexp.npages) { /* check for new pages? */ + if (npages != uvmexp.npages || extrapages != uvm_extrapages) { npages = uvmexp.npages; + extrapages = uvm_extrapages; uvmpd_tune(); }