svn commit: r368399 - head/sys/vm

Mark Johnston markj at FreeBSD.org
Sun Dec 6 22:45:40 UTC 2020


Author: markj
Date: Sun Dec  6 22:45:39 2020
New Revision: 368399
URL: https://svnweb.freebsd.org/changeset/base/368399

Log:
  uma: Enforce the use of uz_bucket_size_max in the free path
  
  uz_bucket_size_max is the maximum permitted bucket size.  When filling a
  new bucket to satisfy uma_zalloc(), the bucket is populated with at most
  uz_bucket_size_max items.  The maximum number of entries in the bucket
  may be larger.  When freeing items, however, we will fill per-CPPU
  buckets up to their maximum number of entries, potentially exceeding
  uz_bucket_size_max.  This makes it difficult to precisely limit the
  number of items that may be cached in a zone.  For example, if one wants
  to limit buckets to 1 entry for a particular zone, that's not possible
  since the smallest bucket holds up to 2 entries.
  
  Try to solve the problem by using uz_bucket_size_max to limit the number
  of entries in a bucket.  Note that the ub_entries field is initialized
  upon every bucket allocation.  Most zones are not affected since they do
  not impose any specific limit on the maximum bucket size.
  
  While here, remove the UMA_ZONE_MINBUCKET flag.  It was unused and we
  now have uma_zone_set_maxcache() to control the zone's cache size more
  precisely.
  
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D27167

Modified:
  head/sys/vm/uma.h
  head/sys/vm/uma_core.c

Modified: head/sys/vm/uma.h
==============================================================================
--- head/sys/vm/uma.h	Sun Dec  6 22:45:22 2020	(r368398)
+++ head/sys/vm/uma.h	Sun Dec  6 22:45:39 2020	(r368399)
@@ -250,7 +250,6 @@ uma_zone_t uma_zcache_create(const char *name, int siz
 #define	UMA_ZONE_SECONDARY	0x0200	/* Zone is a Secondary Zone */
 #define	UMA_ZONE_NOBUCKET	0x0400	/* Do not use buckets. */
 #define	UMA_ZONE_MAXBUCKET	0x0800	/* Use largest buckets. */
-#define	UMA_ZONE_MINBUCKET	0x1000	/* Use smallest buckets. */
 #define	UMA_ZONE_CACHESPREAD	0x2000	/*
 					 * Spread memory start locations across
 					 * all possible cache lines.  May

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c	Sun Dec  6 22:45:22 2020	(r368398)
+++ head/sys/vm/uma_core.c	Sun Dec  6 22:45:39 2020	(r368399)
@@ -248,7 +248,6 @@ struct uma_bucket_zone {
     (((sizeof(void *) * (n)) - sizeof(struct uma_bucket)) / sizeof(void *))
 
 #define	BUCKET_MAX	BUCKET_SIZE(256)
-#define	BUCKET_MIN	2
 
 struct uma_bucket_zone bucket_zones[] = {
 	/* Literal bucket sizes. */
@@ -507,7 +506,7 @@ bucket_alloc(uma_zone_t zone, void *udata, int flags)
 	}
 	if (((uintptr_t)udata & UMA_ZONE_VM) != 0)
 		flags |= M_NOVM;
-	ubz = bucket_zone_lookup(zone->uz_bucket_size);
+	ubz = bucket_zone_lookup(atomic_load_16(&zone->uz_bucket_size));
 	if (ubz->ubz_zone == zone && (ubz + 1)->ubz_entries != 0)
 		ubz++;
 	bucket = uma_zalloc_arg(ubz->ubz_zone, udata, flags);
@@ -516,7 +515,8 @@ bucket_alloc(uma_zone_t zone, void *udata, int flags)
 		bzero(bucket->ub_bucket, sizeof(void *) * ubz->ubz_entries);
 #endif
 		bucket->ub_cnt = 0;
-		bucket->ub_entries = ubz->ubz_entries;
+		bucket->ub_entries = min(ubz->ubz_entries,
+		    zone->uz_bucket_size_max);
 		bucket->ub_seq = SMR_SEQ_INVALID;
 		CTR3(KTR_UMA, "bucket_alloc: zone %s(%p) allocated bucket %p",
 		    zone->uz_name, zone, bucket);
@@ -2724,8 +2724,6 @@ out:
 		zone->uz_bucket_size_max = zone->uz_bucket_size = 0;
 	if ((arg->flags & UMA_ZONE_MAXBUCKET) != 0)
 		zone->uz_bucket_size = BUCKET_MAX;
-	else if ((arg->flags & UMA_ZONE_MINBUCKET) != 0)
-		zone->uz_bucket_size_max = zone->uz_bucket_size = BUCKET_MIN;
 	else if ((arg->flags & UMA_ZONE_NOBUCKET) != 0)
 		zone->uz_bucket_size = 0;
 	else


More information about the svn-src-head mailing list