Module Name: src Committed By: dyoung Date: Fri Sep 2 22:25:09 UTC 2011
Modified Files: src/sys/arch/xen/x86: xen_shm_machdep.c src/sys/kern: subr_kmem.c subr_percpu.c subr_vmem.c src/sys/rump/net/lib/libshmif: if_shmem.c src/sys/sys: vmem.h src/sys/uvm: uvm_emap.c uvm_swap.c Log Message: Report vmem(9) errors out-of-band so that we can use vmem(9) to manage ranges that include the least and the greatest vmem_addr_t. Update vmem(9) uses throughout the kernel. Slightly expand on the tests in subr_vmem.c, which still pass. I've been running a kernel with this patch without any trouble. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/xen/x86/xen_shm_machdep.c cvs rdiff -u -r1.35 -r1.36 src/sys/kern/subr_kmem.c cvs rdiff -u -r1.14 -r1.15 src/sys/kern/subr_percpu.c cvs rdiff -u -r1.60 -r1.61 src/sys/kern/subr_vmem.c cvs rdiff -u -r1.42 -r1.43 src/sys/rump/net/lib/libshmif/if_shmem.c cvs rdiff -u -r1.13 -r1.14 src/sys/sys/vmem.h cvs rdiff -u -r1.7 -r1.8 src/sys/uvm/uvm_emap.c cvs rdiff -u -r1.156 -r1.157 src/sys/uvm/uvm_swap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/xen/x86/xen_shm_machdep.c diff -u src/sys/arch/xen/x86/xen_shm_machdep.c:1.9 src/sys/arch/xen/x86/xen_shm_machdep.c:1.10 --- src/sys/arch/xen/x86/xen_shm_machdep.c:1.9 Sun Jul 31 18:00:54 2011 +++ src/sys/arch/xen/x86/xen_shm_machdep.c Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: xen_shm_machdep.c,v 1.9 2011/07/31 18:00:54 jym Exp $ */ +/* $NetBSD: xen_shm_machdep.c,v 1.10 2011/09/02 22:25:08 dyoung Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xen_shm_machdep.c,v 1.9 2011/07/31 18:00:54 jym Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xen_shm_machdep.c,v 1.10 2011/09/02 22:25:08 dyoung Exp $"); #include <sys/types.h> @@ -122,7 +122,7 @@ { int s, i; vaddr_t new_va; - u_long new_va_pg; + vmem_addr_t new_va_pg; int err; gnttab_map_grant_ref_t op[XENSHM_MAX_PAGES_PER_REQUEST]; @@ -151,9 +151,8 @@ return ENOMEM; } /* allocate the needed virtual space */ - new_va_pg = vmem_alloc(xen_shm_arena, nentries, - VM_INSTANTFIT | VM_NOSLEEP); - if (new_va_pg == 0) { + if (vmem_alloc(xen_shm_arena, nentries, + VM_INSTANTFIT | VM_NOSLEEP, &new_va_pg) != 0) { #ifdef DEBUG static struct timeval lasttime; #endif Index: src/sys/kern/subr_kmem.c diff -u src/sys/kern/subr_kmem.c:1.35 src/sys/kern/subr_kmem.c:1.36 --- src/sys/kern/subr_kmem.c:1.35 Sun Jul 17 20:54:52 2011 +++ src/sys/kern/subr_kmem.c Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_kmem.c,v 1.35 2011/07/17 20:54:52 joerg Exp $ */ +/* $NetBSD: subr_kmem.c,v 1.36 2011/09/02 22:25:08 dyoung Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_kmem.c,v 1.35 2011/07/17 20:54:52 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_kmem.c,v 1.36 2011/09/02 22:25:08 dyoung Exp $"); #include <sys/param.h> #include <sys/callback.h> @@ -133,9 +133,9 @@ #define kmem_size_check(p, sz) /* nothing */ #endif -static vmem_addr_t kmem_backend_alloc(vmem_t *, vmem_size_t, vmem_size_t *, - vm_flag_t); -static void kmem_backend_free(vmem_t *, vmem_addr_t, vmem_size_t); +static int kmem_backend_alloc(void *, vmem_size_t, vmem_size_t *, + vm_flag_t, vmem_addr_t *); +static void kmem_backend_free(void *, vmem_addr_t, vmem_size_t); static int kmem_kva_reclaim_callback(struct callback_entry *, void *, void *); CTASSERT(KM_SLEEP == PR_WAITOK); @@ -163,9 +163,12 @@ static void * kmem_poolpage_alloc(struct pool *pool, int prflags) { + vmem_addr_t addr; + int rc; - return (void *)vmem_alloc(kmem_arena, pool->pr_alloc->pa_pagesz, - kmf_to_vmf(prflags) | VM_INSTANTFIT); + rc = vmem_alloc(kmem_arena, pool->pr_alloc->pa_pagesz, + kmf_to_vmf(prflags) | VM_INSTANTFIT, &addr); + return (rc == 0) ? (void *)addr : NULL; } @@ -208,8 +211,13 @@ kmflags &= (KM_SLEEP | KM_NOSLEEP); p = pool_cache_get(kc->kc_cache, kmflags); } else { - p = (void *)vmem_alloc(kmem_arena, size, - kmf_to_vmf(kmflags) | VM_INSTANTFIT); + vmem_addr_t addr; + + if (vmem_alloc(kmem_arena, size, + kmf_to_vmf(kmflags) | VM_INSTANTFIT, &addr) == 0) + p = (void *)addr; + else + p = NULL; } if (__predict_true(p != NULL)) { kmem_poison_check(p, kmem_roundup_size(size)); @@ -335,9 +343,9 @@ /* ---- uvm glue */ -static vmem_addr_t -kmem_backend_alloc(vmem_t *dummy, vmem_size_t size, vmem_size_t *resultsize, - vm_flag_t vmflags) +static int +kmem_backend_alloc(void *dummy, vmem_size_t size, vmem_size_t *resultsize, + vm_flag_t vmflags, vmem_addr_t *addrp) { uvm_flag_t uflags; vaddr_t va; @@ -355,14 +363,15 @@ *resultsize = size = round_page(size); va = uvm_km_alloc(kernel_map, size, 0, uflags | UVM_KMF_WIRED | UVM_KMF_CANFAIL); - if (va != 0) { - kmem_poison_fill((void *)va, size); - } - return (vmem_addr_t)va; + if (va == 0) + return ENOMEM; + kmem_poison_fill((void *)va, size); + *addrp = (vmem_addr_t)va; + return 0; } static void -kmem_backend_free(vmem_t *dummy, vmem_addr_t addr, vmem_size_t size) +kmem_backend_free(void *dummy, vmem_addr_t addr, vmem_size_t size) { KASSERT(dummy == NULL); Index: src/sys/kern/subr_percpu.c diff -u src/sys/kern/subr_percpu.c:1.14 src/sys/kern/subr_percpu.c:1.15 --- src/sys/kern/subr_percpu.c:1.14 Wed Jul 27 14:35:34 2011 +++ src/sys/kern/subr_percpu.c Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_percpu.c,v 1.14 2011/07/27 14:35:34 uebayasi Exp $ */ +/* $NetBSD: subr_percpu.c,v 1.15 2011/09/02 22:25:08 dyoung Exp $ */ /*- * Copyright (c)2007,2008 YAMAMOTO Takashi, @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_percpu.c,v 1.14 2011/07/27 14:35:34 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_percpu.c,v 1.15 2011/09/02 22:25:08 dyoung Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -160,9 +160,9 @@ * percpu_backend_alloc: vmem import callback for percpu_offset_arena */ -static vmem_addr_t -percpu_backend_alloc(vmem_t *dummy, vmem_size_t size, vmem_size_t *resultsize, - vm_flag_t vmflags) +static int +percpu_backend_alloc(void *dummy, vmem_size_t size, vmem_size_t *resultsize, + vm_flag_t vmflags, vmem_addr_t *addrp) { unsigned int offset; unsigned int nextoff; @@ -171,7 +171,7 @@ KASSERT(dummy == NULL); if ((vmflags & VM_NOSLEEP) != 0) - return VMEM_ADDR_NULL; + return ENOMEM; size = roundup(size, PERCPU_IMPORT_SIZE); mutex_enter(&percpu_allocation_lock); @@ -182,7 +182,8 @@ percpu_cpu_enlarge(nextoff); *resultsize = size; - return (vmem_addr_t)offset; + *addrp = (vmem_addr_t)offset; + return 0; } static void @@ -252,11 +253,13 @@ percpu_t * percpu_alloc(size_t size) { - unsigned int offset; + vmem_addr_t offset; percpu_t *pc; ASSERT_SLEEPABLE(); - offset = vmem_alloc(percpu_offset_arena, size, VM_SLEEP | VM_BESTFIT); + if (vmem_alloc(percpu_offset_arena, size, VM_SLEEP | VM_BESTFIT, + &offset) != 0) + return NULL; pc = (percpu_t *)percpu_encrypt((uintptr_t)offset); percpu_zero(pc, size); return pc; Index: src/sys/kern/subr_vmem.c diff -u src/sys/kern/subr_vmem.c:1.60 src/sys/kern/subr_vmem.c:1.61 --- src/sys/kern/subr_vmem.c:1.60 Tue Aug 23 22:00:57 2011 +++ src/sys/kern/subr_vmem.c Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_vmem.c,v 1.60 2011/08/23 22:00:57 dyoung Exp $ */ +/* $NetBSD: subr_vmem.c,v 1.61 2011/09/02 22:25:08 dyoung Exp $ */ /*- * Copyright (c)2006,2007,2008,2009 YAMAMOTO Takashi, @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.60 2011/08/23 22:00:57 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.61 2011/09/02 22:25:08 dyoung Exp $"); #if defined(_KERNEL) #include "opt_ddb.h" @@ -121,10 +121,11 @@ /* vmem arena */ struct vmem { LOCK_DECL(vm_lock); - vmem_addr_t (*vm_allocfn)(vmem_t *, vmem_size_t, vmem_size_t *, - vm_flag_t); - void (*vm_freefn)(vmem_t *, vmem_addr_t, vmem_size_t); + int (*vm_importfn)(void *, vmem_size_t, vmem_size_t *, + vm_flag_t, vmem_addr_t *); + void (*vm_releasefn)(void *, vmem_addr_t, vmem_size_t); vmem_t *vm_source; + void *vm_arg; struct vmem_seglist vm_seglist; struct vmem_freelist vm_freelist[VMEM_MAXORDER]; size_t vm_hashsize; @@ -461,9 +462,12 @@ { qcache_t *qc = QC_POOL_TO_QCACHE(pool); vmem_t *vm = qc->qc_vmem; + vmem_addr_t addr; - return (void *)vmem_alloc(vm, pool->pr_alloc->pa_pagesz, - prf_to_vmf(prflags) | VM_INSTANTFIT); + if (vmem_alloc(vm, pool->pr_alloc->pa_pagesz, + prf_to_vmf(prflags) | VM_INSTANTFIT, &addr) != 0) + return NULL; + return (void *)addr; } static void @@ -579,7 +583,7 @@ } #endif /* defined(_KERNEL) */ -static vmem_addr_t +static int vmem_add1(vmem_t *vm, vmem_addr_t addr, vmem_size_t size, vm_flag_t flags, int spanbttype) { @@ -593,12 +597,12 @@ btspan = bt_alloc(vm, flags); if (btspan == NULL) { - return VMEM_ADDR_NULL; + return ENOMEM; } btfree = bt_alloc(vm, flags); if (btfree == NULL) { bt_free(vm, btspan); - return VMEM_ADDR_NULL; + return ENOMEM; } btspan->bt_type = spanbttype; @@ -615,7 +619,7 @@ bt_insfree(vm, btfree); VMEM_UNLOCK(vm); - return addr; + return 0; } static void @@ -646,18 +650,19 @@ vmem_import(vmem_t *vm, vmem_size_t size, vm_flag_t flags) { vmem_addr_t addr; + int rc; - if (vm->vm_allocfn == NULL) { + if (vm->vm_importfn == NULL) { return EINVAL; } - addr = (*vm->vm_allocfn)(vm->vm_source, size, &size, flags); - if (addr == VMEM_ADDR_NULL) { + rc = (*vm->vm_importfn)(vm->vm_arg, size, &size, flags, &addr); + if (rc != 0) { return ENOMEM; } - if (vmem_add1(vm, addr, size, flags, BT_TYPE_SPAN) == VMEM_ADDR_NULL) { - (*vm->vm_freefn)(vm->vm_source, addr, size); + if (vmem_add1(vm, addr, size, flags, BT_TYPE_SPAN) != 0) { + (*vm->vm_releasefn)(vm->vm_arg, addr, size); return ENOMEM; } @@ -716,10 +721,10 @@ * before calling us. */ -static vmem_addr_t +static int vmem_fit(const bt_t const *bt, vmem_size_t size, vmem_size_t align, vmem_size_t phase, vmem_size_t nocross, - vmem_addr_t minaddr, vmem_addr_t maxaddr) + vmem_addr_t minaddr, vmem_addr_t maxaddr, vmem_addr_t *addrp) { vmem_addr_t start; vmem_addr_t end; @@ -741,7 +746,7 @@ end = maxaddr; } if (start > end) { - return VMEM_ADDR_NULL; + return ENOMEM; } start = VMEM_ALIGNUP(start - phase, align) + phase; @@ -759,9 +764,10 @@ KASSERT(maxaddr == 0 || start + size - 1 <= maxaddr); KASSERT(bt->bt_start <= start); KASSERT(BT_END(bt) - start >= size - 1); - return start; + *addrp = start; + return 0; } - return VMEM_ADDR_NULL; + return ENOMEM; } /* ---- vmem API */ @@ -775,10 +781,10 @@ vmem_t * vmem_create(const char *name, vmem_addr_t base, vmem_size_t size, vmem_size_t quantum, - vmem_addr_t (*allocfn)(vmem_t *, vmem_size_t, vmem_size_t *, vm_flag_t), - void (*freefn)(vmem_t *, vmem_addr_t, vmem_size_t), - vmem_t *source, vmem_size_t qcache_max, vm_flag_t flags, - int ipl) + int (*importfn)(void *, vmem_size_t, vmem_size_t *, vm_flag_t, + vmem_addr_t *), + void (*releasefn)(void *, vmem_addr_t, vmem_size_t), + void *arg, vmem_size_t qcache_max, vm_flag_t flags, int ipl) { vmem_t *vm; int i; @@ -804,9 +810,9 @@ vm->vm_quantum_mask = quantum - 1; vm->vm_quantum_shift = calc_order(quantum); KASSERT(ORDER2SIZE(vm->vm_quantum_shift) == quantum); - vm->vm_allocfn = allocfn; - vm->vm_freefn = freefn; - vm->vm_source = source; + vm->vm_importfn = importfn; + vm->vm_releasefn = releasefn; + vm->vm_arg = arg; vm->vm_nbusytag = 0; #if defined(QCACHE) qc_init(vm, qcache_max, ipl); @@ -823,7 +829,7 @@ } if (size != 0) { - if (vmem_add(vm, base, size, flags) == 0) { + if (vmem_add(vm, base, size, flags) != 0) { vmem_destroy1(vm); return NULL; } @@ -865,8 +871,8 @@ * if the arena can be accessed from interrupt context. */ -vmem_addr_t -vmem_alloc(vmem_t *vm, vmem_size_t size, vm_flag_t flags) +int +vmem_alloc(vmem_t *vm, vmem_size_t size, vm_flag_t flags, vmem_addr_t *addrp) { const vm_flag_t strat __unused = flags & VM_FITMASK; @@ -881,22 +887,26 @@ #if defined(QCACHE) if (size <= vm->vm_qcache_max) { + void *p; int qidx = (size + vm->vm_quantum_mask) >> vm->vm_quantum_shift; qcache_t *qc = vm->vm_qcache[qidx - 1]; - return (vmem_addr_t)pool_cache_get(qc->qc_cache, - vmf_to_prf(flags)); + p = pool_cache_get(qc->qc_cache, vmf_to_prf(flags)); + if (addrp != NULL) + *addrp = (vmem_addr_t)p; + return (p == NULL) ? ENOMEM : 0; } #endif /* defined(QCACHE) */ return vmem_xalloc(vm, size, 0, 0, 0, VMEM_ADDR_MIN, VMEM_ADDR_MAX, - flags); + flags, addrp); } -vmem_addr_t +int vmem_xalloc(vmem_t *vm, const vmem_size_t size0, vmem_size_t align, const vmem_size_t phase, const vmem_size_t nocross, - const vmem_addr_t minaddr, const vmem_addr_t maxaddr, const vm_flag_t flags) + const vmem_addr_t minaddr, const vmem_addr_t maxaddr, const vm_flag_t flags, + vmem_addr_t *addrp) { struct vmem_freelist *list; struct vmem_freelist *first; @@ -907,6 +917,7 @@ const vmem_size_t size = vmem_roundup_size(vm, size0); vm_flag_t strat = flags & VM_FITMASK; vmem_addr_t start; + int rc; KASSERT(size0 > 0); KASSERT(size > 0); @@ -933,12 +944,12 @@ */ btnew = bt_alloc(vm, flags); if (btnew == NULL) { - return VMEM_ADDR_NULL; + return ENOMEM; } btnew2 = bt_alloc(vm, flags); /* XXX not necessary if no restrictions */ if (btnew2 == NULL) { bt_free(vm, btnew); - return VMEM_ADDR_NULL; + return ENOMEM; } /* @@ -962,9 +973,9 @@ for (list = first; list < end; list++) { bt = LIST_FIRST(list); if (bt != NULL) { - start = vmem_fit(bt, size, align, phase, - nocross, minaddr, maxaddr); - if (start != VMEM_ADDR_NULL) { + rc = vmem_fit(bt, size, align, phase, + nocross, minaddr, maxaddr, &start); + if (rc == 0) { goto gotit; } /* @@ -991,9 +1002,9 @@ for (list = first; list < end; list++) { LIST_FOREACH(bt, list, bt_freelist) { if (bt->bt_size >= size) { - start = vmem_fit(bt, size, align, phase, - nocross, minaddr, maxaddr); - if (start != VMEM_ADDR_NULL) { + rc = vmem_fit(bt, size, align, phase, + nocross, minaddr, maxaddr, &start); + if (rc == 0) { goto gotit; } } @@ -1025,7 +1036,7 @@ fail: bt_free(vm, btnew); bt_free(vm, btnew2); - return VMEM_ADDR_NULL; + return ENOMEM; gotit: KASSERT(bt->bt_type == BT_TYPE_FREE); @@ -1070,7 +1081,9 @@ KASSERT(btnew->bt_size >= size); btnew->bt_type = BT_TYPE_BUSY; - return btnew->bt_start; + if (addrp != NULL) + *addrp = btnew->bt_start; + return 0; } /* @@ -1084,7 +1097,6 @@ vmem_free(vmem_t *vm, vmem_addr_t addr, vmem_size_t size) { - KASSERT(addr != VMEM_ADDR_NULL); KASSERT(size > 0); #if defined(QCACHE) @@ -1105,7 +1117,6 @@ bt_t *bt; bt_t *t; - KASSERT(addr != VMEM_ADDR_NULL); KASSERT(size > 0); VMEM_LOCK(vm); @@ -1141,7 +1152,7 @@ t = CIRCLEQ_PREV(bt, bt_seglist); KASSERT(t != NULL); KASSERT(BT_ISSPAN_P(t) || t->bt_type == BT_TYPE_BUSY); - if (vm->vm_freefn != NULL && t->bt_type == BT_TYPE_SPAN && + if (vm->vm_releasefn != NULL && t->bt_type == BT_TYPE_SPAN && t->bt_size == bt->bt_size) { vmem_addr_t spanaddr; vmem_size_t spansize; @@ -1154,7 +1165,7 @@ bt_remseg(vm, t); bt_free(vm, t); VMEM_UNLOCK(vm); - (*vm->vm_freefn)(vm->vm_source, spanaddr, spansize); + (*vm->vm_releasefn)(vm->vm_arg, spanaddr, spansize); } else { bt_insfree(vm, bt); VMEM_UNLOCK(vm); @@ -1168,7 +1179,7 @@ * if the arena can be accessed from interrupt context. */ -vmem_addr_t +int vmem_add(vmem_t *vm, vmem_addr_t addr, vmem_size_t size, vm_flag_t flags) { @@ -1439,6 +1450,7 @@ int main(void) { + int rc; vmem_t *vm; vmem_addr_t p; struct reg { @@ -1456,38 +1468,50 @@ vm_flag_t strat = VM_BESTFIT; #endif - vm = vmem_create("test", VMEM_ADDR_NULL, 0, 1, - NULL, NULL, NULL, 0, VM_SLEEP, 0/*XXX*/); + vm = vmem_create("test", 0, 0, 1, NULL, NULL, NULL, 0, VM_SLEEP, +#ifdef _KERNEL + IPL_NONE +#else + 0 +#endif + ); if (vm == NULL) { printf("vmem_create\n"); exit(EXIT_FAILURE); } vmem_dump(vm, vmem_printf); - p = vmem_add(vm, 100, 200, VM_SLEEP); - assert(p != VMEM_ADDR_NULL); - p = vmem_add(vm, 2000, 1, VM_SLEEP); - assert(p != VMEM_ADDR_NULL); - p = vmem_add(vm, 40000, 65536, VM_SLEEP); - assert(p != VMEM_ADDR_NULL); - p = vmem_add(vm, 10000, 10000, VM_SLEEP); - assert(p != VMEM_ADDR_NULL); - p = vmem_add(vm, 500, 1000, VM_SLEEP); - assert(p != VMEM_ADDR_NULL); - p = vmem_add(vm, 0xffffff00, 0x100, VM_SLEEP); - assert(p != VMEM_ADDR_NULL); - p = vmem_xalloc(vm, 0x101, 0, 0, 0, - 0xffffff00, 0xffffffff, strat|VM_SLEEP); - assert(p == VMEM_ADDR_NULL); - p = vmem_xalloc(vm, 0x100, 0, 0, 0, - 0xffffff01, 0xffffffff, strat|VM_SLEEP); - assert(p == VMEM_ADDR_NULL); - p = vmem_xalloc(vm, 0x100, 0, 0, 0, - 0xffffff00, 0xfffffffe, strat|VM_SLEEP); - assert(p == VMEM_ADDR_NULL); - p = vmem_xalloc(vm, 0x100, 0, 0, 0, - 0xffffff00, 0xffffffff, strat|VM_SLEEP); - assert(p != VMEM_ADDR_NULL); + rc = vmem_add(vm, 0, 50, VM_SLEEP); + assert(rc == 0); + rc = vmem_add(vm, 100, 200, VM_SLEEP); + assert(rc == 0); + rc = vmem_add(vm, 2000, 1, VM_SLEEP); + assert(rc == 0); + rc = vmem_add(vm, 40000, 65536, VM_SLEEP); + assert(rc == 0); + rc = vmem_add(vm, 10000, 10000, VM_SLEEP); + assert(rc == 0); + rc = vmem_add(vm, 500, 1000, VM_SLEEP); + assert(rc == 0); + rc = vmem_add(vm, 0xffffff00, 0x100, VM_SLEEP); + assert(rc == 0); + rc = vmem_xalloc(vm, 0x101, 0, 0, 0, + 0xffffff00, 0xffffffff, strat|VM_SLEEP, &p); + assert(rc != 0); + rc = vmem_xalloc(vm, 50, 0, 0, 0, 0, 49, strat|VM_SLEEP, &p); + assert(rc == 0 && p == 0); + vmem_xfree(vm, p, 50); + rc = vmem_xalloc(vm, 25, 0, 0, 0, 0, 24, strat|VM_SLEEP, &p); + assert(rc == 0 && p == 0); + rc = vmem_xalloc(vm, 0x100, 0, 0, 0, + 0xffffff01, 0xffffffff, strat|VM_SLEEP, &p); + assert(rc != 0); + rc = vmem_xalloc(vm, 0x100, 0, 0, 0, + 0xffffff00, 0xfffffffe, strat|VM_SLEEP, &p); + assert(rc != 0); + rc = vmem_xalloc(vm, 0x100, 0, 0, 0, + 0xffffff00, 0xffffffff, strat|VM_SLEEP, &p); + assert(rc == 0); vmem_dump(vm, vmem_printf); for (;;) { struct reg *r; @@ -1527,16 +1551,16 @@ (uint64_t)nocross, (uint64_t)minaddr, (uint64_t)maxaddr); - p = vmem_xalloc(vm, sz, align, phase, nocross, - minaddr, maxaddr, strat|VM_SLEEP); + rc = vmem_xalloc(vm, sz, align, phase, nocross, + minaddr, maxaddr, strat|VM_SLEEP, &p); } else { x = false; printf("=== alloc %" PRIu64 "\n", (uint64_t)sz); - p = vmem_alloc(vm, sz, strat|VM_SLEEP); + rc = vmem_alloc(vm, sz, strat|VM_SLEEP, &p); } printf("-> %" PRIu64 "\n", (uint64_t)p); vmem_dump(vm, vmem_printf); - if (p == VMEM_ADDR_NULL) { + if (rc != 0) { if (x) { continue; } Index: src/sys/rump/net/lib/libshmif/if_shmem.c diff -u src/sys/rump/net/lib/libshmif/if_shmem.c:1.42 src/sys/rump/net/lib/libshmif/if_shmem.c:1.43 --- src/sys/rump/net/lib/libshmif/if_shmem.c:1.42 Thu Aug 25 15:14:19 2011 +++ src/sys/rump/net/lib/libshmif/if_shmem.c Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: if_shmem.c,v 1.42 2011/08/25 15:14:19 dyoung Exp $ */ +/* $NetBSD: if_shmem.c,v 1.43 2011/09/02 22:25:08 dyoung Exp $ */ /* * Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.42 2011/08/25 15:14:19 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.43 2011/09/02 22:25:08 dyoung Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -284,6 +284,7 @@ rump_shmif_create(const char *path, int *ifnum) { struct shmif_sc *sc; + vmem_addr_t t; int unit, error; int memfd = -1; /* XXXgcc */ @@ -293,8 +294,16 @@ return error; } - unit = vmem_xalloc(shmif_units, 1, 0, 0, 0, - VMEM_ADDR_MIN, VMEM_ADDR_MAX, VM_INSTANTFIT | VM_SLEEP) - 1; + error = vmem_xalloc(shmif_units, 1, 0, 0, 0, + VMEM_ADDR_MIN, VMEM_ADDR_MAX, VM_INSTANTFIT | VM_SLEEP, &t); + + if (error != 0) { + if (path) + rumpuser_close(memfd, NULL); + return error; + } + + unit = t - 1; if ((error = allocif(unit, &sc)) != 0) { if (path) @@ -325,7 +334,8 @@ static int shmif_clone(struct if_clone *ifc, int unit) { - int unit2; + int rc; + vmem_addr_t unit2; /* * Ok, we know the unit number, but we must still reserve it. @@ -334,9 +344,9 @@ * the range of unit numbers by +1 since vmem cannot deal with * ranges starting from 0. Talk about uuuh. */ - unit2 = vmem_xalloc(shmif_units, 1, 0, 0, 0, unit+1, unit+1, - VM_SLEEP | VM_INSTANTFIT); - KASSERT(unit2-1 == unit); + rc = vmem_xalloc(shmif_units, 1, 0, 0, 0, unit+1, unit+1, + VM_SLEEP | VM_INSTANTFIT, &unit2); + KASSERT(rc == 0 && unit2-1 == unit); return allocif(unit, NULL); } Index: src/sys/sys/vmem.h diff -u src/sys/sys/vmem.h:1.13 src/sys/sys/vmem.h:1.14 --- src/sys/sys/vmem.h:1.13 Tue Aug 23 22:00:57 2011 +++ src/sys/sys/vmem.h Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: vmem.h,v 1.13 2011/08/23 22:00:57 dyoung Exp $ */ +/* $NetBSD: vmem.h,v 1.14 2011/09/02 22:25:08 dyoung Exp $ */ /*- * Copyright (c)2006 YAMAMOTO Takashi, @@ -41,21 +41,20 @@ typedef uintptr_t vmem_addr_t; typedef size_t vmem_size_t; -#define VMEM_ADDR_NULL 0 #define VMEM_ADDR_MIN 0 #define VMEM_ADDR_MAX (~(vmem_addr_t)0) vmem_t *vmem_create(const char *, vmem_addr_t, vmem_size_t, vmem_size_t, - vmem_addr_t (*)(vmem_t *, vmem_size_t, vmem_size_t *, vm_flag_t), - void (*)(vmem_t *, vmem_addr_t, vmem_size_t), vmem_t *, vmem_size_t, + int (*)(void *, vmem_size_t, vmem_size_t *, vm_flag_t, vmem_addr_t *), + void (*)(void *, vmem_addr_t, vmem_size_t), void *, vmem_size_t, vm_flag_t, int); void vmem_destroy(vmem_t *); -vmem_addr_t vmem_alloc(vmem_t *, vmem_size_t, vm_flag_t); +int vmem_alloc(vmem_t *, vmem_size_t, vm_flag_t, vmem_addr_t *); void vmem_free(vmem_t *, vmem_addr_t, vmem_size_t); -vmem_addr_t vmem_xalloc(vmem_t *, vmem_size_t, vmem_size_t, vmem_size_t, - vmem_size_t, vmem_addr_t, vmem_addr_t, vm_flag_t); +int vmem_xalloc(vmem_t *, vmem_size_t, vmem_size_t, vmem_size_t, + vmem_size_t, vmem_addr_t, vmem_addr_t, vm_flag_t, vmem_addr_t *); void vmem_xfree(vmem_t *, vmem_addr_t, vmem_size_t); -vmem_addr_t vmem_add(vmem_t *, vmem_addr_t, vmem_size_t, vm_flag_t); +int vmem_add(vmem_t *, vmem_addr_t, vmem_size_t, vm_flag_t); vmem_size_t vmem_roundup_size(vmem_t *, vmem_size_t); bool vmem_reap(vmem_t *); void vmem_rehash_start(void); Index: src/sys/uvm/uvm_emap.c diff -u src/sys/uvm/uvm_emap.c:1.7 src/sys/uvm/uvm_emap.c:1.8 --- src/sys/uvm/uvm_emap.c:1.7 Sun Apr 25 15:54:14 2010 +++ src/sys/uvm/uvm_emap.c Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_emap.c,v 1.7 2010/04/25 15:54:14 ad Exp $ */ +/* $NetBSD: uvm_emap.c,v 1.8 2011/09/02 22:25:08 dyoung Exp $ */ /*- * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_emap.c,v 1.7 2010/04/25 15:54:14 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_emap.c,v 1.8 2011/09/02 22:25:08 dyoung Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -119,12 +119,16 @@ vaddr_t uvm_emap_alloc(vsize_t size, bool waitok) { + vmem_addr_t addr; KASSERT(size > 0); KASSERT(round_page(size) == size); - return vmem_alloc(uvm_emap_vmem, size, - VM_INSTANTFIT | (waitok ? VM_SLEEP : VM_NOSLEEP)); + if (vmem_alloc(uvm_emap_vmem, size, + VM_INSTANTFIT | (waitok ? VM_SLEEP : VM_NOSLEEP), &addr) == 0) + return (vaddr_t)addr; + + return (vaddr_t)0; } /* Index: src/sys/uvm/uvm_swap.c diff -u src/sys/uvm/uvm_swap.c:1.156 src/sys/uvm/uvm_swap.c:1.157 --- src/sys/uvm/uvm_swap.c:1.156 Sun Jun 12 03:36:04 2011 +++ src/sys/uvm/uvm_swap.c Fri Sep 2 22:25:08 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_swap.c,v 1.156 2011/06/12 03:36:04 rmind Exp $ */ +/* $NetBSD: uvm_swap.c,v 1.157 2011/09/02 22:25:08 dyoung Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 2009 Matthew R. Green @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.156 2011/06/12 03:36:04 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.157 2011/09/02 22:25:08 dyoung Exp $"); #include "opt_uvmhist.h" #include "opt_compat_netbsd.h" @@ -817,7 +817,7 @@ struct vnode *vp; int error, npages, nblocks, size; long addr; - u_long result; + vmem_addr_t result; struct vattr va; const struct bdevsw *bdev; dev_t dev; @@ -980,8 +980,8 @@ /* * now add the new swapdev to the drum and enable. */ - result = vmem_alloc(swapmap, npages, VM_BESTFIT | VM_SLEEP); - if (result == 0) + error = vmem_alloc(swapmap, npages, VM_BESTFIT | VM_SLEEP, &result); + if (error != 0) panic("swapdrum_add"); /* * If this is the first regular swap create the workqueue.