Make the Diabolical (Page)Daemon Director drain vfs buffers when

we are short of memory.

There are still some funnies left to iron out.  For example, with
a certain file system / memory size configuration it's still not
possible to create enough files to make the file system run out of
inodes before the kernel runs out of memory.  Also, with some other
configurations disk access slows down gargantually (though i'm sure
there are >0 buffers available).  Anyway, it ~works for now and
it's by no means worse than what it was before.
This commit is contained in:
pooka 2010-09-07 21:11:10 +00:00
parent f3c7386990
commit 8a2467ef8f
5 changed files with 40 additions and 16 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: rump.c,v 1.187 2010/09/07 18:25:38 pooka Exp $ */
/* $NetBSD: rump.c,v 1.188 2010/09/07 21:11:10 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.187 2010/09/07 18:25:38 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.188 2010/09/07 21:11:10 pooka Exp $");
#include <sys/systm.h>
#define ELFSIZE ARCH_ELFSIZE
@ -153,6 +153,8 @@ __weak_alias(rump_vfs_fini,rump__unavailable);
__weak_alias(biodone,rump__unavailable);
__weak_alias(sopoll,rump__unavailable);
__weak_alias(rump_vfs_drainbufs,rump__unavailable);
void rump__unavailable_vfs_panic(void);
void rump__unavailable_vfs_panic() {panic("vfs component not available");}
__weak_alias(usermount_common_policy,rump__unavailable_vfs_panic);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rump_private.h,v 1.57 2010/09/07 18:25:38 pooka Exp $ */
/* $NetBSD: rump_private.h,v 1.58 2010/09/07 21:11:10 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -87,6 +87,9 @@ do { \
panic("\"%s\" failed", #call); \
} while (/*CONSTCOND*/0)
#define RUMPMEM_UNLIMITED ((unsigned long)-1)
extern unsigned long rump_physmemlimit;
void rump_component_init(enum rump_component_type);
int rump_component_count(enum rump_component_type);

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm.c,v 1.90 2010/09/07 07:47:36 pooka Exp $ */
/* $NetBSD: vm.c,v 1.91 2010/09/07 21:11:10 pooka Exp $ */
/*
* Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.90 2010/09/07 07:47:36 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.91 2010/09/07 21:11:10 pooka Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@ -63,6 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.90 2010/09/07 07:47:36 pooka Exp $");
#include <uvm/uvm_readahead.h>
#include "rump_private.h"
#include "rump_vfs_private.h"
kmutex_t uvm_pageqlock;
kmutex_t uvm_swap_data_lock;
@ -81,8 +82,7 @@ static unsigned int pdaemon_waiters;
static kmutex_t pdaemonmtx;
static kcondvar_t pdaemoncv, oomwait;
#define RUMPMEM_UNLIMITED ((unsigned long)-1)
static unsigned long physmemlimit = RUMPMEM_UNLIMITED;
unsigned long rump_physmemlimit = RUMPMEM_UNLIMITED;
static unsigned long curphysmem;
static int
@ -199,13 +199,13 @@ uvm_init(void)
int error;
if (rumpuser_getenv("RUMP_MEMLIMIT", buf, sizeof(buf), &error) == 0) {
physmemlimit = strtoll(buf, NULL, 10);
rump_physmemlimit = strtoll(buf, NULL, 10);
/* it's not like we'd get far with, say, 1 byte, but ... */
if (physmemlimit == 0)
if (rump_physmemlimit == 0)
panic("uvm_init: no memory available");
#define HUMANIZE_BYTES 9
CTASSERT(sizeof(buf) >= HUMANIZE_BYTES);
format_bytes(buf, HUMANIZE_BYTES, physmemlimit);
format_bytes(buf, HUMANIZE_BYTES, rump_physmemlimit);
#undef HUMANIZE_BYTES
} else {
strlcpy(buf, "unlimited (host limit)", sizeof(buf));
@ -782,6 +782,7 @@ uvm_pageout(void *arg)
pool_drain_start(&pp_first, &where);
pp = pp_first;
for (;;) {
rump_vfs_drainbufs(10 /* XXX: estimate better */);
succ = pool_drain_end(pp, where);
if (succ)
break;
@ -839,9 +840,9 @@ rump_hypermalloc(size_t howmuch, int alignment, bool waitok, const char *wmsg)
/* first we must be within the limit */
limitagain:
if (physmemlimit != RUMPMEM_UNLIMITED) {
if (rump_physmemlimit != RUMPMEM_UNLIMITED) {
newmem = atomic_add_long_nv(&curphysmem, howmuch);
if (newmem > physmemlimit) {
if (newmem > rump_physmemlimit) {
newmem = atomic_add_long_nv(&curphysmem, -howmuch);
if (!waitok)
return NULL;
@ -865,7 +866,7 @@ void
rump_hyperfree(void *what, size_t size)
{
if (physmemlimit != RUMPMEM_UNLIMITED) {
if (rump_physmemlimit != RUMPMEM_UNLIMITED) {
atomic_add_long(&curphysmem, -size);
}
rumpuser_free(what);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rump_vfs.c,v 1.57 2010/09/07 17:13:03 pooka Exp $ */
/* $NetBSD: rump_vfs.c,v 1.58 2010/09/07 21:11:10 pooka Exp $ */
/*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.57 2010/09/07 17:13:03 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.58 2010/09/07 21:11:10 pooka Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@ -98,6 +98,13 @@ rump_vfs_init(void)
struct cpu_info *ci = cpu_lookup(i);
cache_cpu_init(ci);
}
/* make number of bufpages 5% of total memory limit */
if (rump_physmemlimit != RUMPMEM_UNLIMITED) {
extern u_int bufpages;
bufpages = rump_physmemlimit / (20 * PAGE_SIZE);
}
vfsinit();
bufinit();
cwd_sys_init();
@ -482,3 +489,12 @@ rump_biodone(void *arg, size_t count, int error)
biodone(bp);
}
void
rump_vfs_drainbufs(int npages)
{
mutex_enter(&bufcache_lock);
buf_drain(npages);
mutex_exit(&bufcache_lock);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: rump_vfs_private.h,v 1.13 2010/06/15 18:53:48 pooka Exp $ */
/* $NetBSD: rump_vfs_private.h,v 1.14 2010/09/07 21:11:10 pooka Exp $ */
/*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@ -51,6 +51,8 @@ int rump_vfs_makedevnodes(dev_t, const char *, char,
devmajor_t, devminor_t, int);
void rump_vfs_builddevs(struct devsw_conv *, size_t numelem);
void rump_vfs_drainbufs(int);
#include <sys/mount.h>
#include <sys/vnode.h>
#include <rump/rump.h>