FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
/*
 * Return the amount of memory that can be consumed before reclaim will be
 * needed.  Positive if there is sufficient free memory, negative indicates
 * the amount of memory that needs to be freed up.
 */
Return the amount of memory that can be consumed before reclaim will be
needed.  Positive if there is sufficient free memory, negative indicates
the amount of memory that needs to be freed up.
Return the amount of memory that can be consumed before reclaim will be needed . Positive if there is sufficient free memory negative indicates the amount of memory that needs to be freed up .
static int64_t
arc_available_memory(void)
{
	int64_t lowest = INT64_MAX;
	int64_t n;
	free_memory_reason_t r = FMR_UNKNOWN;
#ifdef _KERNEL
	if (needfree > 0) {
		n = PAGESIZE * (-needfree);
		if (n < lowest) {
			lowest = n;
			r = FMR_NEEDFREE;
		}
	}
	n = PAGESIZE * ((int64_t)freemem - zfs_arc_free_target);
	if (n < lowest) {
		lowest = n;
		r = FMR_LOTSFREE;
	}
#ifdef illumos
	n = PAGESIZE * (freemem - lotsfree - needfree - desfree);
	if (n < lowest) {
		lowest = n;
		r = FMR_LOTSFREE;
	}
	n = PAGESIZE * (availrmem - swapfs_minfree - swapfs_reserve -
	    desfree - arc_swapfs_reserve);
	if (n < lowest) {
		lowest = n;
		r = FMR_SWAPFS_MINFREE;
	}
	n = PAGESIZE * (availrmem - pages_pp_maximum -
	    arc_pages_pp_reserve);
	if (n < lowest) {
		lowest = n;
		r = FMR_PAGES_PP_MAXIMUM;
	}
#endif	
#if defined(__i386) || !defined(UMA_MD_SMALL_ALLOC)
	n = (int64_t)vmem_size(heap_arena, VMEM_FREE) -
	    (vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC) >> 2);
	if (n < lowest) {
		lowest = n;
		r = FMR_HEAP_ARENA;
	}
#define	zio_arena	NULL
#else
#define	zio_arena	heap_arena
#endif
	if (zio_arena != NULL) {
		n = (int64_t)vmem_size(zio_arena, VMEM_FREE) -
		    (vmem_size(zio_arena, VMEM_ALLOC) >> 4);
		if (n < lowest) {
			lowest = n;
			r = FMR_ZIO_ARENA;
		}
	}
	if (lowest > 0) {
		n = (vmem_size(heap_arena, VMEM_MAXFREE) < zfs_max_recordsize) ?
		    -((int64_t)vmem_size(heap_arena, VMEM_ALLOC) >> 4) :
		    INT64_MAX;
		if (n < lowest) {
			lowest = n;
			r = FMR_ZIO_FRAG;
		}
	}
#else	
	if (spa_get_random(100) == 0)
		lowest = -1024;
#endif	
	last_free_memory = lowest;
	last_free_reason = r;
	DTRACE_PROBE2(arc__available_memory, int64_t, lowest, int, r);
	return (lowest);
}
static int64_t arc_available_memory ( void ) { int64_t lowest = INT64_MAX ; int64_t n ; free_memory_reason_t r = FMR_UNKNOWN ; #ifdef _KERNEL if ( needfree > 0 ) { n = PAGESIZE * ( - needfree ) ; if ( n < lowest ) { lowest = n ; r = FMR_NEEDFREE ; } } n = PAGESIZE * ( ( int64_t ) freemem - zfs_arc_free_target ) ; if ( n < lowest ) { lowest = n ; r = FMR_LOTSFREE ; } #ifdef illumos n = PAGESIZE * ( freemem - lotsfree - needfree - desfree ) ; if ( n < lowest ) { lowest = n ; r = FMR_LOTSFREE ; } n = PAGESIZE * ( availrmem - swapfs_minfree - swapfs_reserve - desfree - arc_swapfs_reserve ) ; if ( n < lowest ) { lowest = n ; r = FMR_SWAPFS_MINFREE ; } n = PAGESIZE * ( availrmem - pages_pp_maximum - arc_pages_pp_reserve ) ; if ( n < lowest ) { lowest = n ; r = FMR_PAGES_PP_MAXIMUM ; } #endif #if defined ( __i386 ) || ! defined ( UMA_MD_SMALL_ALLOC ) n = ( int64_t ) vmem_size ( heap_arena , VMEM_FREE ) - ( vmem_size ( heap_arena , VMEM_FREE | VMEM_ALLOC ) >> 2 ) ; if ( n < lowest ) { lowest = n ; r = FMR_HEAP_ARENA ; } #define zio_arena 	NULL #else #define zio_arena 	heap_arena #endif if ( zio_arena != NULL ) { n = ( int64_t ) vmem_size ( zio_arena , VMEM_FREE ) - ( vmem_size ( zio_arena , VMEM_ALLOC ) >> 4 ) ; if ( n < lowest ) { lowest = n ; r = FMR_ZIO_ARENA ; } } if ( lowest > 0 ) { n = ( vmem_size ( heap_arena , VMEM_MAXFREE ) < zfs_max_recordsize ) ? - ( ( int64_t ) vmem_size ( heap_arena , VMEM_ALLOC ) >> 4 ) : INT64_MAX ; if ( n < lowest ) { lowest = n ; r = FMR_ZIO_FRAG ; } } #else if ( spa_get_random ( 100 ) == 0 ) lowest = -1024 ; #endif last_free_memory = lowest ; last_free_reason = r ; DTRACE_PROBE2 ( arc__available_memory , int64_t , lowest , int , r ) ; return ( lowest ) ; }
Return the amount of memory that can be consumed before reclaim will be
 needed.
Return the amount of memory that can be consumed before reclaim will be needed .
/*
	 * Cooperate with pagedaemon when it's time for it to scan
	 * and reclaim some pages.
	 */ /*
	 * check that we're out of range of the pageout scanner.  It starts to
	 * schedule paging if freemem is less than lotsfree and needfree.
	 * lotsfree is the high-water mark for pageout, and needfree is the
	 * number of needed free pages.  We add extra pages here to make sure
	 * the scanner doesn't start up while we're freeing memory.
	 */ /*
	 * check to make sure that swapfs has enough space so that anon
	 * reservations can still succeed. anon_resvmem() checks that the
	 * availrmem is greater than swapfs_minfree, and the number of reserved
	 * swap pages.  We also add a bit of extra here just to prevent
	 * circumstances from getting really dire.
	 */ /*
	 * Check that we have enough availrmem that memory locking (e.g., via
	 * mlock(3C) or memcntl(2)) can still succeed.  (pages_pp_maximum
	 * stores the number of pages that cannot be locked; when availrmem
	 * drops below pages_pp_maximum, page locking mechanisms such as
	 * page_pp_lock() will fail.)
	 */ /* illumos */ /*
	 * If we're on an i386 platform, it's possible that we'll exhaust the
	 * kernel heap space before we ever run out of available physical
	 * memory.  Most checks of the size of the heap_area compare against
	 * tune.t_minarmem, which is the minimum available real memory that we
	 * can have in the system.  However, this is generally fixed at 25 pages
	 * which is so low that it's useless.  In this comparison, we seek to
	 * calculate the total heap-size, and reclaim if more than 3/4ths of the
	 * heap is allocated.  (Or, in the calculation, if less than 1/4th is
	 * free)
	 */ /*
	 * If zio data pages are being allocated out of a separate heap segment,
	 * then enforce that the size of available vmem for this arena remains
	 * above about 1/16th free.
	 *
	 * Note: The 1/16th arena free requirement was put in place
	 * to aggressively evict memory from the arc in order to avoid
	 * memory fragmentation issues.
	 */ /*
	 * Above limits know nothing about real level of KVA fragmentation.
	 * Start aggressive reclamation if too little sequential KVA left.
	 */ /* _KERNEL */ /* Every 100 calls, free a small amount */ /* _KERNEL */