svn commit: r258693 - head/sys/vm

Alexander Motin mav at FreeBSD.org
Wed Nov 27 20:56:17 UTC 2013


Author: mav
Date: Wed Nov 27 20:56:10 2013
New Revision: 258693
URL: http://svnweb.freebsd.org/changeset/base/258693

Log:
  Make UMA to not blindly force offpage slab header allocation for large
  (> PAGE_SIZE) zones.  If zone is not multiple to PAGE_SIZE, there may
  be enough space for the header at the last page, so we may avoid extra
  header memory allocation and hash table update/lookup.
  
  ZFS creates bunch of odd-sized UMA zones (5120, 6144, 7168, 10240, 14336).
  This change gives good use to at least some of otherwise lost memory there.
  
  Reviewed by:	avg

Modified:
  head/sys/vm/uma_core.c

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c	Wed Nov 27 20:20:02 2013	(r258692)
+++ head/sys/vm/uma_core.c	Wed Nov 27 20:56:10 2013	(r258693)
@@ -1318,6 +1318,7 @@ keg_small_init(uma_keg_t keg)
 static void
 keg_large_init(uma_keg_t keg)
 {
+	u_int shsize;
 
 	KASSERT(keg != NULL, ("Keg is null in keg_large_init"));
 	KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0,
@@ -1334,8 +1335,21 @@ keg_large_init(uma_keg_t keg)
 	if (keg->uk_flags & UMA_ZFLAG_INTERNAL)
 		return;
 
-	keg->uk_flags |= UMA_ZONE_OFFPAGE;
-	if ((keg->uk_flags & UMA_ZONE_VTOSLAB) == 0)
+	/* Check whether we have enough space to not do OFFPAGE. */
+	if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0) {
+		shsize = sizeof(struct uma_slab);
+		if (keg->uk_flags & UMA_ZONE_REFCNT)
+			shsize += keg->uk_ipers * sizeof(uint32_t);
+		if (shsize & UMA_ALIGN_PTR)
+			shsize = (shsize & ~UMA_ALIGN_PTR) +
+			    (UMA_ALIGN_PTR + 1);
+
+		if ((PAGE_SIZE * keg->uk_ppera) - keg->uk_rsize < shsize)
+			keg->uk_flags |= UMA_ZONE_OFFPAGE;
+	}
+
+	if ((keg->uk_flags & UMA_ZONE_OFFPAGE) &&
+	    (keg->uk_flags & UMA_ZONE_VTOSLAB) == 0)
 		keg->uk_flags |= UMA_ZONE_HASH;
 }
 


More information about the svn-src-head mailing list