From 8a2467ef8f22967972e25acb1d2d01c9a2f97e10 Mon Sep 17 00:00:00 2001 From: pooka Date: Tue, 7 Sep 2010 21:11:10 +0000 Subject: [PATCH] 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. --- sys/rump/librump/rumpkern/rump.c | 6 ++++-- sys/rump/librump/rumpkern/rump_private.h | 5 ++++- sys/rump/librump/rumpkern/vm.c | 21 +++++++++++---------- sys/rump/librump/rumpvfs/rump_vfs.c | 20 ++++++++++++++++++-- sys/rump/librump/rumpvfs/rump_vfs_private.h | 4 +++- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/sys/rump/librump/rumpkern/rump.c b/sys/rump/librump/rumpkern/rump.c index 899d7ffaf899..0cbaccb1bda5 100644 --- a/sys/rump/librump/rumpkern/rump.c +++ b/sys/rump/librump/rumpkern/rump.c @@ -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 -__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 #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); diff --git a/sys/rump/librump/rumpkern/rump_private.h b/sys/rump/librump/rumpkern/rump_private.h index 4be0b1292826..1eaeb03599a2 100644 --- a/sys/rump/librump/rumpkern/rump_private.h +++ b/sys/rump/librump/rumpkern/rump_private.h @@ -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); diff --git a/sys/rump/librump/rumpkern/vm.c b/sys/rump/librump/rumpkern/vm.c index 1b1e3906920c..ef1fe0a77718 100644 --- a/sys/rump/librump/rumpkern/vm.c +++ b/sys/rump/librump/rumpkern/vm.c @@ -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 -__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 #include @@ -63,6 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.90 2010/09/07 07:47:36 pooka Exp $"); #include #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); diff --git a/sys/rump/librump/rumpvfs/rump_vfs.c b/sys/rump/librump/rumpvfs/rump_vfs.c index 50b0675311a8..5ea907aad2b4 100644 --- a/sys/rump/librump/rumpvfs/rump_vfs.c +++ b/sys/rump/librump/rumpvfs/rump_vfs.c @@ -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 -__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 #include @@ -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); +} diff --git a/sys/rump/librump/rumpvfs/rump_vfs_private.h b/sys/rump/librump/rumpvfs/rump_vfs_private.h index 1fcdb84e96c3..d5403e45e0ae 100644 --- a/sys/rump/librump/rumpvfs/rump_vfs_private.h +++ b/sys/rump/librump/rumpvfs/rump_vfs_private.h @@ -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 #include #include