1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or https://opensource.org/licenses/CDDL-1.0. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 #include <sys/spa.h> 23 #include <sys/zio.h> 24 #include <sys/spa_impl.h> 25 #include <sys/counter.h> 26 #include <sys/zio_compress.h> 27 #include <sys/zio_checksum.h> 28 #include <sys/zfs_context.h> 29 #include <sys/arc.h> 30 #include <sys/arc_os.h> 31 #include <sys/zfs_refcount.h> 32 #include <sys/vdev.h> 33 #include <sys/vdev_trim.h> 34 #include <sys/vdev_impl.h> 35 #include <sys/dsl_pool.h> 36 #include <sys/zio_checksum.h> 37 #include <sys/multilist.h> 38 #include <sys/abd.h> 39 #include <sys/zil.h> 40 #include <sys/fm/fs/zfs.h> 41 #include <sys/eventhandler.h> 42 #include <sys/callb.h> 43 #include <sys/kstat.h> 44 #include <sys/zthr.h> 45 #include <zfs_fletcher.h> 46 #include <sys/arc_impl.h> 47 #include <sys/sdt.h> 48 #include <sys/aggsum.h> 49 #include <sys/vnode.h> 50 #include <cityhash.h> 51 #include <machine/vmparam.h> 52 #include <sys/vm.h> 53 #include <sys/vmmeter.h> 54 55 #if __FreeBSD_version >= 1300139 56 static struct sx arc_vnlru_lock; 57 static struct vnode *arc_vnlru_marker; 58 #endif 59 60 extern struct vfsops zfs_vfsops; 61 62 uint_t zfs_arc_free_target = 0; 63 64 static void 65 arc_free_target_init(void *unused __unused) 66 { 67 zfs_arc_free_target = vm_cnt.v_free_target; 68 } 69 SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, 70 arc_free_target_init, NULL); 71 72 /* 73 * We don't have a tunable for arc_free_target due to the dependency on 74 * pagedaemon initialisation. 75 */ 76 ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, free_target, 77 param_set_arc_free_target, 0, CTLFLAG_RW, 78 "Desired number of free pages below which ARC triggers reclaim"); 79 ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, no_grow_shift, 80 param_set_arc_no_grow_shift, 0, ZMOD_RW, 81 "log2(fraction of ARC which must be free to allow growing)"); 82 83 int64_t 84 arc_available_memory(void) 85 { 86 int64_t lowest = INT64_MAX; 87 int64_t n __unused; 88 89 /* 90 * Cooperate with pagedaemon when it's time for it to scan 91 * and reclaim some pages. 92 */ 93 n = PAGESIZE * ((int64_t)freemem - zfs_arc_free_target); 94 if (n < lowest) { 95 lowest = n; 96 } 97 #if defined(__i386) || !defined(UMA_MD_SMALL_ALLOC) 98 /* 99 * If we're on an i386 platform, it's possible that we'll exhaust the 100 * kernel heap space before we ever run out of available physical 101 * memory. Most checks of the size of the heap_area compare against 102 * tune.t_minarmem, which is the minimum available real memory that we 103 * can have in the system. However, this is generally fixed at 25 pages 104 * which is so low that it's useless. In this comparison, we seek to 105 * calculate the total heap-size, and reclaim if more than 3/4ths of the 106 * heap is allocated. (Or, in the calculation, if less than 1/4th is 107 * free) 108 */ 109 n = uma_avail() - (long)(uma_limit() / 4); 110 if (n < lowest) { 111 lowest = n; 112 } 113 #endif 114 115 DTRACE_PROBE1(arc__available_memory, int64_t, lowest); 116 return (lowest); 117 } 118 119 /* 120 * Return a default max arc size based on the amount of physical memory. 121 */ 122 uint64_t 123 arc_default_max(uint64_t min, uint64_t allmem) 124 { 125 uint64_t size; 126 127 if (allmem >= 1 << 30) 128 size = allmem - (1 << 30); 129 else 130 size = min; 131 return (MAX(allmem * 5 / 8, size)); 132 } 133 134 /* 135 * Helper function for arc_prune_async() it is responsible for safely 136 * handling the execution of a registered arc_prune_func_t. 137 */ 138 static void 139 arc_prune_task(void *arg) 140 { 141 uint64_t nr_scan = (uintptr_t)arg; 142 143 #ifndef __ILP32__ 144 if (nr_scan > INT_MAX) 145 nr_scan = INT_MAX; 146 #endif 147 148 #if __FreeBSD_version >= 1300139 149 sx_xlock(&arc_vnlru_lock); 150 vnlru_free_vfsops(nr_scan, &zfs_vfsops, arc_vnlru_marker); 151 sx_xunlock(&arc_vnlru_lock); 152 #else 153 vnlru_free(nr_scan, &zfs_vfsops); 154 #endif 155 } 156 157 /* 158 * Notify registered consumers they must drop holds on a portion of the ARC 159 * buffered they reference. This provides a mechanism to ensure the ARC can 160 * honor the metadata limit and reclaim otherwise pinned ARC buffers. This 161 * is analogous to dnlc_reduce_cache() but more generic. 162 * 163 * This operation is performed asynchronously so it may be safely called 164 * in the context of the arc_reclaim_thread(). A reference is taken here 165 * for each registered arc_prune_t and the arc_prune_task() is responsible 166 * for releasing it once the registered arc_prune_func_t has completed. 167 */ 168 void 169 arc_prune_async(uint64_t adjust) 170 { 171 172 #ifndef __LP64__ 173 if (adjust > UINTPTR_MAX) 174 adjust = UINTPTR_MAX; 175 #endif 176 taskq_dispatch(arc_prune_taskq, arc_prune_task, 177 (void *)(intptr_t)adjust, TQ_SLEEP); 178 ARCSTAT_BUMP(arcstat_prune); 179 } 180 181 uint64_t 182 arc_all_memory(void) 183 { 184 return (ptob(physmem)); 185 } 186 187 int 188 arc_memory_throttle(spa_t *spa, uint64_t reserve, uint64_t txg) 189 { 190 return (0); 191 } 192 193 uint64_t 194 arc_free_memory(void) 195 { 196 return (ptob(freemem)); 197 } 198 199 static eventhandler_tag arc_event_lowmem = NULL; 200 201 static void 202 arc_lowmem(void *arg __unused, int howto __unused) 203 { 204 int64_t free_memory, to_free; 205 206 arc_no_grow = B_TRUE; 207 arc_warm = B_TRUE; 208 arc_growtime = gethrtime() + SEC2NSEC(arc_grow_retry); 209 free_memory = arc_available_memory(); 210 int64_t can_free = arc_c - arc_c_min; 211 if (can_free <= 0) 212 return; 213 to_free = (can_free >> arc_shrink_shift) - MIN(free_memory, 0); 214 DTRACE_PROBE2(arc__needfree, int64_t, free_memory, int64_t, to_free); 215 arc_reduce_target_size(to_free); 216 217 /* 218 * It is unsafe to block here in arbitrary threads, because we can come 219 * here from ARC itself and may hold ARC locks and thus risk a deadlock 220 * with ARC reclaim thread. 221 */ 222 if (curproc == pageproc) 223 arc_wait_for_eviction(to_free, B_FALSE); 224 } 225 226 void 227 arc_lowmem_init(void) 228 { 229 arc_event_lowmem = EVENTHANDLER_REGISTER(vm_lowmem, arc_lowmem, NULL, 230 EVENTHANDLER_PRI_FIRST); 231 #if __FreeBSD_version >= 1300139 232 arc_vnlru_marker = vnlru_alloc_marker(); 233 sx_init(&arc_vnlru_lock, "arc vnlru lock"); 234 #endif 235 } 236 237 void 238 arc_lowmem_fini(void) 239 { 240 if (arc_event_lowmem != NULL) 241 EVENTHANDLER_DEREGISTER(vm_lowmem, arc_event_lowmem); 242 #if __FreeBSD_version >= 1300139 243 if (arc_vnlru_marker != NULL) { 244 vnlru_free_marker(arc_vnlru_marker); 245 sx_destroy(&arc_vnlru_lock); 246 } 247 #endif 248 } 249 250 void 251 arc_register_hotplug(void) 252 { 253 } 254 255 void 256 arc_unregister_hotplug(void) 257 { 258 } 259