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.