Lines 193-201
extern int zfs_prefetch_disable;
Link Here
|
193 |
*/ |
193 |
*/ |
194 |
static boolean_t arc_warm; |
194 |
static boolean_t arc_warm; |
195 |
|
195 |
|
196 |
/* |
|
|
197 |
* These tunables are for performance analysis. |
198 |
*/ |
199 |
uint64_t zfs_arc_max; |
196 |
uint64_t zfs_arc_max; |
200 |
uint64_t zfs_arc_min; |
197 |
uint64_t zfs_arc_min; |
201 |
uint64_t zfs_arc_meta_limit = 0; |
198 |
uint64_t zfs_arc_meta_limit = 0; |
Lines 203-209
int zfs_arc_grow_retry = 0;
Link Here
|
203 |
int zfs_arc_shrink_shift = 0; |
200 |
int zfs_arc_shrink_shift = 0; |
204 |
int zfs_arc_p_min_shift = 0; |
201 |
int zfs_arc_p_min_shift = 0; |
205 |
int zfs_disable_dup_eviction = 0; |
202 |
int zfs_disable_dup_eviction = 0; |
|
|
203 |
u_int zfs_arc_free_target = (1 << 19); /* default before pagedaemon init only */ |
206 |
|
204 |
|
|
|
205 |
static int sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS); |
206 |
|
207 |
#ifdef _KERNEL |
208 |
static void |
209 |
arc_free_target_init(void *unused __unused) |
210 |
{ |
211 |
|
212 |
zfs_arc_free_target = cnt.v_free_reserved + cnt.v_cache_min; |
213 |
} |
214 |
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, |
215 |
arc_free_target_init, NULL); |
216 |
|
207 |
TUNABLE_QUAD("vfs.zfs.arc_max", &zfs_arc_max); |
217 |
TUNABLE_QUAD("vfs.zfs.arc_max", &zfs_arc_max); |
208 |
TUNABLE_QUAD("vfs.zfs.arc_min", &zfs_arc_min); |
218 |
TUNABLE_QUAD("vfs.zfs.arc_min", &zfs_arc_min); |
209 |
TUNABLE_QUAD("vfs.zfs.arc_meta_limit", &zfs_arc_meta_limit); |
219 |
TUNABLE_QUAD("vfs.zfs.arc_meta_limit", &zfs_arc_meta_limit); |
Lines 214-219
SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_min, CTLFLAG_
Link Here
|
214 |
"Minimum ARC size"); |
224 |
"Minimum ARC size"); |
215 |
|
225 |
|
216 |
/* |
226 |
/* |
|
|
227 |
* We don't have a tunable for arc_free_target due to the dependency on |
228 |
* pagedaemon initialisation. |
229 |
*/ |
230 |
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_free_target, |
231 |
CTLTYPE_UINT | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof(u_int), |
232 |
sysctl_vfs_zfs_arc_free_target, "IU", |
233 |
"Desired number of free pages below which ARC triggers reclaim"); |
234 |
|
235 |
static int |
236 |
sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS) |
237 |
{ |
238 |
u_int val; |
239 |
int err; |
240 |
|
241 |
val = zfs_arc_free_target; |
242 |
err = sysctl_handle_int(oidp, &val, 0, req); |
243 |
if (err != 0 || req->newptr == NULL) |
244 |
return (err); |
245 |
|
246 |
if (val < minfree) |
247 |
return (EINVAL); |
248 |
if (val > cnt.v_page_count) |
249 |
return (EINVAL); |
250 |
|
251 |
zfs_arc_free_target = val; |
252 |
|
253 |
return (0); |
254 |
} |
255 |
#endif |
256 |
|
257 |
/* |
217 |
* Note that buffers can be in one of 6 states: |
258 |
* Note that buffers can be in one of 6 states: |
218 |
* ARC_anon - anonymous (discussed below) |
259 |
* ARC_anon - anonymous (discussed below) |
219 |
* ARC_mru - recently used, currently cached |
260 |
* ARC_mru - recently used, currently cached |
Lines 2405-2413
arc_flush(spa_t *spa)
Link Here
|
2405 |
void |
2446 |
void |
2406 |
arc_shrink(void) |
2447 |
arc_shrink(void) |
2407 |
{ |
2448 |
{ |
|
|
2449 |
|
2408 |
if (arc_c > arc_c_min) { |
2450 |
if (arc_c > arc_c_min) { |
2409 |
uint64_t to_free; |
2451 |
uint64_t to_free; |
2410 |
|
2452 |
|
|
|
2453 |
DTRACE_PROBE2(arc__shrink, uint64_t, arc_c, uint64_t, |
2454 |
arc_c_min); |
2411 |
#ifdef _KERNEL |
2455 |
#ifdef _KERNEL |
2412 |
to_free = arc_c >> arc_shrink_shift; |
2456 |
to_free = arc_c >> arc_shrink_shift; |
2413 |
#else |
2457 |
#else |
Lines 2427-2434
arc_shrink(void)
Link Here
|
2427 |
ASSERT((int64_t)arc_p >= 0); |
2471 |
ASSERT((int64_t)arc_p >= 0); |
2428 |
} |
2472 |
} |
2429 |
|
2473 |
|
2430 |
if (arc_size > arc_c) |
2474 |
if (arc_size > arc_c) { |
|
|
2475 |
DTRACE_PROBE2(arc__shrink_adjust, uint64_t, arc_size, |
2476 |
uint64_t, arc_c); |
2431 |
arc_adjust(); |
2477 |
arc_adjust(); |
|
|
2478 |
} |
2432 |
} |
2479 |
} |
2433 |
|
2480 |
|
2434 |
static int needfree = 0; |
2481 |
static int needfree = 0; |
Lines 2439-2453
arc_reclaim_needed(void)
Link Here
|
2439 |
|
2486 |
|
2440 |
#ifdef _KERNEL |
2487 |
#ifdef _KERNEL |
2441 |
|
2488 |
|
2442 |
if (needfree) |
2489 |
if (needfree) { |
|
|
2490 |
DTRACE_PROBE(arc__reclaim_needfree); |
2443 |
return (1); |
2491 |
return (1); |
|
|
2492 |
} |
2444 |
|
2493 |
|
2445 |
/* |
2494 |
/* |
2446 |
* Cooperate with pagedaemon when it's time for it to scan |
2495 |
* Cooperate with pagedaemon when it's time for it to scan |
2447 |
* and reclaim some pages. |
2496 |
* and reclaim some pages. |
2448 |
*/ |
2497 |
*/ |
2449 |
if (vm_paging_needed()) |
2498 |
if (freemem < zfs_arc_free_target) { |
|
|
2499 |
DTRACE_PROBE2(arc__reclaim_freetarget, uint64_t, |
2500 |
freemem, uint64_t, zfs_arc_free_target); |
2450 |
return (1); |
2501 |
return (1); |
|
|
2502 |
} |
2451 |
|
2503 |
|
2452 |
#ifdef sun |
2504 |
#ifdef sun |
2453 |
/* |
2505 |
/* |
Lines 2487-2505
arc_reclaim_needed(void)
Link Here
|
2487 |
* heap is allocated. (Or, in the calculation, if less than 1/4th is |
2539 |
* heap is allocated. (Or, in the calculation, if less than 1/4th is |
2488 |
* free) |
2540 |
* free) |
2489 |
*/ |
2541 |
*/ |
2490 |
if (btop(vmem_size(heap_arena, VMEM_FREE)) < |
2542 |
if (vmem_size(heap_arena, VMEM_FREE) < |
2491 |
(btop(vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)) >> 2)) |
2543 |
(vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC) >> 2)) |
2492 |
return (1); |
2544 |
return (1); |
2493 |
#endif |
2545 |
#endif |
|
|
2546 |
|
2547 |
/* |
2548 |
* If zio data pages are being allocated out of a separate heap segment, |
2549 |
* then enforce that the size of available vmem for this arena remains |
2550 |
* above about 1/16th free. |
2551 |
* |
2552 |
* Note: The 1/16th arena free requirement was put in place |
2553 |
* to aggressively evict memory from the arc in order to avoid |
2554 |
* memory fragmentation issues. |
2555 |
*/ |
2556 |
if (zio_arena != NULL && |
2557 |
vmem_size(zio_arena, VMEM_FREE) < |
2558 |
(vmem_size(zio_arena, VMEM_ALLOC) >> 4)) |
2559 |
return (1); |
2494 |
#else /* !sun */ |
2560 |
#else /* !sun */ |
2495 |
if (kmem_used() > (kmem_size() * 3) / 4) |
2561 |
#ifndef UMA_MD_SMALL_ALLOC |
|
|
2562 |
/* i386 has KVA limits that the raw page counts above don't consider */ |
2563 |
if (kmem_map_used() > (kmem_size() * 3) / 4) { |
2564 |
DTRACE_PROBE2(arc__reclaim_used, uint64_t, |
2565 |
kmem_map_used(), uint64_t, (kmem_size() * 3) / 4); |
2496 |
return (1); |
2566 |
return (1); |
|
|
2567 |
} |
2568 |
#endif |
2497 |
#endif /* sun */ |
2569 |
#endif /* sun */ |
2498 |
|
2570 |
|
2499 |
#else |
2571 |
#else /* !_KERNEL */ |
2500 |
if (spa_get_random(100) == 0) |
2572 |
if (spa_get_random(100) == 0) |
2501 |
return (1); |
2573 |
return (1); |
2502 |
#endif |
2574 |
#endif /* _KERNEL */ |
|
|
2575 |
DTRACE_PROBE(arc__reclaim_no); |
2576 |
|
2503 |
return (0); |
2577 |
return (0); |
2504 |
} |
2578 |
} |
2505 |
|
2579 |
|
Lines 2697-2716
arc_evict_needed(arc_buf_contents_t type)
Link Here
|
2697 |
if (type == ARC_BUFC_METADATA && arc_meta_used >= arc_meta_limit) |
2771 |
if (type == ARC_BUFC_METADATA && arc_meta_used >= arc_meta_limit) |
2698 |
return (1); |
2772 |
return (1); |
2699 |
|
2773 |
|
2700 |
#ifdef sun |
|
|
2701 |
#ifdef _KERNEL |
2702 |
/* |
2703 |
* If zio data pages are being allocated out of a separate heap segment, |
2704 |
* then enforce that the size of available vmem for this area remains |
2705 |
* above about 1/32nd free. |
2706 |
*/ |
2707 |
if (type == ARC_BUFC_DATA && zio_arena != NULL && |
2708 |
vmem_size(zio_arena, VMEM_FREE) < |
2709 |
(vmem_size(zio_arena, VMEM_ALLOC) >> 5)) |
2710 |
return (1); |
2711 |
#endif |
2712 |
#endif /* sun */ |
2713 |
|
2714 |
if (arc_reclaim_needed()) |
2774 |
if (arc_reclaim_needed()) |
2715 |
return (1); |
2775 |
return (1); |
2716 |
|
2776 |
|
Lines 3876-3883
static int
Link Here
|
3876 |
arc_memory_throttle(uint64_t reserve, uint64_t txg) |
3936 |
arc_memory_throttle(uint64_t reserve, uint64_t txg) |
3877 |
{ |
3937 |
{ |
3878 |
#ifdef _KERNEL |
3938 |
#ifdef _KERNEL |
3879 |
uint64_t available_memory = |
3939 |
uint64_t available_memory = ptob(freemem); |
3880 |
ptoa((uintmax_t)cnt.v_free_count + cnt.v_cache_count); |
|
|
3881 |
static uint64_t page_load = 0; |
3940 |
static uint64_t page_load = 0; |
3882 |
static uint64_t last_txg = 0; |
3941 |
static uint64_t last_txg = 0; |
3883 |
|
3942 |
|
Lines 3886-3895
arc_memory_throttle(uint64_t reserve, uint64_t txg
Link Here
|
3886 |
available_memory = |
3945 |
available_memory = |
3887 |
MIN(available_memory, vmem_size(heap_arena, VMEM_FREE)); |
3946 |
MIN(available_memory, vmem_size(heap_arena, VMEM_FREE)); |
3888 |
#endif |
3947 |
#endif |
|
|
3948 |
#else /* sun */ |
3949 |
#ifndef UMA_MD_SMALL_ALLOC |
3950 |
available_memory = MIN(available_memory, kmem_map_free()); |
3951 |
#endif |
3889 |
#endif /* sun */ |
3952 |
#endif /* sun */ |
3890 |
|
3953 |
|
3891 |
if (cnt.v_free_count + cnt.v_cache_count > |
3954 |
if (freemem > (uint64_t)physmem * arc_lotsfree_percent / 100) |
3892 |
(uint64_t)physmem * arc_lotsfree_percent / 100) |
|
|
3893 |
return (0); |
3955 |
return (0); |
3894 |
|
3956 |
|
3895 |
if (txg > last_txg) { |
3957 |
if (txg > last_txg) { |
Lines 3902-3908
arc_memory_throttle(uint64_t reserve, uint64_t txg
Link Here
|
3902 |
* continue to let page writes occur as quickly as possible. |
3964 |
* continue to let page writes occur as quickly as possible. |
3903 |
*/ |
3965 |
*/ |
3904 |
if (curproc == pageproc) { |
3966 |
if (curproc == pageproc) { |
3905 |
if (page_load > available_memory / 4) |
3967 |
if (page_load > MAX(ptob(minfree), available_memory) / 4) |
3906 |
return (SET_ERROR(ERESTART)); |
3968 |
return (SET_ERROR(ERESTART)); |
3907 |
/* Note: reserve is inflated, so we deflate */ |
3969 |
/* Note: reserve is inflated, so we deflate */ |
3908 |
page_load += reserve / 8; |
3970 |
page_load += reserve / 8; |