Index: uma_core.c =================================================================== --- uma_core.c (revision 258354) +++ uma_core.c (working copy) @@ -251,10 +251,10 @@ static void *zone_alloc_item(uma_zone_t, void *, i static void zone_free_item(uma_zone_t, void *, void *, enum zfreeskip); static void bucket_enable(void); static void bucket_init(void); -static uma_bucket_t bucket_alloc(uma_zone_t zone, void *, int); -static void bucket_free(uma_zone_t zone, uma_bucket_t, void *); +static uma_bucket_t bucket_alloc(uma_zone_t zone, int); +static void bucket_free(uma_zone_t zone, uma_bucket_t); static void bucket_zone_drain(void); -static uma_bucket_t zone_alloc_bucket(uma_zone_t zone, void *, int flags); +static uma_bucket_t zone_alloc_bucket(uma_zone_t zone, int flags); static uma_slab_t zone_fetch_slab(uma_zone_t zone, uma_keg_t last, int flags); static uma_slab_t zone_fetch_slab_multi(uma_zone_t zone, uma_keg_t last, int flags); static void *slab_alloc_item(uma_keg_t keg, uma_slab_t slab); @@ -346,7 +346,7 @@ bucket_select(int size) } static uma_bucket_t -bucket_alloc(uma_zone_t zone, void *udata, int flags) +bucket_alloc(uma_zone_t zone, int flags) { struct uma_bucket_zone *ubz; uma_bucket_t bucket; @@ -359,26 +359,10 @@ static uma_bucket_t */ if (bucketdisable) return (NULL); - /* - * To limit bucket recursion we store the original zone flags - * in a cookie passed via zalloc_arg/zfree_arg. This allows the - * NOVM flag to persist even through deep recursions. We also - * store ZFLAG_BUCKET once we have recursed attempting to allocate - * a bucket for a bucket zone so we do not allow infinite bucket - * recursion. This cookie will even persist to frees of unused - * buckets via the allocation path or bucket allocations in the - * free path. - */ - if ((uintptr_t)udata & UMA_ZFLAG_BUCKET) - return (NULL); - if ((zone->uz_flags & UMA_ZFLAG_BUCKET) == 0) - udata = (void *)(uintptr_t)zone->uz_flags; - else - udata = (void *)((uintptr_t)udata | UMA_ZFLAG_BUCKET); - if ((uintptr_t)udata & UMA_ZFLAG_CACHEONLY) + if (zone->uz_flags & UMA_ZFLAG_CACHEONLY) flags |= M_NOVM; ubz = bucket_zone_lookup(zone->uz_count); - bucket = uma_zalloc_arg(ubz->ubz_zone, udata, flags); + bucket = uma_zalloc(ubz->ubz_zone, flags | UMA_ZFLAG_BUCKET); if (bucket) { #ifdef INVARIANTS bzero(bucket->ub_bucket, sizeof(void *) * ubz->ubz_entries); @@ -391,16 +375,14 @@ static uma_bucket_t } static void -bucket_free(uma_zone_t zone, uma_bucket_t bucket, void *udata) +bucket_free(uma_zone_t zone, uma_bucket_t bucket) { struct uma_bucket_zone *ubz; KASSERT(bucket->ub_cnt == 0, ("bucket_free: Freeing a non free bucket.")); - if ((zone->uz_flags & UMA_ZFLAG_BUCKET) == 0) - udata = (void *)(uintptr_t)zone->uz_flags; ubz = bucket_zone_lookup(bucket->ub_entries); - uma_zfree_arg(ubz->ubz_zone, bucket, udata); + uma_zfree(ubz->ubz_zone, bucket); } static void @@ -675,9 +657,9 @@ cache_drain(uma_zone_t zone) bucket_drain(zone, cache->uc_allocbucket); bucket_drain(zone, cache->uc_freebucket); if (cache->uc_allocbucket != NULL) - bucket_free(zone, cache->uc_allocbucket, NULL); + bucket_free(zone, cache->uc_allocbucket); if (cache->uc_freebucket != NULL) - bucket_free(zone, cache->uc_freebucket, NULL); + bucket_free(zone, cache->uc_freebucket); cache->uc_allocbucket = cache->uc_freebucket = NULL; } ZONE_LOCK(zone); @@ -773,7 +755,7 @@ bucket_cache_drain(uma_zone_t zone) LIST_REMOVE(bucket, ub_link); ZONE_UNLOCK(zone); bucket_drain(zone, bucket); - bucket_free(zone, bucket, NULL); + bucket_free(zone, bucket); ZONE_LOCK(zone); } @@ -2160,7 +2156,7 @@ zalloc_start: cache->uc_allocbucket = NULL; critical_exit(); if (bucket != NULL) - bucket_free(zone, bucket, udata); + bucket_free(zone, bucket); /* Short-circuit for zones without buckets and low memory. */ if (zone->uz_count == 0 || bucketdisable) @@ -2227,7 +2223,7 @@ zalloc_start: * works we'll restart the allocation from the begining and it * will use the just filled bucket. */ - bucket = zone_alloc_bucket(zone, udata, flags); + bucket = zone_alloc_bucket(zone, flags); if (bucket != NULL) { ZONE_LOCK(zone); critical_enter(); @@ -2488,13 +2484,17 @@ zone_import(uma_zone_t zone, void **bucket, int ma } static uma_bucket_t -zone_alloc_bucket(uma_zone_t zone, void *udata, int flags) +zone_alloc_bucket(uma_zone_t zone, int flags) { uma_bucket_t bucket; int max; + /* Don't recurse allocating bucket while allocating bucket. */ + if (flags & UMA_ZFLAG_BUCKET) + return (NULL); + /* Don't wait for buckets, preserve caller's NOVM setting. */ - bucket = bucket_alloc(zone, udata, M_NOWAIT | (flags & M_NOVM)); + bucket = bucket_alloc(zone, M_NOWAIT | (flags & M_NOVM)); if (bucket == NULL) goto out; @@ -2530,7 +2530,7 @@ static uma_bucket_t out: if (bucket == NULL || bucket->ub_cnt == 0) { if (bucket != NULL) - bucket_free(zone, bucket, udata); + bucket_free(zone, bucket); atomic_add_long(&zone->uz_fails, 1); return (NULL); } @@ -2737,7 +2737,7 @@ zfree_start: #ifdef UMA_DEBUG_ALLOC printf("uma_zfree: Allocating new free bucket.\n"); #endif - bucket = bucket_alloc(zone, udata, M_NOWAIT); + bucket = bucket_alloc(zone, M_NOWAIT); if (bucket) { critical_enter(); cpu = curcpu; @@ -2751,7 +2751,7 @@ zfree_start: * critical section to free the bucket. */ critical_exit(); - bucket_free(zone, bucket, udata); + bucket_free(zone, bucket); goto zfree_restart; }