svn commit: r327485 - in head/sys: cddl/compat/opensolaris/sys cddl/contrib/opensolaris/uts/common/fs/zfs vm

Jeff Roberson jeff at FreeBSD.org
Tue Jan 2 04:35:58 UTC 2018


Author: jeff
Date: Tue Jan  2 04:35:56 2018
New Revision: 327485
URL: https://svnweb.freebsd.org/changeset/base/327485

Log:
  Fix arc after r326347 broke various memory limit queries.  Use UMA features
  rather than kmem arena size to determine available memory.
  
  Initialize the UMA limit to LONG_MAX to avoid spurious wakeups on boot before
  the real limit is set.
  
  PR:		224330 (partial), 224080
  Reviewed by:	markj, avg
  Sponsored by:	Netflix / Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D13494

Modified:
  head/sys/cddl/compat/opensolaris/sys/kmem.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
  head/sys/vm/uma.h
  head/sys/vm/uma_core.c
  head/sys/vm/uma_int.h

Modified: head/sys/cddl/compat/opensolaris/sys/kmem.h
==============================================================================
--- head/sys/cddl/compat/opensolaris/sys/kmem.h	Tue Jan  2 03:59:46 2018	(r327484)
+++ head/sys/cddl/compat/opensolaris/sys/kmem.h	Tue Jan  2 04:35:56 2018	(r327485)
@@ -80,7 +80,8 @@ void *calloc(size_t n, size_t s);
 
 #define	freemem				vm_cnt.v_free_count
 #define	minfree				vm_cnt.v_free_min
-#define	heap_arena			kmem_arena
+#define	heap_arena			kernel_arena
+#define	zio_arena			NULL
 #define	kmem_alloc(size, kmflags)	zfs_kmem_alloc((size), (kmflags))
 #define	kmem_zalloc(size, kmflags)	zfs_kmem_alloc((size), (kmflags) | M_ZERO)
 #define	kmem_free(buf, size)		zfs_kmem_free((buf), (size))

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Tue Jan  2 03:59:46 2018	(r327484)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Tue Jan  2 04:35:56 2018	(r327485)
@@ -4207,7 +4207,6 @@ typedef enum free_memory_reason_t {
 	FMR_PAGES_PP_MAXIMUM,
 	FMR_HEAP_ARENA,
 	FMR_ZIO_ARENA,
-	FMR_ZIO_FRAG,
 } free_memory_reason_t;
 
 int64_t last_free_memory;
@@ -4302,15 +4301,11 @@ arc_available_memory(void)
 	 * heap is allocated.  (Or, in the calculation, if less than 1/4th is
 	 * free)
 	 */
-	n = (int64_t)vmem_size(heap_arena, VMEM_FREE) -
-	    (vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC) >> 2);
+	n = uma_avail() - (long)(uma_limit() / 4);
 	if (n < lowest) {
 		lowest = n;
 		r = FMR_HEAP_ARENA;
 	}
-#define	zio_arena	NULL
-#else
-#define	zio_arena	heap_arena
 #endif
 
 	/*
@@ -4331,20 +4326,6 @@ arc_available_memory(void)
 		}
 	}
 
-	/*
-	 * Above limits know nothing about real level of KVA fragmentation.
-	 * Start aggressive reclamation if too little sequential KVA left.
-	 */
-	if (lowest > 0) {
-		n = (vmem_size(heap_arena, VMEM_MAXFREE) < SPA_MAXBLOCKSIZE) ?
-		    -((int64_t)vmem_size(heap_arena, VMEM_ALLOC) >> 4) :
-		    INT64_MAX;
-		if (n < lowest) {
-			lowest = n;
-			r = FMR_ZIO_FRAG;
-		}
-	}
-
 #else	/* _KERNEL */
 	/* Every 100 calls, free a small amount */
 	if (spa_get_random(100) == 0)
@@ -6110,8 +6091,7 @@ arc_memory_throttle(uint64_t reserve, uint64_t txg)
 	static uint64_t last_txg = 0;
 
 #if defined(__i386) || !defined(UMA_MD_SMALL_ALLOC)
-	available_memory =
-	    MIN(available_memory, ptob(vmem_size(heap_arena, VMEM_FREE)));
+	available_memory = MIN(available_memory, uma_avail());
 #endif
 
 	if (freemem > (uint64_t)physmem * arc_lotsfree_percent / 100)
@@ -6492,8 +6472,12 @@ arc_init(void)
 	 * Metadata is stored in the kernel's heap.  Don't let us
 	 * use more than half the heap for the ARC.
 	 */
+#ifdef __FreeBSD__
+	arc_meta_limit = MIN(arc_meta_limit, uma_limit() / 2);
+#else
 	arc_meta_limit = MIN(arc_meta_limit,
 	    vmem_size(heap_arena, VMEM_ALLOC | VMEM_FREE) / 2);
+#endif
 #endif
 
 	/* Allow the tunable to override if it is reasonable */

Modified: head/sys/vm/uma.h
==============================================================================
--- head/sys/vm/uma.h	Tue Jan  2 03:59:46 2018	(r327484)
+++ head/sys/vm/uma.h	Tue Jan  2 04:35:56 2018	(r327485)
@@ -698,4 +698,12 @@ struct uma_percpu_stat {
 void uma_reclaim_wakeup(void);
 void uma_reclaim_worker(void *);
 
+unsigned long uma_limit(void);
+
+/* Return the amount of memory managed by UMA. */
+unsigned long uma_size(void);
+
+/* Return the amount of memory remaining.  May be negative. */
+long uma_avail(void);
+
 #endif	/* _VM_UMA_H_ */

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c	Tue Jan  2 03:59:46 2018	(r327484)
+++ head/sys/vm/uma_core.c	Tue Jan  2 04:35:56 2018	(r327485)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/eventhandler.h>
 #include <sys/kernel.h>
 #include <sys/types.h>
+#include <sys/limits.h>
 #include <sys/queue.h>
 #include <sys/malloc.h>
 #include <sys/ktr.h>
@@ -148,7 +149,7 @@ static struct mtx uma_boot_pages_mtx;
 static struct sx uma_drain_lock;
 
 /* kmem soft limit. */
-static unsigned long uma_kmem_limit;
+static unsigned long uma_kmem_limit = LONG_MAX;
 static volatile unsigned long uma_kmem_total;
 
 /* Is the VM done starting up? */
@@ -3265,7 +3266,14 @@ unsigned long
 uma_size(void)
 {
 
-	return uma_kmem_total;
+	return (uma_kmem_total);
+}
+
+long
+uma_avail(void)
+{
+
+	return (uma_kmem_limit - uma_kmem_total);
 }
 
 void

Modified: head/sys/vm/uma_int.h
==============================================================================
--- head/sys/vm/uma_int.h	Tue Jan  2 03:59:46 2018	(r327484)
+++ head/sys/vm/uma_int.h	Tue Jan  2 04:35:56 2018	(r327485)
@@ -428,10 +428,6 @@ void uma_small_free(void *mem, vm_size_t size, uint8_t
 
 /* Set a global soft limit on UMA managed memory. */
 void uma_set_limit(unsigned long limit);
-unsigned long uma_limit(void);
-
-/* Return the amount of memory managed by UMA. */
-unsigned long uma_size(void);
 #endif /* _KERNEL */
 
 #endif /* VM_UMA_INT_H */


More information about the svn-src-all mailing list