Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111604010
D27220.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D27220.diff
View Options
Index: lib/Makefile
===================================================================
--- lib/Makefile
+++ lib/Makefile
@@ -99,6 +99,7 @@
libugidfw \
libulog \
libutil \
+ libuvmem \
${_libvgl} \
libwrap \
libxo \
Index: lib/libuvmem/Makefile
===================================================================
--- /dev/null
+++ lib/libuvmem/Makefile
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+PACKAGE= runtime
+
+LIB= uvmem
+SRCS= subr_vmem.c
+
+SHLIB_MAJOR = 1
+LIBADD+= pthread
+CFLAGS.clang+=-Wno-thread-safety-analysis
+
+SYMBOL_MAPS= ${.CURDIR}/Symbol.map
+VERSION_DEF= ${.CURDIR}/../libc/Versions.def
+
+.include <src.opts.mk>
+
+.PATH: ${SRCTOP}/sys/kern
+
+.include <bsd.lib.mk>
Index: lib/libuvmem/Symbol.map
===================================================================
--- /dev/null
+++ lib/libuvmem/Symbol.map
@@ -0,0 +1,21 @@
+/* $FreeBSD$ */
+
+FBSD_1.6 {
+ vmem_add;
+ vmem_alloc;
+ vmem_create;
+ vmem_destroy;
+ vmem_free;
+ vmem_init;
+ vmem_print;
+ vmem_printall;
+ vmem_roundup_size;
+ vmem_set_import;
+ vmem_set_limit;
+ vmem_set_reclaim;
+ vmem_size;
+ vmem_startup;
+ vmem_whatis;
+ vmem_xalloc;
+ vmem_xfree;
+};
Index: share/mk/bsd.libnames.mk
===================================================================
--- share/mk/bsd.libnames.mk
+++ share/mk/bsd.libnames.mk
@@ -159,6 +159,7 @@
LIBUSBHID?= ${LIBDESTDIR}${LIBDIR_BASE}/libusbhid.a
LIBUTIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libutil.a
LIBUUTIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libuutil.a
+LIBUVMEM?= ${LIBDESTDIR}${LIBDIR_BASE}/libuvmem.a
LIBVGL?= ${LIBDESTDIR}${LIBDIR_BASE}/libvgl.a
LIBVMMAPI?= ${LIBDESTDIR}${LIBDIR_BASE}/libvmmapi.a
LIBWIND?= ${LIBDESTDIR}${LIBDIR_BASE}/libwind.a
Index: share/mk/src.libnames.mk
===================================================================
--- share/mk/src.libnames.mk
+++ share/mk/src.libnames.mk
@@ -193,6 +193,7 @@
usb \
usbhid \
util \
+ uvmem \
uutil \
vmmapi \
wind \
@@ -386,6 +387,7 @@
_DP_ipf= kvm
_DP_tpool= spl
_DP_uutil= avl spl
+_DP_uvmem= pthread
_DP_zfs= md pthread umem util uutil m avl bsdxml crypto geom nvpair \
z zfs_core zutil
_DP_zfsbootenv= zfs nvpair
@@ -592,6 +594,9 @@
LIBC_NOSSP_PICDIR= ${_LIB_OBJTOP}/lib/libc
LIBC_NOSSP_PIC?= ${LIBC_NOSSP_PICDIR}/libc_nossp_pic.a
+LIBUVMEMDIR= ${OBJTOP}/lib/libuvmem
+LIBUVMEM?= ${LIBUVMEMDIR}/libuvmem${PIE_SUFFIX}.a
+
# Define a directory for each library. This is useful for adding -L in when
# not using a --sysroot or for meta mode bootstrapping when there is no
# Makefile.depend. These are sorted by directory.
Index: sys/contrib/openzfs/include/sys/zfs_context.h
===================================================================
--- sys/contrib/openzfs/include/sys/zfs_context.h
+++ sys/contrib/openzfs/include/sys/zfs_context.h
@@ -50,7 +50,9 @@
#include <sys/cmn_err.h>
#include <sys/kmem.h>
#include <sys/kmem_cache.h>
+#ifndef __FreeBSD__
#include <sys/vmem.h>
+#endif
#include <sys/taskq.h>
#include <sys/param.h>
#include <sys/disp.h>
Index: sys/kern/subr_vmem.c
===================================================================
--- sys/kern/subr_vmem.c
+++ sys/kern/subr_vmem.c
@@ -43,6 +43,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#ifdef _KERNEL
+
#include "opt_ddb.h"
#include <sys/param.h>
@@ -77,6 +79,28 @@
#include <vm/vm_pagequeue.h>
#include <vm/uma_int.h>
+#else /* _KERNEL */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/hash.h>
+#include <sys/vmem.h>
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#define KASSERT(a, b)
+#define MPASS(a)
+#define WITNESS_WARN(a, b, c)
+#define panic(...) assert(0)
+
+#endif /* _KERNEL */
+
#define VMEM_OPTORDER 5
#define VMEM_OPTVALUE (1 << VMEM_OPTORDER)
#define VMEM_MAXORDER \
@@ -89,24 +113,42 @@
#define VMEM_FITMASK (M_BESTFIT | M_FIRSTFIT | M_NEXTFIT)
-#define VMEM_FLAGS (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_NOVM | \
- M_BESTFIT | M_FIRSTFIT | M_NEXTFIT)
-
-#define BT_FLAGS (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_NOVM)
-
#define QC_NAME_MAX 16
/*
* Data structures private to vmem.
*/
+#ifdef _KERNEL
+
+#define VMEM_FLAGS (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_NOVM | \
+ M_BESTFIT | M_FIRSTFIT | M_NEXTFIT)
+
+#define BT_FLAGS (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_NOVM)
+
MALLOC_DEFINE(M_VMEM, "vmem", "vmem internal structures");
+#else /* _KERNEL */
+
+/* bit-compat with kernel */
+#define M_NOWAIT 0x0001
+#define M_WAITOK 0x0002
+#define M_ZERO 0
+#define M_NOVM 0
+#define M_USE_RESERVE 0
+
+#define VMEM_FLAGS (M_BESTFIT | M_FIRSTFIT | M_NEXTFIT)
+
+#define BT_FLAGS 0
+
+#endif /* _KERNEL */
+
typedef struct vmem_btag bt_t;
TAILQ_HEAD(vmem_seglist, vmem_btag);
LIST_HEAD(vmem_freelist, vmem_btag);
LIST_HEAD(vmem_hashlist, vmem_btag);
+#ifdef _KERNEL
struct qcache {
uma_zone_t qc_cache;
vmem_t *qc_vmem;
@@ -115,6 +157,7 @@
};
typedef struct qcache qcache_t;
#define QC_POOL_TO_QCACHE(pool) ((qcache_t *)(pool->pr_qcache))
+#endif
#define VMEM_NAME_MAX 16
@@ -134,8 +177,13 @@
/* vmem arena */
struct vmem {
+#ifdef _KERNEL
struct mtx_padalign vm_lock;
struct cv vm_cv;
+#else
+ pthread_mutex_t vm_lock;
+ pthread_cond_t vm_cv;
+#endif
char vm_name[VMEM_NAME_MAX+1];
LIST_ENTRY(vmem) vm_alllist;
struct vmem_hashlist vm_hash0[VMEM_HASHSIZE_MIN];
@@ -167,8 +215,10 @@
/* Space exhaustion callback. */
vmem_reclaim_t *vm_reclaimfn;
+#ifdef _KERNEL
/* quantum cache */
qcache_t vm_qcache[VMEM_QCACHE_IDX_MAX];
+#endif
};
#define BT_TYPE_SPAN 1 /* Allocated from importfn */
@@ -180,6 +230,7 @@
#define BT_END(bt) ((bt)->bt_start + (bt)->bt_size - 1)
+#ifdef _KERNEL
#if defined(DIAGNOSTIC)
static int enable_vmem_check = 1;
SYSCTL_INT(_debug, OID_AUTO, vmem_check, CTLFLAG_RWTUN,
@@ -192,10 +243,17 @@
static struct task vmem_periodic_wk;
static struct mtx_padalign __exclusive_cache_line vmem_list_lock;
-static LIST_HEAD(, vmem) vmem_list = LIST_HEAD_INITIALIZER(vmem_list);
static uma_zone_t vmem_zone;
+#else /* _KERNEL */
+static pthread_mutex_t vmem_list_lock = PTHREAD_MUTEX_INITIALIZER;
+
+#endif /* _KERNEL */
+
+static LIST_HEAD(, vmem) vmem_list = LIST_HEAD_INITIALIZER(vmem_list);
+
/* ---- misc */
+#ifdef _KERNEL
#define VMEM_CONDVAR_INIT(vm, wchan) cv_init(&vm->vm_cv, wchan)
#define VMEM_CONDVAR_DESTROY(vm) cv_destroy(&vm->vm_cv)
#define VMEM_CONDVAR_WAIT(vm) cv_wait(&vm->vm_cv, &vm->vm_lock)
@@ -207,6 +265,19 @@
#define VMEM_LOCK_INIT(vm, name) mtx_init(&vm->vm_lock, (name), NULL, MTX_DEF)
#define VMEM_LOCK_DESTROY(vm) mtx_destroy(&vm->vm_lock)
#define VMEM_ASSERT_LOCKED(vm) mtx_assert(&vm->vm_lock, MA_OWNED);
+#else /* _KERNEL */
+#define VMEM_CONDVAR_INIT(vm, wchan) pthread_cond_init(&vm->vm_cv, NULL)
+#define VMEM_CONDVAR_DESTROY(vm) pthread_cond_destroy(&vm->vm_cv)
+#define VMEM_CONDVAR_WAIT(vm) pthread_cond_wait(&vm->vm_cv, &vm->vm_lock)
+#define VMEM_CONDVAR_BROADCAST(vm) pthread_cond_broadcast(&vm->vm_cv)
+
+#define VMEM_LOCK(vm) pthread_mutex_lock(&vm->vm_lock)
+#define VMEM_TRYLOCK(vm) pthread_mutex_trylock(&vm->vm_lock)
+#define VMEM_UNLOCK(vm) pthread_mutex_unlock(&vm->vm_lock)
+#define VMEM_LOCK_INIT(vm, name) pthread_mutex_init(&vm->vm_lock, NULL)
+#define VMEM_LOCK_DESTROY(vm) pthread_mutex_destroy(&vm->vm_lock)
+#define VMEM_ASSERT_LOCKED(vm) pthread_mutex_isowned_np(&vm->vm_lock)
+#endif /* _KERNEL */
#define VMEM_ALIGNUP(addr, align) (-(-(addr) & -(align)))
@@ -231,6 +302,7 @@
*/
#define BT_MAXFREE (BT_MAXALLOC * 8)
+#ifdef _KERNEL
/* Allocator for boundary tags. */
static uma_zone_t vmem_bt_zone;
@@ -247,7 +319,8 @@
#ifdef DEBUG_MEMGUARD
static struct vmem memguard_arena_storage;
vmem_t *memguard_arena = &memguard_arena_storage;
-#endif
+#endif /* DEBUG_MEMGUARD */
+#endif /* _KERNEL */
static bool
bt_isbusy(bt_t *bt)
@@ -278,8 +351,10 @@
* dip into reserve tags. They are where new tags come from.
*/
flags &= BT_FLAGS;
+#ifdef _KERNEL
if (vm != kernel_arena && vm->vm_arg != kernel_arena)
flags &= ~M_USE_RESERVE;
+#endif
/*
* Loop until we meet the reserve. To minimize the lock shuffle
@@ -288,12 +363,18 @@
* holding a vmem lock.
*/
while (vm->vm_nfreetags < BT_MAXALLOC) {
+#ifdef _KERNEL
bt = uma_zalloc(vmem_bt_zone,
(flags & M_USE_RESERVE) | M_NOWAIT | M_NOVM);
+#else
+ bt = malloc(sizeof(struct vmem_btag));
+#endif
if (bt == NULL) {
+#ifdef _KERNEL
VMEM_UNLOCK(vm);
bt = uma_zalloc(vmem_bt_zone, flags);
VMEM_LOCK(vm);
+#endif
if (bt == NULL)
break;
}
@@ -353,7 +434,11 @@
VMEM_UNLOCK(vm);
while ((bt = LIST_FIRST(&freetags)) != NULL) {
LIST_REMOVE(bt, bt_freelist);
+#ifdef _KERNEL
uma_zfree(vmem_bt_zone, bt);
+#else
+ free(bt);
+#endif
}
}
@@ -540,6 +625,7 @@
/* ---- vmem internal functions */
+#ifdef _KERNEL
/*
* Import from the arena into the quantum cache in UMA.
*
@@ -728,8 +814,6 @@
#endif
}
-/* ---- rehash */
-
static int
vmem_rehash(vmem_t *vm, vmem_size_t newhashsize)
{
@@ -827,6 +911,7 @@
vmem_periodic_kick, NULL);
}
SYSINIT(vfs, SI_SUB_CONFIGURE, SI_ORDER_ANY, vmem_start_callout, NULL);
+#endif /* _KERNEL */
static void
vmem_add1(vmem_t *vm, vmem_addr_t addr, vmem_size_t size, int type)
@@ -882,10 +967,12 @@
{
bt_t *bt;
+#ifdef _KERNEL
/*
* Drain per-cpu quantum caches.
*/
qc_destroy(vm);
+#endif
/*
* The vmem should now only contain empty segments.
@@ -897,14 +984,23 @@
while ((bt = TAILQ_FIRST(&vm->vm_seglist)) != NULL)
bt_remseg(vm, bt);
- if (vm->vm_hashlist != NULL && vm->vm_hashlist != vm->vm_hash0)
+ if (vm->vm_hashlist != NULL && vm->vm_hashlist != vm->vm_hash0) {
+#ifdef _KERNEL
free(vm->vm_hashlist, M_VMEM);
+#else
+ free(vm->vm_hashlist);
+#endif
+ }
bt_freetrim(vm, 0);
VMEM_CONDVAR_DESTROY(vm);
VMEM_LOCK_DESTROY(vm);
+#ifdef _KERNEL
uma_zfree(vmem_zone, vm);
+#else
+ free(vm);
+#endif
}
static int
@@ -1061,8 +1157,10 @@
avail = vm->vm_size - vm->vm_inuse;
bt_save(vm);
VMEM_UNLOCK(vm);
+#ifdef _KERNEL
if (vm->vm_qcache_max != 0)
qc_drain(vm);
+#endif
if (vm->vm_reclaimfn != NULL)
vm->vm_reclaimfn(vm, flags);
VMEM_LOCK(vm);
@@ -1242,8 +1340,13 @@
{
vmem_size_t i;
+#ifdef _KERNEL
MPASS(quantum > 0);
MPASS((quantum & (quantum - 1)) == 0);
+#else
+ assert(quantum == 0);
+ assert(qcache_max == 0);
+#endif
bzero(vm, sizeof(*vm));
@@ -1258,7 +1361,11 @@
vm->vm_size = 0;
vm->vm_limit = 0;
vm->vm_inuse = 0;
+#ifdef _KERNEL
qc_init(vm, qcache_max);
+#else
+ qcache_max++;
+#endif
TAILQ_INIT(&vm->vm_seglist);
vm->vm_cursor.bt_start = vm->vm_cursor.bt_size = 0;
@@ -1279,9 +1386,17 @@
}
}
+#ifdef _KERNEL
mtx_lock(&vmem_list_lock);
+#else
+ pthread_mutex_lock(&vmem_list_lock);
+#endif
LIST_INSERT_HEAD(&vmem_list, vm, vm_alllist);
+#ifdef _KERNEL
mtx_unlock(&vmem_list_lock);
+#else
+ pthread_mutex_unlock(&vmem_list_lock);
+#endif
return vm;
}
@@ -1296,7 +1411,13 @@
vmem_t *vm;
+#ifdef _KERNEL
vm = uma_zalloc(vmem_zone, flags & (M_WAITOK|M_NOWAIT));
+#else
+ assert(quantum == 0);
+ assert(qcache_max == 0);
+ vm = malloc(sizeof(vmem_t));
+#endif
if (vm == NULL)
return (NULL);
if (vmem_init(vm, name, base, size, quantum, qcache_max,
@@ -1308,10 +1429,17 @@
void
vmem_destroy(vmem_t *vm)
{
-
+#ifdef _KERNEL
mtx_lock(&vmem_list_lock);
+#else
+ pthread_mutex_lock(&vmem_list_lock);
+#endif
LIST_REMOVE(vm, vm_alllist);
+#ifdef _KERNEL
mtx_unlock(&vmem_list_lock);
+#else
+ pthread_mutex_unlock(&vmem_list_lock);
+#endif
vmem_destroy1(vm);
}
@@ -1330,7 +1458,6 @@
vmem_alloc(vmem_t *vm, vmem_size_t size, int flags, vmem_addr_t *addrp)
{
const int strat __unused = flags & VMEM_FITMASK;
- qcache_t *qc;
flags &= VMEM_FLAGS;
MPASS(size > 0);
@@ -1338,7 +1465,10 @@
if ((flags & M_NOWAIT) == 0)
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "vmem_alloc");
+#ifdef _KERNEL
if (size <= vm->vm_qcache_max) {
+ qcache_t *qc;
+
/*
* Resource 0 cannot be cached, so avoid a blocking allocation
* in qc_import() and give the vmem_xalloc() call below a chance
@@ -1350,6 +1480,7 @@
if (__predict_true(*addrp != 0))
return (0);
}
+#endif
return (vmem_xalloc(vm, size, 0, 0, 0, VMEM_ADDR_MIN, VMEM_ADDR_MAX,
flags, addrp));
@@ -1469,14 +1600,17 @@
void
vmem_free(vmem_t *vm, vmem_addr_t addr, vmem_size_t size)
{
- qcache_t *qc;
MPASS(size > 0);
+#ifdef _KERNEL
if (size <= vm->vm_qcache_max &&
__predict_true(addr >= VMEM_ADDR_QCACHE_MIN)) {
+ qcache_t *qc;
+
qc = &vm->vm_qcache[(size - 1) >> vm->vm_quantum_shift];
uma_zfree(qc->qc_cache, (void *)addr);
} else
+#endif
vmem_xfree(vm, addr, size);
}
@@ -1570,11 +1704,13 @@
return (0);
default:
panic("vmem_size");
+ return (0);
}
}
/* ---- debug */
+#ifdef _KERNEL
#if defined(DDB) || defined(DIAGNOSTIC)
static void bt_dump(const bt_t *, int (*)(const char *, ...)
@@ -1826,3 +1962,4 @@
}
#endif /* defined(DIAGNOSTIC) */
+#endif /* _KERNEL */
Index: sys/sys/vmem.h
===================================================================
--- sys/sys/vmem.h
+++ sys/sys/vmem.h
@@ -34,8 +34,6 @@
#include <sys/types.h>
-#ifdef _KERNEL
-
typedef struct vmem vmem_t;
typedef uintptr_t vmem_addr_t;
@@ -45,10 +43,23 @@
#define VMEM_ADDR_QCACHE_MIN 1
#define VMEM_ADDR_MAX (~(vmem_addr_t)0)
+/* vmem_size typemask */
+#define VMEM_ALLOC 0x01
+#define VMEM_FREE 0x02
+#define VMEM_MAXFREE 0x10
+
typedef int (vmem_import_t)(void *, vmem_size_t, int, vmem_addr_t *);
typedef void (vmem_release_t)(void *, vmem_addr_t, vmem_size_t);
typedef void (vmem_reclaim_t)(vmem_t *, int);
+#ifndef _KERNEL
+#define M_FIRSTFIT 0x1000 /* only for vmem, fast fit */
+#define M_BESTFIT 0x2000 /* only for vmem, low fragmentation */
+#define M_NEXTFIT 0x8000 /* only for vmem, follow cursor */
+#endif
+
+__BEGIN_DECLS
+
/*
* Create a vmem:
* name - Name of the region
@@ -135,11 +146,6 @@
__printflike(1, 2));
void vmem_startup(void);
-/* vmem_size typemask */
-#define VMEM_ALLOC 0x01
-#define VMEM_FREE 0x02
-#define VMEM_MAXFREE 0x10
-
-#endif /* _KERNEL */
+__END_DECLS
#endif /* !_SYS_VMEM_H_ */
Index: usr.sbin/bhyve/Makefile
===================================================================
--- usr.sbin/bhyve/Makefile
+++ usr.sbin/bhyve/Makefile
@@ -84,7 +84,7 @@
.PATH: ${BHYVE_SYSDIR}/sys/amd64/vmm
SRCS+= vmm_instruction_emul.c
-LIBADD= vmmapi md pthread z util sbuf cam 9p casper cap_pwd cap_grp
+LIBADD= vmmapi md pthread z util sbuf cam 9p casper cap_pwd cap_grp uvmem
.if ${MK_BHYVE_SNAPSHOT} != "no"
LIBADD+= ucl xo
.endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 6, 9:44 PM (13 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17020243
Default Alt Text
D27220.diff (14 KB)
Attached To
Mode
D27220: libuvmem: usermode port of vmem(9)
Attached
Detach File
Event Timeline
Log In to Comment