Lines 216-221
Link Here
|
216 |
extern int zfs_prefetch_disable; |
216 |
extern int zfs_prefetch_disable; |
217 |
|
217 |
|
218 |
/* |
218 |
/* |
|
|
219 |
* KD 2015-02-10 |
220 |
* We have to be able to test for UIO use inside the arc allocator. |
221 |
* NOTE: DO NOT MODIFY HERE! |
222 |
*/ |
223 |
extern int zio_use_uma; |
224 |
extern int zfs_dynamic_write_buffer; |
225 |
|
226 |
|
227 |
/* |
219 |
* The arc has filled available memory and has now warmed up. |
228 |
* The arc has filled available memory and has now warmed up. |
220 |
*/ |
229 |
*/ |
221 |
static boolean_t arc_warm; |
230 |
static boolean_t arc_warm; |
Lines 242-248
Link Here
|
242 |
arc_free_target_init(void *unused __unused) |
251 |
arc_free_target_init(void *unused __unused) |
243 |
{ |
252 |
{ |
244 |
|
253 |
|
245 |
zfs_arc_free_target = vm_pageout_wakeup_thresh; |
254 |
zfs_arc_free_target = vm_pageout_wakeup_thresh + ((cnt.v_free_target - vm_pageout_wakeup_thresh) / 2); |
246 |
} |
255 |
} |
247 |
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, |
256 |
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, |
248 |
arc_free_target_init, NULL); |
257 |
arc_free_target_init, NULL); |
Lines 261-267
Link Here
|
261 |
SYSCTL_INT(_vfs_zfs, OID_AUTO, arc_shrink_shift, CTLFLAG_RW, |
270 |
SYSCTL_INT(_vfs_zfs, OID_AUTO, arc_shrink_shift, CTLFLAG_RW, |
262 |
&arc_shrink_shift, 0, |
271 |
&arc_shrink_shift, 0, |
263 |
"log2(fraction of arc to reclaim)"); |
272 |
"log2(fraction of arc to reclaim)"); |
264 |
|
273 |
SYSCTL_INT(_vfs_zfs, OID_AUTO, dynamic_write_buffer, CTLFLAG_RWTUN, |
|
|
274 |
&zfs_dynamic_write_buffer, 0, |
275 |
"Dynamically restrict dirty data when memory is low"); |
265 |
/* |
276 |
/* |
266 |
* We don't have a tunable for arc_free_target due to the dependency on |
277 |
* We don't have a tunable for arc_free_target due to the dependency on |
267 |
* pagedaemon initialisation. |
278 |
* pagedaemon initialisation. |
Lines 3518-3523
Link Here
|
3518 |
extern kmem_cache_t *zio_data_buf_cache[]; |
3529 |
extern kmem_cache_t *zio_data_buf_cache[]; |
3519 |
extern kmem_cache_t *range_seg_cache; |
3530 |
extern kmem_cache_t *range_seg_cache; |
3520 |
|
3531 |
|
|
|
3532 |
static void __used |
3533 |
reap_arc_caches() |
3534 |
{ |
3535 |
size_t i; |
3536 |
kmem_cache_t *prev_cache = NULL; |
3537 |
kmem_cache_t *prev_data_cache = NULL; |
3538 |
|
3539 |
for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) { |
3540 |
if (zio_buf_cache[i] != prev_cache) { |
3541 |
prev_cache = zio_buf_cache[i]; |
3542 |
kmem_cache_reap_now(zio_buf_cache[i]); |
3543 |
} |
3544 |
if (zio_data_buf_cache[i] != prev_data_cache) { |
3545 |
prev_data_cache = zio_data_buf_cache[i]; |
3546 |
kmem_cache_reap_now(zio_data_buf_cache[i]); |
3547 |
} |
3548 |
} |
3549 |
kmem_cache_reap_now(buf_cache); |
3550 |
kmem_cache_reap_now(hdr_full_cache); |
3551 |
kmem_cache_reap_now(hdr_l2only_cache); |
3552 |
kmem_cache_reap_now(range_seg_cache); |
3553 |
} |
3554 |
|
3521 |
static __noinline void |
3555 |
static __noinline void |
3522 |
arc_kmem_reap_now(void) |
3556 |
arc_kmem_reap_now(void) |
3523 |
{ |
3557 |
{ |
Lines 3542-3561
Link Here
|
3542 |
#endif |
3576 |
#endif |
3543 |
#endif |
3577 |
#endif |
3544 |
|
3578 |
|
3545 |
for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) { |
3579 |
reap_arc_caches(); |
3546 |
if (zio_buf_cache[i] != prev_cache) { |
|
|
3547 |
prev_cache = zio_buf_cache[i]; |
3548 |
kmem_cache_reap_now(zio_buf_cache[i]); |
3549 |
} |
3550 |
if (zio_data_buf_cache[i] != prev_data_cache) { |
3551 |
prev_data_cache = zio_data_buf_cache[i]; |
3552 |
kmem_cache_reap_now(zio_data_buf_cache[i]); |
3553 |
} |
3554 |
} |
3555 |
kmem_cache_reap_now(buf_cache); |
3556 |
kmem_cache_reap_now(hdr_full_cache); |
3557 |
kmem_cache_reap_now(hdr_l2only_cache); |
3558 |
kmem_cache_reap_now(range_seg_cache); |
3559 |
|
3580 |
|
3560 |
#ifdef illumos |
3581 |
#ifdef illumos |
3561 |
if (zio_arena != NULL) { |
3582 |
if (zio_arena != NULL) { |
Lines 3590-3600
Link Here
|
3590 |
{ |
3611 |
{ |
3591 |
clock_t growtime = 0; |
3612 |
clock_t growtime = 0; |
3592 |
callb_cpr_t cpr; |
3613 |
callb_cpr_t cpr; |
|
|
3614 |
int autoreap = 0; |
3593 |
|
3615 |
|
3594 |
CALLB_CPR_INIT(&cpr, &arc_reclaim_lock, callb_generic_cpr, FTAG); |
3616 |
CALLB_CPR_INIT(&cpr, &arc_reclaim_lock, callb_generic_cpr, FTAG); |
3595 |
|
3617 |
|
3596 |
mutex_enter(&arc_reclaim_lock); |
3618 |
mutex_enter(&arc_reclaim_lock); |
3597 |
while (!arc_reclaim_thread_exit) { |
3619 |
while (!arc_reclaim_thread_exit) { |
|
|
3620 |
#ifdef _KERNEL |
3621 |
/* KD 2015-02-10 |
3622 |
* Protect against UMA free memory bloat. We already do this on a low-memory |
3623 |
* basis in the allocator; it has to happen there rather than here due to |
3624 |
* response time considerations. Make the call here once every 10 passes as |
3625 |
* well; this reclaims unused UMA buffers every 10 seconds on an idle system |
3626 |
* and more frequently if the reclaim thread gets woken up by low RAM |
3627 |
* conditions. |
3628 |
*/ |
3629 |
if ((zio_use_uma) && (autoreap++ == 10)) { |
3630 |
autoreap = 0; |
3631 |
DTRACE_PROBE(arc__reclaim_timed_reap); |
3632 |
reap_arc_caches(); |
3633 |
} |
3634 |
#endif /* _KERNEL */ |
3635 |
|
3598 |
int64_t free_memory = arc_available_memory(); |
3636 |
int64_t free_memory = arc_available_memory(); |
3599 |
uint64_t evicted = 0; |
3637 |
uint64_t evicted = 0; |
3600 |
|
3638 |
|
Lines 3860-3865
Link Here
|
3860 |
arc_space_consume(size, ARC_SPACE_META); |
3899 |
arc_space_consume(size, ARC_SPACE_META); |
3861 |
} else { |
3900 |
} else { |
3862 |
ASSERT(type == ARC_BUFC_DATA); |
3901 |
ASSERT(type == ARC_BUFC_DATA); |
|
|
3902 |
#ifdef _KERNEL |
3903 |
/* KD 2015-02-10 |
3904 |
* It would be nice if we could leave this to the arc_reclaim thread. |
3905 |
* Unfortunately we cannot; the test has to be done here as well, because |
3906 |
* under heavy I/O demand we can grab enough RAM fast enough to induce |
3907 |
* nasty oscillation problems. Fortunately we only need to call this when |
3908 |
* the system is under reasonably-severe memory stress. |
3909 |
*/ |
3910 |
if (zio_use_uma && (ptob(cnt.v_free_count) + size < ptob(cnt.v_free_target))) { |
3911 |
DTRACE_PROBE3(arc__alloc_lowmem_reap, int, cnt.v_free_count, int, size, int, cnt.v_free_target); |
3912 |
reap_arc_caches(); |
3913 |
} |
3914 |
#endif /* _KERNEL */ |
3863 |
buf->b_data = zio_data_buf_alloc(size); |
3915 |
buf->b_data = zio_data_buf_alloc(size); |
3864 |
arc_space_consume(size, ARC_SPACE_DATA); |
3916 |
arc_space_consume(size, ARC_SPACE_DATA); |
3865 |
} |
3917 |
} |