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.

Reply via email to