X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Farc.c;h=89f5fe5f0272e9706a1e6cd838c10831b2a47c44;hb=57b650b86f15793195f9bf2185e1161c7c67904d;hp=de869666b9d3aa3cd2553630dbbf6c47772dfe15;hpb=294f68063b49c06d3118d51016811063e69cf97a;p=zfs.git diff --git a/module/zfs/arc.c b/module/zfs/arc.c index de86966..89f5fe5 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -148,7 +148,7 @@ static kcondvar_t arc_reclaim_thr_cv; /* used to signal reclaim thr */ static uint8_t arc_thread_exit; /* number of bytes to prune from caches when at arc_meta_limit is reached */ -uint_t arc_meta_prune = 1048576; +int zfs_arc_meta_prune = 1048576; typedef enum arc_reclaim_strategy { ARC_RECLAIM_AGGR, /* Aggressive reclaim strategy */ @@ -156,25 +156,31 @@ typedef enum arc_reclaim_strategy { } arc_reclaim_strategy_t; /* number of seconds before growing cache again */ -static int arc_grow_retry = 5; - -/* expiration time for arc_no_grow */ -static clock_t arc_grow_time = 0; +int zfs_arc_grow_retry = 5; /* shift of arc_c for calculating both min and max arc_p */ -static int arc_p_min_shift = 4; +int zfs_arc_p_min_shift = 4; /* log2(fraction of arc to reclaim) */ -static int arc_shrink_shift = 5; +int zfs_arc_shrink_shift = 5; /* * minimum lifespan of a prefetch block in clock ticks * (initialized in arc_init()) */ -static int arc_min_prefetch_lifespan; +int zfs_arc_min_prefetch_lifespan = HZ; + +/* disable arc proactive arc throttle due to low memory */ +int zfs_arc_memory_throttle_disable = 1; + +/* disable duplicate buffer eviction */ +int zfs_disable_dup_eviction = 0; static int arc_dead; +/* expiration time for arc_no_grow */ +static clock_t arc_grow_time = 0; + /* * The arc has filled available memory and has now warmed up. */ @@ -186,12 +192,6 @@ static boolean_t arc_warm; unsigned long zfs_arc_max = 0; unsigned long zfs_arc_min = 0; unsigned long zfs_arc_meta_limit = 0; -int zfs_arc_grow_retry = 0; -int zfs_arc_shrink_shift = 0; -int zfs_arc_p_min_shift = 0; -int zfs_arc_memory_throttle_disable = 1; -int zfs_disable_dup_eviction = 0; -int zfs_arc_meta_prune = 0; /* * Note that buffers can be in one of 6 states: @@ -501,7 +501,6 @@ struct arc_buf_hdr { kmutex_t b_freeze_lock; zio_cksum_t *b_freeze_cksum; - void *b_thawed; arc_buf_hdr_t *b_hash_next; arc_buf_t *b_buf; @@ -640,7 +639,7 @@ unsigned long l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */ unsigned long l2arc_feed_min_ms = L2ARC_FEED_MIN_MS; /* min interval msecs */ int l2arc_noprefetch = B_TRUE; /* don't cache prefetch bufs */ int l2arc_feed_again = B_TRUE; /* turbo warmup */ -int l2arc_norw = B_TRUE; /* no reads during writes */ +int l2arc_norw = B_FALSE; /* no reads during writes */ /* * L2ARC Internals @@ -1033,12 +1032,6 @@ arc_buf_thaw(arc_buf_t *buf) buf->b_hdr->b_freeze_cksum = NULL; } - if (zfs_flags & ZFS_DEBUG_MODIFY) { - if (buf->b_hdr->b_thawed) - kmem_free(buf->b_hdr->b_thawed, 1); - buf->b_hdr->b_thawed = kmem_alloc(1, KM_SLEEP); - } - mutex_exit(&buf->b_hdr->b_freeze_lock); } @@ -1260,23 +1253,6 @@ arc_space_return(uint64_t space, arc_space_type_t type) atomic_add_64(&arc_size, -space); } -void * -arc_data_buf_alloc(uint64_t size) -{ - if (arc_evict_needed(ARC_BUFC_DATA)) - cv_signal(&arc_reclaim_thr_cv); - atomic_add_64(&arc_size, size); - return (zio_data_buf_alloc(size)); -} - -void -arc_data_buf_free(void *buf, uint64_t size) -{ - zio_data_buf_free(buf, size); - ASSERT(arc_size >= size); - atomic_add_64(&arc_size, -size); -} - arc_buf_t * arc_buf_alloc(spa_t *spa, int size, void *tag, arc_buf_contents_t type) { @@ -1545,6 +1521,7 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr) list_remove(l2hdr->b_dev->l2ad_buflist, hdr); ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size); kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t)); + arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS); if (hdr->b_state == arc_l2c_only) l2arc_hdr_stat_remove(); hdr->b_l2hdr = NULL; @@ -1580,10 +1557,6 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr) kmem_free(hdr->b_freeze_cksum, sizeof (zio_cksum_t)); hdr->b_freeze_cksum = NULL; } - if (hdr->b_thawed) { - kmem_free(hdr->b_thawed, 1); - hdr->b_thawed = NULL; - } ASSERT(!list_link_active(&hdr->b_arc_node)); ASSERT3P(hdr->b_hash_next, ==, NULL); @@ -1642,7 +1615,7 @@ int arc_buf_remove_ref(arc_buf_t *buf, void* tag) { arc_buf_hdr_t *hdr = buf->b_hdr; - kmutex_t *hash_lock = HDR_LOCK(hdr); + kmutex_t *hash_lock = NULL; int no_callback = (buf->b_efunc == NULL); if (hdr->b_state == arc_anon) { @@ -1651,6 +1624,7 @@ arc_buf_remove_ref(arc_buf_t *buf, void* tag) return (no_callback); } + hash_lock = HDR_LOCK(hdr); mutex_enter(hash_lock); hdr = buf->b_hdr; ASSERT3P(hash_lock, ==, HDR_LOCK(hdr)); @@ -1759,7 +1733,7 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle, (spa && ab->b_spa != spa) || (ab->b_flags & (ARC_PREFETCH|ARC_INDIRECT) && ddi_get_lbolt() - ab->b_arc_access < - arc_min_prefetch_lifespan)) { + zfs_arc_min_prefetch_lifespan)) { skipped++; continue; } @@ -2110,7 +2084,7 @@ arc_adjust_meta(int64_t adjustment, boolean_t may_prune) } if (may_prune && (adjustment > 0) && (arc_meta_used > arc_meta_limit)) - arc_do_user_prune(arc_meta_prune); + arc_do_user_prune(zfs_arc_meta_prune); } /* @@ -2161,14 +2135,14 @@ arc_shrink(uint64_t bytes) if (arc_c > arc_c_min) { uint64_t to_free; - to_free = bytes ? bytes : arc_c >> arc_shrink_shift; + to_free = bytes ? bytes : arc_c >> zfs_arc_shrink_shift; if (arc_c > arc_c_min + to_free) atomic_add_64(&arc_c, -to_free); else arc_c = arc_c_min; - atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift)); + atomic_add_64(&arc_p, -(arc_p >> zfs_arc_shrink_shift)); if (arc_c > arc_size) arc_c = MAX(arc_size, arc_c_min); if (arc_p > arc_c) @@ -2247,7 +2221,7 @@ arc_adapt_thread(void) } /* reset the growth delay for every reclaim */ - arc_grow_time = ddi_get_lbolt()+(arc_grow_retry * hz); + arc_grow_time = ddi_get_lbolt()+(zfs_arc_grow_retry * hz); arc_kmem_reap_now(last_reclaim, 0); arc_warm = B_TRUE; @@ -2277,6 +2251,26 @@ arc_adapt_thread(void) (void) cv_timedwait_interruptible(&arc_reclaim_thr_cv, &arc_reclaim_thr_lock, (ddi_get_lbolt() + hz)); CALLB_CPR_SAFE_END(&cpr, &arc_reclaim_thr_lock); + + + /* Allow the module options to be changed */ + if (zfs_arc_max > 64 << 20 && + zfs_arc_max < physmem * PAGESIZE && + zfs_arc_max != arc_c_max) + arc_c_max = zfs_arc_max; + + if (zfs_arc_min > 0 && + zfs_arc_min < arc_c_max && + zfs_arc_min != arc_c_min) + arc_c_min = zfs_arc_min; + + if (zfs_arc_meta_limit > 0 && + zfs_arc_meta_limit <= arc_c_max && + zfs_arc_meta_limit != arc_meta_limit) + arc_meta_limit = zfs_arc_meta_limit; + + + } arc_thread_exit = 0; @@ -2397,7 +2391,7 @@ __arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc) ARCSTAT_BUMP(arcstat_memory_indirect_count); } else { arc_no_grow = B_TRUE; - arc_grow_time = ddi_get_lbolt() + (arc_grow_retry * hz); + arc_grow_time = ddi_get_lbolt() + (zfs_arc_grow_retry * hz); ARCSTAT_BUMP(arcstat_memory_direct_count); } @@ -2419,7 +2413,7 @@ static void arc_adapt(int bytes, arc_state_t *state) { int mult; - uint64_t arc_p_min = (arc_c >> arc_p_min_shift); + uint64_t arc_p_min = (arc_c >> zfs_arc_p_min_shift); if (state == arc_l2c_only) return; @@ -3442,6 +3436,7 @@ arc_release(arc_buf_t *buf, void *tag) if (l2hdr) { list_remove(l2hdr->b_dev->l2ad_buflist, hdr); kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t)); + arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS); ARCSTAT_INCR(arcstat_l2_size, -buf_size); mutex_exit(&l2arc_buflist_mtx); } @@ -3753,7 +3748,7 @@ arc_init(void) cv_init(&arc_reclaim_thr_cv, NULL, CV_DEFAULT, NULL); /* Convert seconds to clock ticks */ - arc_min_prefetch_lifespan = 1 * hz; + zfs_arc_min_prefetch_lifespan = 1 * hz; /* Start out with 1/8 of all memory */ arc_c = physmem * PAGESIZE / 8; @@ -3801,18 +3796,6 @@ arc_init(void) if (arc_c_min < arc_meta_limit / 2 && zfs_arc_min == 0) arc_c_min = arc_meta_limit / 2; - if (zfs_arc_grow_retry > 0) - arc_grow_retry = zfs_arc_grow_retry; - - if (zfs_arc_shrink_shift > 0) - arc_shrink_shift = zfs_arc_shrink_shift; - - if (zfs_arc_p_min_shift > 0) - arc_p_min_shift = zfs_arc_p_min_shift; - - if (zfs_arc_meta_prune > 0) - arc_meta_prune = zfs_arc_meta_prune; - /* if kmem_flags are set, lets try to use less memory */ if (kmem_debugging()) arc_c = arc_c / 2; @@ -4141,14 +4124,14 @@ l2arc_write_interval(clock_t began, uint64_t wanted, uint64_t wrote) static void l2arc_hdr_stat_add(void) { - ARCSTAT_INCR(arcstat_l2_hdr_size, HDR_SIZE + L2HDR_SIZE); + ARCSTAT_INCR(arcstat_l2_hdr_size, HDR_SIZE); ARCSTAT_INCR(arcstat_hdr_size, -HDR_SIZE); } static void l2arc_hdr_stat_remove(void) { - ARCSTAT_INCR(arcstat_l2_hdr_size, -(HDR_SIZE + L2HDR_SIZE)); + ARCSTAT_INCR(arcstat_l2_hdr_size, -HDR_SIZE); ARCSTAT_INCR(arcstat_hdr_size, HDR_SIZE); } @@ -4292,6 +4275,7 @@ l2arc_write_done(zio_t *zio) abl2 = ab->b_l2hdr; ab->b_l2hdr = NULL; kmem_free(abl2, sizeof (l2arc_buf_hdr_t)); + arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS); ARCSTAT_INCR(arcstat_l2_size, -ab->b_size); } @@ -4538,6 +4522,7 @@ top: abl2 = ab->b_l2hdr; ab->b_l2hdr = NULL; kmem_free(abl2, sizeof (l2arc_buf_hdr_t)); + arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS); ARCSTAT_INCR(arcstat_l2_size, -ab->b_size); } list_remove(buflist, ab); @@ -4663,6 +4648,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) KM_PUSHPAGE); hdrl2->b_dev = dev; hdrl2->b_daddr = dev->l2ad_hand; + arc_space_consume(L2HDR_SIZE, ARC_SPACE_L2HDRS); ab->b_flags |= ARC_L2_WRITING; ab->b_l2hdr = hdrl2; @@ -5007,25 +4993,25 @@ EXPORT_SYMBOL(arc_getbuf_func); EXPORT_SYMBOL(arc_add_prune_callback); EXPORT_SYMBOL(arc_remove_prune_callback); -module_param(zfs_arc_min, ulong, 0444); +module_param(zfs_arc_min, ulong, 0644); MODULE_PARM_DESC(zfs_arc_min, "Min arc size"); -module_param(zfs_arc_max, ulong, 0444); +module_param(zfs_arc_max, ulong, 0644); MODULE_PARM_DESC(zfs_arc_max, "Max arc size"); -module_param(zfs_arc_meta_limit, ulong, 0444); +module_param(zfs_arc_meta_limit, ulong, 0644); MODULE_PARM_DESC(zfs_arc_meta_limit, "Meta limit for arc size"); -module_param(zfs_arc_meta_prune, int, 0444); +module_param(zfs_arc_meta_prune, int, 0644); MODULE_PARM_DESC(zfs_arc_meta_prune, "Bytes of meta data to prune"); -module_param(zfs_arc_grow_retry, int, 0444); +module_param(zfs_arc_grow_retry, int, 0644); MODULE_PARM_DESC(zfs_arc_grow_retry, "Seconds before growing arc size"); -module_param(zfs_arc_shrink_shift, int, 0444); +module_param(zfs_arc_shrink_shift, int, 0644); MODULE_PARM_DESC(zfs_arc_shrink_shift, "log2(fraction of arc to reclaim)"); -module_param(zfs_arc_p_min_shift, int, 0444); +module_param(zfs_arc_p_min_shift, int, 0644); MODULE_PARM_DESC(zfs_arc_p_min_shift, "arc_c shift to calc min/max arc_p"); module_param(zfs_disable_dup_eviction, int, 0644); @@ -5034,28 +5020,31 @@ MODULE_PARM_DESC(zfs_disable_dup_eviction, "disable duplicate buffer eviction"); module_param(zfs_arc_memory_throttle_disable, int, 0644); MODULE_PARM_DESC(zfs_arc_memory_throttle_disable, "disable memory throttle"); -module_param(l2arc_write_max, ulong, 0444); +module_param(zfs_arc_min_prefetch_lifespan, int, 0644); +MODULE_PARM_DESC(zfs_arc_min_prefetch_lifespan, "Min life of prefetch block"); + +module_param(l2arc_write_max, ulong, 0644); MODULE_PARM_DESC(l2arc_write_max, "Max write bytes per interval"); -module_param(l2arc_write_boost, ulong, 0444); +module_param(l2arc_write_boost, ulong, 0644); MODULE_PARM_DESC(l2arc_write_boost, "Extra write bytes during device warmup"); -module_param(l2arc_headroom, ulong, 0444); +module_param(l2arc_headroom, ulong, 0644); MODULE_PARM_DESC(l2arc_headroom, "Number of max device writes to precache"); -module_param(l2arc_feed_secs, ulong, 0444); +module_param(l2arc_feed_secs, ulong, 0644); MODULE_PARM_DESC(l2arc_feed_secs, "Seconds between L2ARC writing"); -module_param(l2arc_feed_min_ms, ulong, 0444); +module_param(l2arc_feed_min_ms, ulong, 0644); MODULE_PARM_DESC(l2arc_feed_min_ms, "Min feed interval in milliseconds"); -module_param(l2arc_noprefetch, int, 0444); +module_param(l2arc_noprefetch, int, 0644); MODULE_PARM_DESC(l2arc_noprefetch, "Skip caching prefetched buffers"); -module_param(l2arc_feed_again, int, 0444); +module_param(l2arc_feed_again, int, 0644); MODULE_PARM_DESC(l2arc_feed_again, "Turbo L2ARC warmup"); -module_param(l2arc_norw, int, 0444); +module_param(l2arc_norw, int, 0644); MODULE_PARM_DESC(l2arc_norw, "No reads during writes"); #endif