|
Lines 237-243
int zfs_arc_p_min_shift = 0;
Link Here
|
| 237 |
int zfs_disable_dup_eviction = 0; |
237 |
int zfs_disable_dup_eviction = 0; |
| 238 |
uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */ |
238 |
uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */ |
| 239 |
u_int zfs_arc_free_target = 0; |
239 |
u_int zfs_arc_free_target = 0; |
|
|
240 |
u_int zfs_arc_wakeup_pager = 0; |
| 241 |
u_int zfs_arc_wakeup_delay = 500; |
| 242 |
int zfs_arc_last_slab = 0; |
| 240 |
|
243 |
|
|
|
244 |
#define WAKE_PAGER |
| 245 |
#ifdef WAKE_PAGER |
| 246 |
#define WAKE_PAGER_CONSTANT 10 / 9 /* Pager wakeup threshold */ |
| 247 |
static int arc_init_done = 0; /* After arc_warm is valid */ |
| 248 |
extern void pagedaemon_wakeup(void); |
| 249 |
#endif |
| 250 |
|
| 241 |
/* Absolute min for arc min / max is 16MB. */ |
251 |
/* Absolute min for arc min / max is 16MB. */ |
| 242 |
static uint64_t arc_abs_min = 16 << 20; |
252 |
static uint64_t arc_abs_min = 16 << 20; |
| 243 |
|
253 |
|
|
Lines 251-257
static void
Link Here
|
| 251 |
arc_free_target_init(void *unused __unused) |
261 |
arc_free_target_init(void *unused __unused) |
| 252 |
{ |
262 |
{ |
| 253 |
|
263 |
|
| 254 |
zfs_arc_free_target = vm_pageout_wakeup_thresh; |
264 |
zfs_arc_free_target = vm_pageout_wakeup_thresh + (vm_pageout_wakeup_thresh / 20); |
|
|
265 |
zfs_arc_wakeup_pager = vm_pageout_wakeup_thresh * WAKE_PAGER_CONSTANT; |
| 255 |
} |
266 |
} |
| 256 |
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, |
267 |
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, |
| 257 |
arc_free_target_init, NULL); |
268 |
arc_free_target_init, NULL); |
|
Lines 3476-3481
int64_t arc_pages_pp_reserve = 64;
Link Here
|
| 3476 |
int64_t arc_swapfs_reserve = 64; |
3487 |
int64_t arc_swapfs_reserve = 64; |
| 3477 |
|
3488 |
|
| 3478 |
/* |
3489 |
/* |
|
|
3490 |
* Declare file-local static for event processor bypass |
| 3491 |
*/ |
| 3492 |
static unsigned int arc_no_wake_event = 0; |
| 3493 |
|
| 3494 |
/* |
| 3479 |
* Return the amount of memory that can be consumed before reclaim will be |
3495 |
* Return the amount of memory that can be consumed before reclaim will be |
| 3480 |
* needed. Positive if there is sufficient free memory, negative indicates |
3496 |
* needed. Positive if there is sufficient free memory, negative indicates |
| 3481 |
* the amount of memory that needs to be freed up. |
3497 |
* the amount of memory that needs to be freed up. |
|
Lines 3488-3493
arc_available_memory(void)
Link Here
|
| 3488 |
free_memory_reason_t r = FMR_UNKNOWN; |
3504 |
free_memory_reason_t r = FMR_UNKNOWN; |
| 3489 |
|
3505 |
|
| 3490 |
#ifdef _KERNEL |
3506 |
#ifdef _KERNEL |
|
|
3507 |
#ifdef WAKE_PAGER |
| 3508 |
sbintime_t now; |
| 3509 |
static sbintime_t last_pagedaemon_wake = 0; |
| 3510 |
void call_arc_kmem_reap(int); |
| 3511 |
#endif /* WAKE_PAGER */ |
| 3512 |
|
| 3491 |
if (needfree > 0) { |
3513 |
if (needfree > 0) { |
| 3492 |
n = PAGESIZE * (-needfree); |
3514 |
n = PAGESIZE * (-needfree); |
| 3493 |
if (n < lowest) { |
3515 |
if (n < lowest) { |
|
Lines 3495-3500
arc_available_memory(void)
Link Here
|
| 3495 |
r = FMR_NEEDFREE; |
3517 |
r = FMR_NEEDFREE; |
| 3496 |
} |
3518 |
} |
| 3497 |
} |
3519 |
} |
|
|
3520 |
#ifdef WAKE_PAGER |
| 3521 |
/* |
| 3522 |
* When arc is initialized, perform the following: |
| 3523 |
* |
| 3524 |
* 1. If we are in the "memory is low enough to wake the pager" zone, |
| 3525 |
* reap the kernel UMA caches once per wakeup_delay period 500ms default) |
| 3526 |
* AND wake the pager up (so it can demote pages from inactive to cache to |
| 3527 |
* ultimately the free list.) |
| 3528 |
* |
| 3529 |
* 2. If we're below VM's free_target in free RAM reap *one* UMA zone per |
| 3530 |
* time period (500ms). |
| 3531 |
* |
| 3532 |
*/ |
| 3533 |
if (arc_init_done) { |
| 3534 |
now = getsbinuptime(); |
| 3535 |
if ((now - last_pagedaemon_wake) / SBT_1MS > zfs_arc_wakeup_delay) { |
| 3536 |
last_pagedaemon_wake = now; |
| 3537 |
arc_no_wake_event++; /* Set bypass flag for ARC */ |
| 3538 |
if ( ( ((int64_t) freemem - zfs_arc_wakeup_pager) < 0) && (arc_warm == B_TRUE) ) { |
| 3539 |
call_arc_kmem_reap(0); /* Reap caches if we're close */ |
| 3540 |
DTRACE_PROBE(arc__wake_pagedaemon); |
| 3541 |
(void) pagedaemon_wakeup(); /* Wake the pager */ |
| 3542 |
} else { |
| 3543 |
if ( ((int64_t) freemem - vm_cnt.v_free_target) < 0) { |
| 3544 |
call_arc_kmem_reap(1); /* Reap one cache if lots of memory */ |
| 3545 |
DTRACE_PROBE2(arc__reap_one, int, zfs_arc_last_slab, int, SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT); |
| 3546 |
} |
| 3547 |
} |
| 3548 |
} |
| 3549 |
} |
| 3550 |
#endif /* WAKE_PAGER */ |
| 3498 |
|
3551 |
|
| 3499 |
/* |
3552 |
/* |
| 3500 |
* Cooperate with pagedaemon when it's time for it to scan |
3553 |
* Cooperate with pagedaemon when it's time for it to scan |
|
Lines 3633-3644
extern kmem_cache_t *zio_buf_cache[];
Link Here
|
| 3633 |
extern kmem_cache_t *zio_data_buf_cache[]; |
3686 |
extern kmem_cache_t *zio_data_buf_cache[]; |
| 3634 |
extern kmem_cache_t *range_seg_cache; |
3687 |
extern kmem_cache_t *range_seg_cache; |
| 3635 |
|
3688 |
|
|
|
3689 |
/* |
| 3690 |
* Pass a flag to this routine; if zero, then reap all. If not then reap |
| 3691 |
* one slab on a rotating basis. This allows a low-rate call to be used |
| 3692 |
* on a routine, maintenance basis even when not low on RAM so we don't have |
| 3693 |
* huge amounts of RAM out in unused UMA allocations. |
| 3694 |
*/ |
| 3636 |
static __noinline void |
3695 |
static __noinline void |
| 3637 |
arc_kmem_reap_now(void) |
3696 |
arc_kmem_reap_now(flag) |
|
|
3697 |
int flag; |
| 3638 |
{ |
3698 |
{ |
| 3639 |
size_t i; |
3699 |
size_t i; |
| 3640 |
kmem_cache_t *prev_cache = NULL; |
3700 |
kmem_cache_t *prev_cache = NULL; |
| 3641 |
kmem_cache_t *prev_data_cache = NULL; |
3701 |
kmem_cache_t *prev_data_cache = NULL; |
|
|
3702 |
int arc_cache_reaped = 0; |
| 3703 |
int arc_data_cache_reaped = 0; |
| 3704 |
int reset_last_slab = 0; |
| 3642 |
|
3705 |
|
| 3643 |
DTRACE_PROBE(arc__kmem_reap_start); |
3706 |
DTRACE_PROBE(arc__kmem_reap_start); |
| 3644 |
#ifdef _KERNEL |
3707 |
#ifdef _KERNEL |
|
Lines 3660-3672
static __noinline void
Link Here
|
| 3660 |
for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) { |
3723 |
for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) { |
| 3661 |
if (zio_buf_cache[i] != prev_cache) { |
3724 |
if (zio_buf_cache[i] != prev_cache) { |
| 3662 |
prev_cache = zio_buf_cache[i]; |
3725 |
prev_cache = zio_buf_cache[i]; |
| 3663 |
kmem_cache_reap_now(zio_buf_cache[i]); |
3726 |
if ((!flag) || ((i > zfs_arc_last_slab) && (!arc_cache_reaped))) { |
|
|
3727 |
kmem_cache_reap_now(zio_buf_cache[i]); |
| 3728 |
arc_cache_reaped++; |
| 3729 |
} |
| 3664 |
} |
3730 |
} |
| 3665 |
if (zio_data_buf_cache[i] != prev_data_cache) { |
3731 |
if (zio_data_buf_cache[i] != prev_data_cache) { |
| 3666 |
prev_data_cache = zio_data_buf_cache[i]; |
3732 |
prev_data_cache = zio_data_buf_cache[i]; |
| 3667 |
kmem_cache_reap_now(zio_data_buf_cache[i]); |
3733 |
if ((!flag) || ((i > zfs_arc_last_slab) && (!arc_data_cache_reaped))) { |
|
|
3734 |
kmem_cache_reap_now(zio_data_buf_cache[i]); |
| 3735 |
arc_data_cache_reaped++; |
| 3736 |
} |
| 3668 |
} |
3737 |
} |
|
|
3738 |
if (flag && (!reset_last_slab) && (arc_cache_reaped || arc_data_cache_reaped)) { |
| 3739 |
reset_last_slab = i; |
| 3740 |
} |
| 3669 |
} |
3741 |
} |
|
|
3742 |
if (reset_last_slab) { |
| 3743 |
zfs_arc_last_slab = reset_last_slab; |
| 3744 |
} |
| 3745 |
if ((!arc_cache_reaped) && (!arc_data_cache_reaped) && (flag)) { /* Found nothing to reap on one-pass */ |
| 3746 |
zfs_arc_last_slab = 0; /* Reset */ |
| 3747 |
} |
| 3670 |
kmem_cache_reap_now(buf_cache); |
3748 |
kmem_cache_reap_now(buf_cache); |
| 3671 |
kmem_cache_reap_now(hdr_full_cache); |
3749 |
kmem_cache_reap_now(hdr_full_cache); |
| 3672 |
kmem_cache_reap_now(hdr_l2only_cache); |
3750 |
kmem_cache_reap_now(hdr_l2only_cache); |
|
Lines 3684-3689
static __noinline void
Link Here
|
| 3684 |
DTRACE_PROBE(arc__kmem_reap_end); |
3762 |
DTRACE_PROBE(arc__kmem_reap_end); |
| 3685 |
} |
3763 |
} |
| 3686 |
|
3764 |
|
|
|
3765 |
void call_arc_kmem_reap(flag) |
| 3766 |
int flag; |
| 3767 |
{ |
| 3768 |
arc_kmem_reap_now(flag); |
| 3769 |
} |
| 3770 |
|
| 3687 |
/* |
3771 |
/* |
| 3688 |
* Threads can block in arc_get_data_buf() waiting for this thread to evict |
3772 |
* Threads can block in arc_get_data_buf() waiting for this thread to evict |
| 3689 |
* enough data and signal them to proceed. When this happens, the threads in |
3773 |
* enough data and signal them to proceed. When this happens, the threads in |
|
Lines 3726-3732
arc_reclaim_thread(void *dummy __unused)
Link Here
|
| 3726 |
*/ |
3810 |
*/ |
| 3727 |
growtime = gethrtime() + SEC2NSEC(arc_grow_retry); |
3811 |
growtime = gethrtime() + SEC2NSEC(arc_grow_retry); |
| 3728 |
|
3812 |
|
| 3729 |
arc_kmem_reap_now(); |
3813 |
arc_kmem_reap_now(0); |
| 3730 |
|
3814 |
|
| 3731 |
/* |
3815 |
/* |
| 3732 |
* If we are still low on memory, shrink the ARC |
3816 |
* If we are still low on memory, shrink the ARC |
|
Lines 5431-5436
static eventhandler_tag arc_event_lowmem = NULL;
Link Here
|
| 5431 |
static void |
5515 |
static void |
| 5432 |
arc_lowmem(void *arg __unused, int howto __unused) |
5516 |
arc_lowmem(void *arg __unused, int howto __unused) |
| 5433 |
{ |
5517 |
{ |
|
|
5518 |
if (arc_no_wake_event) { /* Don't do it if we woke the pager */ |
| 5519 |
arc_no_wake_event = 0; /* Just clear the flag */ |
| 5520 |
return; |
| 5521 |
} |
| 5434 |
|
5522 |
|
| 5435 |
mutex_enter(&arc_reclaim_lock); |
5523 |
mutex_enter(&arc_reclaim_lock); |
| 5436 |
/* XXX: Memory deficit should be passed as argument. */ |
5524 |
/* XXX: Memory deficit should be passed as argument. */ |
|
Lines 5696-5701
arc_init(void)
Link Here
|
| 5696 |
printf(" in /boot/loader.conf.\n"); |
5784 |
printf(" in /boot/loader.conf.\n"); |
| 5697 |
} |
5785 |
} |
| 5698 |
#endif |
5786 |
#endif |
|
|
5787 |
#ifdef WAKE_PAGER |
| 5788 |
arc_init_done++; |
| 5789 |
#endif /* WAKE_PAGER */ |
| 5699 |
} |
5790 |
} |
| 5700 |
|
5791 |
|
| 5701 |
void |
5792 |
void |