Make uvm_pagealloc_tele() fail if the request can't be immediately

satisfied.  This allows the caller to unlock the object and the
pagedaemon to avoid deadlock even if ~all memory is consumed by
one vm object.  This in turn makes is possible to copy a large file
into a rump kernel with a 10MB memory limit (where large >> 10MB).
A little more tuning will be required to avoid the pagedaemon
hitting the sleep-and-retry path, though.

+ fix some outdated unrelated comments
This commit is contained in:
pooka 2010-12-01 11:19:18 +00:00
parent 301198ac5d
commit f73729b6b4
1 changed files with 13 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm.c,v 1.102 2010/11/22 20:42:19 pooka Exp $ */ /* $NetBSD: vm.c,v 1.103 2010/12/01 11:19:18 pooka Exp $ */
/* /*
* Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved. * Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved.
@ -41,7 +41,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.102 2010/11/22 20:42:19 pooka Exp $"); __KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.103 2010/12/01 11:19:18 pooka Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/atomic.h> #include <sys/atomic.h>
@ -146,8 +146,9 @@ pgctor(void *arg, void *obj, int flags)
struct vm_page *pg = obj; struct vm_page *pg = obj;
memset(pg, 0, sizeof(*pg)); memset(pg, 0, sizeof(*pg));
pg->uanon = rump_hypermalloc(PAGE_SIZE, PAGE_SIZE, true, "pgalloc"); pg->uanon = rump_hypermalloc(PAGE_SIZE, PAGE_SIZE,
return 0; (flags & PR_WAITOK) == PR_WAITOK, "pgalloc");
return pg->uanon == NULL;
} }
static void static void
@ -172,7 +173,10 @@ uvm_pagealloc_strat(struct uvm_object *uobj, voff_t off, struct vm_anon *anon,
KASSERT(uobj && mutex_owned(&uobj->vmobjlock)); KASSERT(uobj && mutex_owned(&uobj->vmobjlock));
KASSERT(anon == NULL); KASSERT(anon == NULL);
pg = pool_cache_get(&pagecache, PR_WAITOK); pg = pool_cache_get(&pagecache, PR_NOWAIT);
if (__predict_false(pg == NULL))
return NULL;
pg->offset = off; pg->offset = off;
pg->uobject = uobj; pg->uobject = uobj;
@ -326,8 +330,7 @@ uvm_init_limits(struct proc *p)
/* /*
* This satisfies the "disgusting mmap hack" used by proplib. * This satisfies the "disgusting mmap hack" used by proplib.
* We probably should grow some more assertables to make sure we're * We probably should grow some more assertables to make sure we're
* not satisfying anything we shouldn't be satisfying. At least we * not satisfying anything we shouldn't be satisfying.
* should make sure it's the local machine we're mmapping ...
*/ */
int int
uvm_mmap(struct vm_map *map, vaddr_t *addr, vsize_t size, vm_prot_t prot, uvm_mmap(struct vm_map *map, vaddr_t *addr, vsize_t size, vm_prot_t prot,
@ -760,8 +763,7 @@ uvmspace_addref(struct vmspace *vm)
{ {
/* /*
* there is only vmspace0. we're not planning on * No dynamically allocated vmspaces exist.
* feeding it to the fishes.
*/ */
} }
@ -1052,8 +1054,9 @@ rump_hypermalloc(size_t howmuch, int alignment, bool waitok, const char *wmsg)
newmem = atomic_add_long_nv(&curphysmem, howmuch); newmem = atomic_add_long_nv(&curphysmem, howmuch);
if (newmem > rump_physmemlimit) { if (newmem > rump_physmemlimit) {
newmem = atomic_add_long_nv(&curphysmem, -howmuch); newmem = atomic_add_long_nv(&curphysmem, -howmuch);
if (!waitok) if (!waitok) {
return NULL; return NULL;
}
uvm_wait(wmsg); uvm_wait(wmsg);
goto limitagain; goto limitagain;
} }