Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Feb 2020 01:07:19 +0000 (UTC)
From:      Jeff Roberson <jeff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r357988 - head/sys/vm
Message-ID:  <202002160107.01G17JBm096349@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jeff
Date: Sun Feb 16 01:07:19 2020
New Revision: 357988
URL: https://svnweb.freebsd.org/changeset/base/357988

Log:
  Slightly restructure uma_zalloc* to generate better code from clang and
  reduce duplication among zalloc functions.
  
  Reviewed by:	markj
  Discussed with:	mjg
  Differential Revision:	https://reviews.freebsd.org/D23672

Modified:
  head/sys/vm/uma_core.c

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c	Sun Feb 16 00:12:53 2020	(r357987)
+++ head/sys/vm/uma_core.c	Sun Feb 16 01:07:19 2020	(r357988)
@@ -3013,8 +3013,8 @@ item_ctor(uma_zone_t zone, int uz_flags, int size, voi
 	if (!skipdbg)
 		uma_dbg_alloc(zone, NULL, item);
 #endif
-	if (flags & M_ZERO)
-		bzero(item, size);
+	if (__predict_false(flags & M_ZERO))
+		return (memset(item, 0, size));
 
 	return (item);
 }
@@ -3117,11 +3117,35 @@ uma_zfree_debug(uma_zone_t zone, void *item, void *uda
 }
 #endif
 
+static inline void *
+cache_alloc_item(uma_zone_t zone, uma_cache_t cache, uma_cache_bucket_t bucket,
+    void *udata, int flags)
+{
+	void *item;
+	int size, uz_flags;
+
+	item = cache_bucket_pop(cache, bucket);
+	size = cache_uz_size(cache);
+	uz_flags = cache_uz_flags(cache);
+	critical_exit();
+	return (item_ctor(zone, uz_flags, size, udata, flags, item));
+}
+
 static __noinline void *
-uma_zalloc_single(uma_zone_t zone, void *udata, int flags)
+cache_alloc_retry(uma_zone_t zone, uma_cache_t cache, void *udata, int flags)
 {
+	uma_cache_bucket_t bucket;
 	int domain;
 
+	while (cache_alloc(zone, cache, udata, flags)) {
+		cache = &zone->uz_cpu[curcpu];
+		bucket = &cache->uc_allocbucket;
+		if (__predict_false(bucket->ucb_cnt == 0))
+			continue;
+		return (cache_alloc_item(zone, cache, bucket, udata, flags));
+	}
+	critical_exit();
+
 	/*
 	 * We can not get a bucket so try to return a single item.
 	 */
@@ -3138,10 +3162,10 @@ uma_zalloc_smr(uma_zone_t zone, int flags)
 {
 	uma_cache_bucket_t bucket;
 	uma_cache_t cache;
-	void *item;
-	int size, uz_flags;
 
 #ifdef UMA_ZALLOC_DEBUG
+	void *item;
+
 	KASSERT((zone->uz_flags & UMA_ZONE_SMR) != 0,
 	    ("uma_zalloc_arg: called with non-SMR zone.\n"));
 	if (uma_zalloc_debug(zone, &item, NULL, flags) == EJUSTRETURN)
@@ -3149,21 +3173,11 @@ uma_zalloc_smr(uma_zone_t zone, int flags)
 #endif
 
 	critical_enter();
-	do {
-		cache = &zone->uz_cpu[curcpu];
-		bucket = &cache->uc_allocbucket;
-		size = cache_uz_size(cache);
-		uz_flags = cache_uz_flags(cache);
-		if (__predict_true(bucket->ucb_cnt != 0)) {
-			item = cache_bucket_pop(cache, bucket);
-			critical_exit();
-			return (item_ctor(zone, uz_flags, size, NULL, flags,
-			    item));
-		}
-	} while (cache_alloc(zone, cache, NULL, flags));
-	critical_exit();
-
-	return (uma_zalloc_single(zone, NULL, flags));
+	cache = &zone->uz_cpu[curcpu];
+	bucket = &cache->uc_allocbucket;
+	if (__predict_false(bucket->ucb_cnt == 0))
+		return (cache_alloc_retry(zone, cache, NULL, flags));
+	return (cache_alloc_item(zone, cache, bucket, NULL, flags));
 }
 
 /* See uma.h */
@@ -3172,8 +3186,6 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags
 {
 	uma_cache_bucket_t bucket;
 	uma_cache_t cache;
-	void *item;
-	int size, uz_flags;
 
 	/* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */
 	random_harvest_fast_uma(&zone, sizeof(zone), RANDOM_UMA);
@@ -3183,6 +3195,8 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags
 	    zone, flags);
 
 #ifdef UMA_ZALLOC_DEBUG
+	void *item;
+
 	KASSERT((zone->uz_flags & UMA_ZONE_SMR) == 0,
 	    ("uma_zalloc_arg: called with SMR zone.\n"));
 	if (uma_zalloc_debug(zone, &item, udata, flags) == EJUSTRETURN)
@@ -3201,21 +3215,11 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags
 	 * must detect and handle migration if it has occurred.
 	 */
 	critical_enter();
-	do {
-		cache = &zone->uz_cpu[curcpu];
-		bucket = &cache->uc_allocbucket;
-		size = cache_uz_size(cache);
-		uz_flags = cache_uz_flags(cache);
-		if (__predict_true(bucket->ucb_cnt != 0)) {
-			item = cache_bucket_pop(cache, bucket);
-			critical_exit();
-			return (item_ctor(zone, uz_flags, size, udata, flags,
-			    item));
-		}
-	} while (cache_alloc(zone, cache, udata, flags));
-	critical_exit();
-
-	return (uma_zalloc_single(zone, udata, flags));
+	cache = &zone->uz_cpu[curcpu];
+	bucket = &cache->uc_allocbucket;
+	if (__predict_false(bucket->ucb_cnt == 0))
+		return (cache_alloc_retry(zone, cache, udata, flags));
+	return (cache_alloc_item(zone, cache, bucket, udata, flags));
 }
 
 /*
@@ -4326,7 +4330,7 @@ zone_release(void *arg, void **bucket, int cnt)
  *	udata  User supplied data for the dtor
  *	skip   Skip dtors and finis
  */
-static void
+static __noinline void
 zone_free_item(uma_zone_t zone, void *item, void *udata, enum zfreeskip skip)
 {
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002160107.01G17JBm096349>