svn commit: r343052 - head/sys/vm

Gleb Smirnoff glebius at FreeBSD.org
Tue Jan 15 18:32:27 UTC 2019


Author: glebius
Date: Tue Jan 15 18:32:26 2019
New Revision: 343052
URL: https://svnweb.freebsd.org/changeset/base/343052

Log:
  Only do uz_items accounting for zones that have a limit set in uz_max_items.
  This reduces amount of locking required for these zones.
  
  Also, for cache only zones (UMA_ZFLAG_CACHE) accounting uz_items wasn't
  correct at all, since they may allocate items directly from their backing
  store and then free them via UMA underflowing uz_items.
  
  Tested by:	pho

Modified:
  head/sys/vm/uma_core.c

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c	Tue Jan 15 18:24:34 2019	(r343051)
+++ head/sys/vm/uma_core.c	Tue Jan 15 18:32:26 2019	(r343052)
@@ -736,11 +736,13 @@ bucket_drain(uma_zone_t zone, uma_bucket_t bucket)
 		for (i = 0; i < bucket->ub_cnt; i++) 
 			zone->uz_fini(bucket->ub_bucket[i], zone->uz_size);
 	zone->uz_release(zone->uz_arg, bucket->ub_bucket, bucket->ub_cnt);
-	ZONE_LOCK(zone);
-	zone->uz_items -= bucket->ub_cnt;
-	if (zone->uz_sleepers && zone->uz_items < zone->uz_max_items)
-		wakeup_one(zone);
-	ZONE_UNLOCK(zone);
+	if (zone->uz_max_items > 0) {
+		ZONE_LOCK(zone);
+		zone->uz_items -= bucket->ub_cnt;
+		if (zone->uz_sleepers && zone->uz_items < zone->uz_max_items)
+			wakeup_one(zone);
+		ZONE_UNLOCK(zone);
+	}
 	bucket->ub_cnt = 0;
 }
 
@@ -2515,9 +2517,9 @@ zalloc_start:
 			goto zalloc_item;
 		maxbucket = MIN(zone->uz_count,
 		    zone->uz_max_items - zone->uz_items);
+		zone->uz_items += maxbucket;
 	} else
 		maxbucket = zone->uz_count;
-	zone->uz_items += maxbucket;
 	ZONE_UNLOCK(zone);
 
 	/*
@@ -2530,9 +2532,8 @@ zalloc_start:
 	    zone->uz_name, zone, bucket);
 	ZONE_LOCK(zone);
 	if (bucket != NULL) {
-		if (bucket->ub_cnt < maxbucket) {
-			MPASS(zone->uz_flags & UMA_ZFLAG_CACHE ||
-			    zone->uz_items >= maxbucket - bucket->ub_cnt);
+		if (zone->uz_max_items > 0 && bucket->ub_cnt < maxbucket) {
+			MPASS(zone->uz_items >= maxbucket - bucket->ub_cnt);
 			zone->uz_items -= maxbucket - bucket->ub_cnt;
 			if (zone->uz_sleepers > 0 &&
 			    zone->uz_items < zone->uz_max_items)
@@ -2562,7 +2563,7 @@ zalloc_start:
 			zone_put_bucket(zone, zdom, bucket, false);
 		ZONE_UNLOCK(zone);
 		goto zalloc_start;
-	} else {
+	} else if (zone->uz_max_items > 0) {
 		zone->uz_items -= maxbucket;
 		if (zone->uz_sleepers > 0 &&
 		    zone->uz_items + 1 < zone->uz_max_items)
@@ -2912,24 +2913,25 @@ zone_alloc_item_locked(uma_zone_t zone, void *udata, i
 
 	ZONE_LOCK_ASSERT(zone);
 
-	if (zone->uz_max_items > 0 && zone->uz_items >= zone->uz_max_items) {
-		zone_log_warning(zone);
-		zone_maxaction(zone);
-		if (flags & M_NOWAIT) {
-			ZONE_UNLOCK(zone);
-			return (NULL);
+	if (zone->uz_max_items > 0) {
+		if (zone->uz_items >= zone->uz_max_items) {
+			zone_log_warning(zone);
+			zone_maxaction(zone);
+			if (flags & M_NOWAIT) {
+				ZONE_UNLOCK(zone);
+				return (NULL);
+			}
+			zone->uz_sleeps++;
+			zone->uz_sleepers++;
+			while (zone->uz_items >= zone->uz_max_items)
+				mtx_sleep(zone, zone->uz_lockptr, PVM, "zonelimit", 0);
+			zone->uz_sleepers--;
+			if (zone->uz_sleepers > 0 &&
+			    zone->uz_items + 1 < zone->uz_max_items)
+				wakeup_one(zone);
 		}
-		zone->uz_sleeps++;
-		zone->uz_sleepers++;
-		while (zone->uz_items >= zone->uz_max_items)
-			mtx_sleep(zone, zone->uz_lockptr, PVM, "zonelimit", 0);
-		zone->uz_sleepers--;
-		if (zone->uz_sleepers > 0 &&
-		    zone->uz_items + 1 < zone->uz_max_items)
-			wakeup_one(zone);
+		zone->uz_items++;
 	}
-
-	zone->uz_items++;
 	ZONE_UNLOCK(zone);
 
 	if (domain != UMA_ANYDOMAIN) {
@@ -2978,9 +2980,11 @@ zone_alloc_item_locked(uma_zone_t zone, void *udata, i
 	return (item);
 
 fail:
-	ZONE_LOCK(zone);
-	zone->uz_items--;
-	ZONE_UNLOCK(zone);
+	if (zone->uz_max_items > 0) {
+		ZONE_LOCK(zone);
+		zone->uz_items--;
+		ZONE_UNLOCK(zone);
+	}
 	counter_u64_add(zone->uz_fails, 1);
 	CTR2(KTR_UMA, "zone_alloc_item failed from %s(%p)",
 	    zone->uz_name, zone);
@@ -3294,11 +3298,14 @@ zone_free_item(uma_zone_t zone, void *item, void *udat
 
 	counter_u64_add(zone->uz_frees, 1);
 
-	ZONE_LOCK(zone);
-	zone->uz_items--;
-	if (zone->uz_sleepers > 0 && zone->uz_items < zone->uz_max_items)
-		wakeup_one(zone);
-	ZONE_UNLOCK(zone);
+	if (zone->uz_max_items > 0) {
+		ZONE_LOCK(zone);
+		zone->uz_items--;
+		if (zone->uz_sleepers > 0 &&
+		    zone->uz_items < zone->uz_max_items)
+			wakeup_one(zone);
+		ZONE_UNLOCK(zone);
+	}
 }
 
 /* See uma.h */
@@ -3902,8 +3909,11 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
 			uth.uth_align = kz->uk_align;
 			uth.uth_size = kz->uk_size;
 			uth.uth_rsize = kz->uk_rsize;
-			uth.uth_pages += (z->uz_items / kz->uk_ipers) *
-			    kz->uk_ppera;
+			if (z->uz_max_items > 0)
+				uth.uth_pages = (z->uz_items / kz->uk_ipers) *
+					kz->uk_ppera;
+			else
+				uth.uth_pages = kz->uk_pages;
 			uth.uth_maxpages += (z->uz_max_items / kz->uk_ipers) *
 			    kz->uk_ppera;
 			uth.uth_limit = z->uz_max_items;


More information about the svn-src-all mailing list