diff --git a/sys/cddl/compat/opensolaris/sys/kmem.h b/sys/cddl/compat/opensolaris/sys/kmem.h index 75837d29e20a..7b5c4f9956b3 100644 --- a/sys/cddl/compat/opensolaris/sys/kmem.h +++ b/sys/cddl/compat/opensolaris/sys/kmem.h @@ -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)) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 0cff5a70a55e..facd1d227bc6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -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 */ diff --git a/sys/vm/uma.h b/sys/vm/uma.h index 1ea8ee06245b..1bd366416cbc 100644 --- a/sys/vm/uma.h +++ b/sys/vm/uma.h @@ -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_ */ diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 81c953a48383..0dd16dd9c325 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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 diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h index 158c2383c885..a8aca454f066 100644 --- a/sys/vm/uma_int.h +++ b/sys/vm/uma_int.h @@ -428,10 +428,6 @@ void uma_small_free(void *mem, vm_size_t size, uint8_t flags); /* 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 */