summaryrefslogtreecommitdiffstats
path: root/sys/vm/uma_int.h
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2013-06-20 19:08:12 +0000
committerjeff <jeff@FreeBSD.org>2013-06-20 19:08:12 +0000
commita6b6e4783cacc87cafc71706cba9641c4c3718cf (patch)
treeb028c6ab28bde9b40465f529e8e9618d39716baf /sys/vm/uma_int.h
parentda3b12a1bbf9d2863451efdee810a0ee646494a9 (diff)
downloadFreeBSD-src-a6b6e4783cacc87cafc71706cba9641c4c3718cf.zip
FreeBSD-src-a6b6e4783cacc87cafc71706cba9641c4c3718cf.tar.gz
- Add a per-zone lock for zones without kegs.
- Be more explicit about zone vs keg locking. This functionally changes almost nothing. - Add a size parameter to uma_zcache_create() so we can size the buckets. - Pass the zone to bucket_alloc() so it can modify allocation flags as appropriate. - Fix a bug in zone_alloc_bucket() where I missed an address of operator in a failure case. (Found by pho) Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/vm/uma_int.h')
-rw-r--r--sys/vm/uma_int.h31
1 files changed, 23 insertions, 8 deletions
diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index 592fe19..b6bec1a 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -189,7 +189,7 @@ typedef struct uma_cache * uma_cache_t;
*
*/
struct uma_keg {
- struct mtx uk_lock; /* Lock for the keg */
+ struct mtx_padalign uk_lock; /* Lock for the keg */
struct uma_hash uk_hash;
LIST_HEAD(,uma_zone) uk_zones; /* Keg's zones */
@@ -281,8 +281,9 @@ typedef struct uma_klink *uma_klink_t;
*
*/
struct uma_zone {
- const char *uz_name; /* Text name of the zone */
- struct mtx *uz_lock; /* Lock for the zone (keg's lock) */
+ struct mtx_padalign uz_lock; /* Lock for the zone */
+ struct mtx_padalign *uz_lockptr;
+ const char *uz_name; /* Text name of the zone */
LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */
LIST_HEAD(,uma_bucket) uz_buckets; /* full buckets */
@@ -334,8 +335,10 @@ struct uma_zone {
static inline uma_keg_t
zone_first_keg(uma_zone_t zone)
{
+ uma_klink_t klink;
- return (LIST_FIRST(&zone->uz_kegs)->kl_keg);
+ klink = LIST_FIRST(&zone->uz_kegs);
+ return (klink != NULL) ? klink->kl_keg : NULL;
}
#undef UMA_ALIGN
@@ -357,13 +360,25 @@ void uma_large_free(uma_slab_t slab);
mtx_init(&(k)->uk_lock, (k)->uk_name, \
"UMA zone", MTX_DEF | MTX_DUPOK); \
} while (0)
-
+
#define KEG_LOCK_FINI(k) mtx_destroy(&(k)->uk_lock)
#define KEG_LOCK(k) mtx_lock(&(k)->uk_lock)
#define KEG_UNLOCK(k) mtx_unlock(&(k)->uk_lock)
-#define ZONE_LOCK(z) mtx_lock((z)->uz_lock)
-#define ZONE_TRYLOCK(z) mtx_trylock((z)->uz_lock)
-#define ZONE_UNLOCK(z) mtx_unlock((z)->uz_lock)
+
+#define ZONE_LOCK_INIT(z, lc) \
+ do { \
+ if ((lc)) \
+ mtx_init(&(z)->uz_lock, (z)->uz_name, \
+ (z)->uz_name, MTX_DEF | MTX_DUPOK); \
+ else \
+ mtx_init(&(z)->uz_lock, (z)->uz_name, \
+ "UMA zone", MTX_DEF | MTX_DUPOK); \
+ } while (0)
+
+#define ZONE_LOCK(z) mtx_lock((z)->uz_lockptr)
+#define ZONE_TRYLOCK(z) mtx_trylock((z)->uz_lockptr)
+#define ZONE_UNLOCK(z) mtx_unlock((z)->uz_lockptr)
+#define ZONE_LOCK_FINI(z) mtx_destroy(&(z)->uz_lock)
/*
* Find a slab within a hash table. This is used for OFFPAGE zones to lookup
OpenPOWER on IntegriCloud