1eda14cbcSMatt Macy /* 2eda14cbcSMatt Macy * CDDL HEADER START 3eda14cbcSMatt Macy * 4eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7eda14cbcSMatt Macy * 8eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9271171e0SMartin Matuska * or https://opensource.org/licenses/CDDL-1.0. 10eda14cbcSMatt Macy * See the License for the specific language governing permissions 11eda14cbcSMatt Macy * and limitations under the License. 12eda14cbcSMatt Macy * 13eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18eda14cbcSMatt Macy * 19eda14cbcSMatt Macy * CDDL HEADER END 20eda14cbcSMatt Macy */ 21eda14cbcSMatt Macy 22eda14cbcSMatt Macy #include <sys/spa.h> 23eda14cbcSMatt Macy #include <sys/zio.h> 24eda14cbcSMatt Macy #include <sys/spa_impl.h> 25eda14cbcSMatt Macy #include <sys/counter.h> 26eda14cbcSMatt Macy #include <sys/zio_compress.h> 27eda14cbcSMatt Macy #include <sys/zio_checksum.h> 28eda14cbcSMatt Macy #include <sys/zfs_context.h> 29eda14cbcSMatt Macy #include <sys/arc.h> 30c7046f76SMartin Matuska #include <sys/arc_os.h> 31eda14cbcSMatt Macy #include <sys/zfs_refcount.h> 32eda14cbcSMatt Macy #include <sys/vdev.h> 33eda14cbcSMatt Macy #include <sys/vdev_trim.h> 34eda14cbcSMatt Macy #include <sys/vdev_impl.h> 35eda14cbcSMatt Macy #include <sys/dsl_pool.h> 36eda14cbcSMatt Macy #include <sys/zio_checksum.h> 37eda14cbcSMatt Macy #include <sys/multilist.h> 38eda14cbcSMatt Macy #include <sys/abd.h> 39eda14cbcSMatt Macy #include <sys/zil.h> 40eda14cbcSMatt Macy #include <sys/fm/fs/zfs.h> 41eda14cbcSMatt Macy #include <sys/eventhandler.h> 42eda14cbcSMatt Macy #include <sys/callb.h> 43eda14cbcSMatt Macy #include <sys/kstat.h> 44eda14cbcSMatt Macy #include <sys/zthr.h> 45eda14cbcSMatt Macy #include <zfs_fletcher.h> 46eda14cbcSMatt Macy #include <sys/arc_impl.h> 47eda14cbcSMatt Macy #include <sys/sdt.h> 48eda14cbcSMatt Macy #include <sys/aggsum.h> 49eda14cbcSMatt Macy #include <sys/vnode.h> 50eda14cbcSMatt Macy #include <cityhash.h> 51eda14cbcSMatt Macy #include <machine/vmparam.h> 52eda14cbcSMatt Macy #include <sys/vm.h> 53eda14cbcSMatt Macy #include <sys/vmmeter.h> 54eda14cbcSMatt Macy 55eda14cbcSMatt Macy extern struct vfsops zfs_vfsops; 56eda14cbcSMatt Macy 57eda14cbcSMatt Macy uint_t zfs_arc_free_target = 0; 58eda14cbcSMatt Macy 59eda14cbcSMatt Macy static void 60eda14cbcSMatt Macy arc_free_target_init(void *unused __unused) 61eda14cbcSMatt Macy { 62eda14cbcSMatt Macy zfs_arc_free_target = vm_cnt.v_free_target; 63eda14cbcSMatt Macy } 64eda14cbcSMatt Macy SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, 65eda14cbcSMatt Macy arc_free_target_init, NULL); 66eda14cbcSMatt Macy 67eda14cbcSMatt Macy /* 68eda14cbcSMatt Macy * We don't have a tunable for arc_free_target due to the dependency on 69eda14cbcSMatt Macy * pagedaemon initialisation. 70eda14cbcSMatt Macy */ 71c7046f76SMartin Matuska ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, free_target, 72c7046f76SMartin Matuska param_set_arc_free_target, 0, CTLFLAG_RW, 73eda14cbcSMatt Macy "Desired number of free pages below which ARC triggers reclaim"); 74c7046f76SMartin Matuska ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, no_grow_shift, 75c7046f76SMartin Matuska param_set_arc_no_grow_shift, 0, ZMOD_RW, 76c7046f76SMartin Matuska "log2(fraction of ARC which must be free to allow growing)"); 77eda14cbcSMatt Macy 78eda14cbcSMatt Macy int64_t 79eda14cbcSMatt Macy arc_available_memory(void) 80eda14cbcSMatt Macy { 81eda14cbcSMatt Macy int64_t lowest = INT64_MAX; 82eda14cbcSMatt Macy int64_t n __unused; 83eda14cbcSMatt Macy 84eda14cbcSMatt Macy /* 85eda14cbcSMatt Macy * Cooperate with pagedaemon when it's time for it to scan 86eda14cbcSMatt Macy * and reclaim some pages. 87eda14cbcSMatt Macy */ 88eda14cbcSMatt Macy n = PAGESIZE * ((int64_t)freemem - zfs_arc_free_target); 89eda14cbcSMatt Macy if (n < lowest) { 90eda14cbcSMatt Macy lowest = n; 91eda14cbcSMatt Macy } 924c053c17SBojan Novković #if !defined(UMA_MD_SMALL_ALLOC) && !defined(UMA_USE_DMAP) 93eda14cbcSMatt Macy /* 9475e1fea6SMartin Matuska * If we're on a platform without a direct map, it's possible that we'll 9575e1fea6SMartin Matuska * exhaust the kernel heap space before we ever run out of available 9675e1fea6SMartin Matuska * physical memory. Most checks of the size of the heap_area compare 9775e1fea6SMartin Matuska * against tune.t_minarmem, which is the minimum available real memory 9875e1fea6SMartin Matuska * that we can have in the system. However, this is generally fixed at 9975e1fea6SMartin Matuska * 25 pages which is so low that it's useless. In this comparison, we 10075e1fea6SMartin Matuska * seek to calculate the total heap-size, and reclaim if more than 10175e1fea6SMartin Matuska * 3/4ths of the heap is allocated. (Or, in the calculation, if less 10275e1fea6SMartin Matuska * than 1/4th is free) 103eda14cbcSMatt Macy */ 104eda14cbcSMatt Macy n = uma_avail() - (long)(uma_limit() / 4); 105eda14cbcSMatt Macy if (n < lowest) { 106eda14cbcSMatt Macy lowest = n; 107eda14cbcSMatt Macy } 108eda14cbcSMatt Macy #endif 109eda14cbcSMatt Macy 110eda14cbcSMatt Macy DTRACE_PROBE1(arc__available_memory, int64_t, lowest); 111eda14cbcSMatt Macy return (lowest); 112eda14cbcSMatt Macy } 113eda14cbcSMatt Macy 114eda14cbcSMatt Macy /* 115eda14cbcSMatt Macy * Return a default max arc size based on the amount of physical memory. 116eda14cbcSMatt Macy */ 117eda14cbcSMatt Macy uint64_t 118eda14cbcSMatt Macy arc_default_max(uint64_t min, uint64_t allmem) 119eda14cbcSMatt Macy { 120eda14cbcSMatt Macy uint64_t size; 121eda14cbcSMatt Macy 122eda14cbcSMatt Macy if (allmem >= 1 << 30) 123eda14cbcSMatt Macy size = allmem - (1 << 30); 124eda14cbcSMatt Macy else 125eda14cbcSMatt Macy size = min; 126eda14cbcSMatt Macy return (MAX(allmem * 5 / 8, size)); 127eda14cbcSMatt Macy } 128eda14cbcSMatt Macy 129eda14cbcSMatt Macy uint64_t 130eda14cbcSMatt Macy arc_all_memory(void) 131eda14cbcSMatt Macy { 132eda14cbcSMatt Macy return (ptob(physmem)); 133eda14cbcSMatt Macy } 134eda14cbcSMatt Macy 135eda14cbcSMatt Macy int 136eda14cbcSMatt Macy arc_memory_throttle(spa_t *spa, uint64_t reserve, uint64_t txg) 137eda14cbcSMatt Macy { 138eda14cbcSMatt Macy return (0); 139eda14cbcSMatt Macy } 140eda14cbcSMatt Macy 141eda14cbcSMatt Macy uint64_t 142eda14cbcSMatt Macy arc_free_memory(void) 143eda14cbcSMatt Macy { 144eda14cbcSMatt Macy return (ptob(freemem)); 145eda14cbcSMatt Macy } 146eda14cbcSMatt Macy 147eda14cbcSMatt Macy static eventhandler_tag arc_event_lowmem = NULL; 148eda14cbcSMatt Macy 149eda14cbcSMatt Macy static void 150eda14cbcSMatt Macy arc_lowmem(void *arg __unused, int howto __unused) 151eda14cbcSMatt Macy { 152*ce4dcb97SMartin Matuska int64_t can_free, free_memory, to_free; 153eda14cbcSMatt Macy 154eda14cbcSMatt Macy arc_no_grow = B_TRUE; 155eda14cbcSMatt Macy arc_warm = B_TRUE; 156eda14cbcSMatt Macy arc_growtime = gethrtime() + SEC2NSEC(arc_grow_retry); 157*ce4dcb97SMartin Matuska 158eda14cbcSMatt Macy free_memory = arc_available_memory(); 159*ce4dcb97SMartin Matuska can_free = arc_c - arc_c_min; 160*ce4dcb97SMartin Matuska to_free = (MAX(can_free, 0) >> arc_shrink_shift) - MIN(free_memory, 0); 161eda14cbcSMatt Macy DTRACE_PROBE2(arc__needfree, int64_t, free_memory, int64_t, to_free); 162*ce4dcb97SMartin Matuska to_free = arc_reduce_target_size(to_free); 163eda14cbcSMatt Macy 164eda14cbcSMatt Macy /* 165eda14cbcSMatt Macy * It is unsafe to block here in arbitrary threads, because we can come 166eda14cbcSMatt Macy * here from ARC itself and may hold ARC locks and thus risk a deadlock 167eda14cbcSMatt Macy * with ARC reclaim thread. 168eda14cbcSMatt Macy */ 169*ce4dcb97SMartin Matuska if (curproc == pageproc) { 170*ce4dcb97SMartin Matuska arc_wait_for_eviction(to_free, B_FALSE, B_FALSE); 171*ce4dcb97SMartin Matuska ARCSTAT_BUMP(arcstat_memory_indirect_count); 172*ce4dcb97SMartin Matuska } else { 173*ce4dcb97SMartin Matuska ARCSTAT_BUMP(arcstat_memory_direct_count); 174*ce4dcb97SMartin Matuska } 175eda14cbcSMatt Macy } 176eda14cbcSMatt Macy 177eda14cbcSMatt Macy void 178eda14cbcSMatt Macy arc_lowmem_init(void) 179eda14cbcSMatt Macy { 180eda14cbcSMatt Macy arc_event_lowmem = EVENTHANDLER_REGISTER(vm_lowmem, arc_lowmem, NULL, 181eda14cbcSMatt Macy EVENTHANDLER_PRI_FIRST); 182eda14cbcSMatt Macy } 183eda14cbcSMatt Macy 184eda14cbcSMatt Macy void 185eda14cbcSMatt Macy arc_lowmem_fini(void) 186eda14cbcSMatt Macy { 187eda14cbcSMatt Macy if (arc_event_lowmem != NULL) 188eda14cbcSMatt Macy EVENTHANDLER_DEREGISTER(vm_lowmem, arc_event_lowmem); 189eda14cbcSMatt Macy } 1907877fdebSMatt Macy 1917877fdebSMatt Macy void 1927877fdebSMatt Macy arc_register_hotplug(void) 1937877fdebSMatt Macy { 1947877fdebSMatt Macy } 1957877fdebSMatt Macy 1967877fdebSMatt Macy void 1977877fdebSMatt Macy arc_unregister_hotplug(void) 1987877fdebSMatt Macy { 1997877fdebSMatt Macy } 200