Date: Wed, 28 Jan 2015 23:13:12 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r277865 - user/delphij/zfs-arc-rebase/sys/cddl/contrib/opensolaris/uts/common/fs/zfs Message-ID: <201501282313.t0SNDC3B020590@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Wed Jan 28 23:13:12 2015 New Revision: 277865 URL: https://svnweb.freebsd.org/changeset/base/277865 Log: Undo portion of r205231 (kmacy) which breaks up ARC state locks into 16 as well as the related r272708 (avg). Upstream have implemented this differently and we will adopt the upstream implementation. Modified: user/delphij/zfs-arc-rebase/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Modified: user/delphij/zfs-arc-rebase/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c ============================================================================== --- user/delphij/zfs-arc-rebase/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Wed Jan 28 23:00:22 2015 (r277864) +++ user/delphij/zfs-arc-rebase/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Wed Jan 28 23:13:12 2015 (r277865) @@ -195,6 +195,9 @@ extern int zfs_prefetch_disable; */ static boolean_t arc_warm; +/* + * These tunables are for performance analysis. + */ uint64_t zfs_arc_max; uint64_t zfs_arc_min; uint64_t zfs_arc_meta_limit = 0; @@ -306,31 +309,13 @@ SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_meta * second level ARC benefit from these fast lookups. */ -#define ARCS_LOCK_PAD CACHE_LINE_SIZE -struct arcs_lock { - kmutex_t arcs_lock; -#ifdef _KERNEL - unsigned char pad[(ARCS_LOCK_PAD - sizeof (kmutex_t))]; -#endif -}; - -/* - * must be power of two for mask use to work - * - */ -#define ARC_BUFC_NUMDATALISTS 16 -#define ARC_BUFC_NUMMETADATALISTS 16 -#define ARC_BUFC_NUMLISTS (ARC_BUFC_NUMMETADATALISTS + ARC_BUFC_NUMDATALISTS) - typedef struct arc_state { + list_t arcs_list[ARC_BUFC_NUMTYPES]; /* list of evictable buffers */ uint64_t arcs_lsize[ARC_BUFC_NUMTYPES]; /* amount of evictable data */ uint64_t arcs_size; /* total amount of data in this state */ - list_t arcs_lists[ARC_BUFC_NUMLISTS]; /* list of evictable buffers */ - struct arcs_lock arcs_locks[ARC_BUFC_NUMLISTS] __aligned(CACHE_LINE_SIZE); + kmutex_t arcs_mtx; } arc_state_t; -#define ARCS_LOCK(s, i) (&((s)->arcs_locks[(i)].arcs_lock)) - /* The 6 states: */ static arc_state_t ARC_anon; static arc_state_t ARC_mru; @@ -1305,23 +1290,6 @@ arc_buf_freeze(arc_buf_t *buf) } static void -get_buf_info(arc_buf_hdr_t *hdr, arc_state_t *state, list_t **list, kmutex_t **lock) -{ - uint64_t buf_hashid = buf_hash(hdr->b_spa, &hdr->b_dva, hdr->b_birth); - - if (hdr->b_type == ARC_BUFC_METADATA) - buf_hashid &= (ARC_BUFC_NUMMETADATALISTS - 1); - else { - buf_hashid &= (ARC_BUFC_NUMDATALISTS - 1); - buf_hashid += ARC_BUFC_NUMMETADATALISTS; - } - - *list = &state->arcs_lists[buf_hashid]; - *lock = ARCS_LOCK(state, buf_hashid); -} - - -static void add_reference(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, void *tag) { ASSERT(MUTEX_HELD(hash_lock)); @@ -1329,13 +1297,11 @@ add_reference(arc_buf_hdr_t *hdr, kmutex if ((refcount_add(&hdr->b_refcnt, tag) == 1) && (hdr->b_state != arc_anon)) { uint64_t delta = hdr->b_size * hdr->b_datacnt; + list_t *list = &hdr->b_state->arcs_list[hdr->b_type]; uint64_t *size = &hdr->b_state->arcs_lsize[hdr->b_type]; - list_t *list; - kmutex_t *lock; - get_buf_info(hdr, hdr->b_state, &list, &lock); - ASSERT(!MUTEX_HELD(lock)); - mutex_enter(lock); + ASSERT(!MUTEX_HELD(&hdr->b_state->arcs_mtx)); + mutex_enter(&hdr->b_state->arcs_mtx); ASSERT(list_link_active(&hdr->b_arc_node)); list_remove(list, hdr); if (GHOST_STATE(hdr->b_state)) { @@ -1346,7 +1312,7 @@ add_reference(arc_buf_hdr_t *hdr, kmutex ASSERT(delta > 0); ASSERT3U(*size, >=, delta); atomic_add_64(size, -delta); - mutex_exit(lock); + mutex_exit(&hdr->b_state->arcs_mtx); /* remove the prefetch flag if we get a reference */ if (hdr->b_flags & ARC_FLAG_PREFETCH) hdr->b_flags &= ~ARC_FLAG_PREFETCH; @@ -1365,17 +1331,14 @@ remove_reference(arc_buf_hdr_t *hdr, kmu if (((cnt = refcount_remove(&hdr->b_refcnt, tag)) == 0) && (state != arc_anon)) { uint64_t *size = &state->arcs_lsize[hdr->b_type]; - list_t *list; - kmutex_t *lock; - get_buf_info(hdr, state, &list, &lock); - ASSERT(!MUTEX_HELD(lock)); - mutex_enter(lock); + ASSERT(!MUTEX_HELD(&state->arcs_mtx)); + mutex_enter(&state->arcs_mtx); ASSERT(!list_link_active(&hdr->b_arc_node)); - list_insert_head(list, hdr); + list_insert_head(&state->arcs_list[hdr->b_type], hdr); ASSERT(hdr->b_datacnt > 0); atomic_add_64(size, hdr->b_size * hdr->b_datacnt); - mutex_exit(lock); + mutex_exit(&state->arcs_mtx); } return (cnt); } @@ -1391,8 +1354,6 @@ arc_change_state(arc_state_t *new_state, arc_state_t *old_state = hdr->b_state; int64_t refcnt = refcount_count(&hdr->b_refcnt); uint64_t from_delta, to_delta; - list_t *list; - kmutex_t *lock; ASSERT(MUTEX_HELD(hash_lock)); ASSERT3P(new_state, !=, old_state); @@ -1408,16 +1369,14 @@ arc_change_state(arc_state_t *new_state, */ if (refcnt == 0) { if (old_state != arc_anon) { - int use_mutex; + int use_mutex = !MUTEX_HELD(&old_state->arcs_mtx); uint64_t *size = &old_state->arcs_lsize[hdr->b_type]; - get_buf_info(hdr, old_state, &list, &lock); - use_mutex = !MUTEX_HELD(lock); if (use_mutex) - mutex_enter(lock); + mutex_enter(&old_state->arcs_mtx); ASSERT(list_link_active(&hdr->b_arc_node)); - list_remove(list, hdr); + list_remove(&old_state->arcs_list[hdr->b_type], hdr); /* * If prefetching out of the ghost cache, @@ -1432,18 +1391,17 @@ arc_change_state(arc_state_t *new_state, atomic_add_64(size, -from_delta); if (use_mutex) - mutex_exit(lock); + mutex_exit(&old_state->arcs_mtx); } if (new_state != arc_anon) { - int use_mutex; + int use_mutex = !MUTEX_HELD(&new_state->arcs_mtx); uint64_t *size = &new_state->arcs_lsize[hdr->b_type]; - get_buf_info(hdr, new_state, &list, &lock); - use_mutex = !MUTEX_HELD(lock); if (use_mutex) - mutex_enter(lock); + mutex_enter(&new_state->arcs_mtx); - list_insert_head(list, hdr); + list_insert_head(&new_state->arcs_list[hdr->b_type], + hdr); /* ghost elements have a ghost size */ if (GHOST_STATE(new_state)) { @@ -1454,7 +1412,7 @@ arc_change_state(arc_state_t *new_state, atomic_add_64(size, to_delta); if (use_mutex) - mutex_exit(lock); + mutex_exit(&new_state->arcs_mtx); } } @@ -2028,52 +1986,49 @@ arc_evict(arc_state_t *state, uint64_t s { arc_state_t *evicted_state; uint64_t bytes_evicted = 0, skipped = 0, missed = 0; - int64_t bytes_remaining; arc_buf_hdr_t *hdr, *hdr_prev = NULL; - list_t *evicted_list, *list, *evicted_list_start, *list_start; - kmutex_t *lock, *evicted_lock; kmutex_t *hash_lock; boolean_t have_lock; void *stolen = NULL; arc_buf_hdr_t marker = { 0 }; int count = 0; - static int evict_metadata_offset, evict_data_offset; - int i, idx, offset, list_count, lists; ASSERT(state == arc_mru || state == arc_mfu); evicted_state = (state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost; + mutex_enter(&state->arcs_mtx); + mutex_enter(&evicted_state->arcs_mtx); + /* * Decide which "type" (data vs metadata) to recycle from. * * If we are over the metadata limit, recycle from metadata. * If we are under the metadata minimum, recycle from data. * Otherwise, recycle from whichever type has the oldest (least - * recently accessed) header. This is not yet implemented. + * recently accessed) header. */ if (recycle) { + arc_buf_hdr_t *data_hdr = + list_tail(&state->arcs_list[ARC_BUFC_DATA]); + arc_buf_hdr_t *metadata_hdr = + list_tail(&state->arcs_list[ARC_BUFC_METADATA]); arc_buf_contents_t realtype; - if (state->arcs_lsize[ARC_BUFC_DATA] == 0) { + if (data_hdr == NULL) { realtype = ARC_BUFC_METADATA; - } else if (state->arcs_lsize[ARC_BUFC_METADATA] == 0) { + } else if (metadata_hdr == NULL) { realtype = ARC_BUFC_DATA; } else if (arc_meta_used >= arc_meta_limit) { realtype = ARC_BUFC_METADATA; } else if (arc_meta_used <= arc_meta_min) { realtype = ARC_BUFC_DATA; } else { -#ifdef illumos if (data_hdr->b_arc_access < metadata_hdr->b_arc_access) { realtype = ARC_BUFC_DATA; } else { realtype = ARC_BUFC_METADATA; } -#else - /* TODO */ - realtype = type; -#endif } if (realtype != type) { /* @@ -2087,34 +2042,10 @@ arc_evict(arc_state_t *state, uint64_t s } } - if (type == ARC_BUFC_METADATA) { - offset = 0; - list_count = ARC_BUFC_NUMMETADATALISTS; - list_start = &state->arcs_lists[0]; - evicted_list_start = &evicted_state->arcs_lists[0]; - idx = evict_metadata_offset; - } else { - offset = ARC_BUFC_NUMMETADATALISTS; - list_start = &state->arcs_lists[offset]; - evicted_list_start = &evicted_state->arcs_lists[offset]; - list_count = ARC_BUFC_NUMDATALISTS; - idx = evict_data_offset; - } - bytes_remaining = evicted_state->arcs_lsize[type]; - lists = 0; - -evict_start: - list = &list_start[idx]; - evicted_list = &evicted_list_start[idx]; - lock = ARCS_LOCK(state, (offset + idx)); - evicted_lock = ARCS_LOCK(evicted_state, (offset + idx)); - - mutex_enter(lock); - mutex_enter(evicted_lock); + list_t *list = &state->arcs_list[type]; for (hdr = list_tail(list); hdr; hdr = hdr_prev) { hdr_prev = list_prev(list, hdr); - bytes_remaining -= (hdr->b_size * hdr->b_datacnt); /* prefetch buffers have a minimum lifespan */ if (HDR_IO_IN_PROGRESS(hdr) || (spa && hdr->b_spa != spa) || @@ -2144,11 +2075,11 @@ evict_start: */ if (!recycle && count++ > arc_evict_iterations) { list_insert_after(list, hdr, &marker); - mutex_exit(evicted_lock); - mutex_exit(lock); + mutex_exit(&evicted_state->arcs_mtx); + mutex_exit(&state->arcs_mtx); kpreempt(KPREEMPT_SYNC); - mutex_enter(lock); - mutex_enter(evicted_lock); + mutex_enter(&state->arcs_mtx); + mutex_enter(&evicted_state->arcs_mtx); hdr_prev = list_prev(list, &marker); list_remove(list, &marker); count = 0; @@ -2217,35 +2148,17 @@ evict_start: mutex_exit(hash_lock); if (bytes >= 0 && bytes_evicted >= bytes) break; - if (bytes_remaining > 0) { - mutex_exit(evicted_lock); - mutex_exit(lock); - idx = ((idx + 1) & (list_count - 1)); - lists++; - goto evict_start; - } } else { missed += 1; } } - mutex_exit(evicted_lock); - mutex_exit(lock); + mutex_exit(&evicted_state->arcs_mtx); + mutex_exit(&state->arcs_mtx); - idx = ((idx + 1) & (list_count - 1)); - lists++; - - if (bytes_evicted < bytes) { - if (lists < list_count) - goto evict_start; - else - dprintf("only evicted %lld bytes from %x", - (longlong_t)bytes_evicted, state); - } - if (type == ARC_BUFC_METADATA) - evict_metadata_offset = idx; - else - evict_data_offset = idx; + if (bytes_evicted < bytes) + dprintf("only evicted %lld bytes from %x", + (longlong_t)bytes_evicted, state); if (skipped) ARCSTAT_INCR(arcstat_evict_skip, skipped); @@ -2274,29 +2187,15 @@ arc_evict_ghost(arc_state_t *state, uint { arc_buf_hdr_t *hdr, *hdr_prev; arc_buf_hdr_t marker = { 0 }; - list_t *list, *list_start; - kmutex_t *hash_lock, *lock; + list_t *list = &state->arcs_list[ARC_BUFC_DATA]; + kmutex_t *hash_lock; uint64_t bytes_deleted = 0; uint64_t bufs_skipped = 0; int count = 0; - static int evict_offset; - int list_count, idx = evict_offset; - int offset, lists = 0; ASSERT(GHOST_STATE(state)); - - /* - * data lists come after metadata lists - */ - list_start = &state->arcs_lists[ARC_BUFC_NUMMETADATALISTS]; - list_count = ARC_BUFC_NUMDATALISTS; - offset = ARC_BUFC_NUMMETADATALISTS; - -evict_start: - list = &list_start[idx]; - lock = ARCS_LOCK(state, idx + offset); - - mutex_enter(lock); +top: + mutex_enter(&state->arcs_mtx); for (hdr = list_tail(list); hdr; hdr = hdr_prev) { hdr_prev = list_prev(list, hdr); if (hdr->b_type > ARC_BUFC_NUMTYPES) @@ -2321,9 +2220,9 @@ evict_start: */ if (count++ > arc_evict_iterations) { list_insert_after(list, hdr, &marker); - mutex_exit(lock); + mutex_exit(&state->arcs_mtx); kpreempt(KPREEMPT_SYNC); - mutex_enter(lock); + mutex_enter(&state->arcs_mtx); hdr_prev = list_prev(list, &marker); list_remove(list, &marker); count = 0; @@ -2358,10 +2257,10 @@ evict_start: * available, restart from where we left off. */ list_insert_after(list, hdr, &marker); - mutex_exit(lock); + mutex_exit(&state->arcs_mtx); mutex_enter(hash_lock); mutex_exit(hash_lock); - mutex_enter(lock); + mutex_enter(&state->arcs_mtx); hdr_prev = list_prev(list, &marker); list_remove(list, &marker); } else { @@ -2369,20 +2268,12 @@ evict_start: } } - mutex_exit(lock); - idx = ((idx + 1) & (ARC_BUFC_NUMDATALISTS - 1)); - lists++; + mutex_exit(&state->arcs_mtx); - if (lists < list_count) - goto evict_start; - - evict_offset = idx; - if ((uintptr_t)list > (uintptr_t)&state->arcs_lists[ARC_BUFC_NUMMETADATALISTS] && + if (list == &state->arcs_list[ARC_BUFC_DATA] && (bytes < 0 || bytes_deleted < bytes)) { - list_start = &state->arcs_lists[0]; - list_count = ARC_BUFC_NUMMETADATALISTS; - offset = lists = 0; - goto evict_start; + list = &state->arcs_list[ARC_BUFC_METADATA]; + goto top; } if (bufs_skipped) { @@ -2537,7 +2428,6 @@ arc_flush(spa_t *spa) void arc_shrink(void) { - if (arc_c > arc_c_min) { uint64_t to_free; @@ -2571,9 +2461,17 @@ arc_shrink(void) static int needfree = 0; +/* + * Determine if the system is under memory pressure and is asking + * to reclaim memory. A return value of 1 indicates that the system + * is under memory pressure and that the arc should adjust accordingly. + */ static int arc_reclaim_needed(void) { +#ifdef illumos + uint64_t extra; +#endif #ifdef _KERNEL @@ -3293,7 +3191,7 @@ arc_read_done(zio_t *zio) } /* - * "Read" the block block at the specified DVA (in bp) via the + * "Read" the block at the specified DVA (in bp) via the * cache. If the block is found in the cache, invoke the provided * callback immediately and return. Note that the `zio' parameter * in the callback will be NULL in this case, since no IO was @@ -3677,8 +3575,6 @@ arc_clear_callback(arc_buf_t *buf) kmutex_t *hash_lock; arc_evict_func_t *efunc = buf->b_efunc; void *private = buf->b_private; - list_t *list, *evicted_list; - kmutex_t *lock, *evicted_lock; mutex_enter(&buf->b_evict_lock); hdr = buf->b_hdr; @@ -4258,33 +4154,33 @@ arc_init(void) arc_l2c_only = &ARC_l2c_only; arc_size = 0; - for (i = 0; i < ARC_BUFC_NUMLISTS; i++) { - mutex_init(&arc_anon->arcs_locks[i].arcs_lock, - NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mru->arcs_locks[i].arcs_lock, - NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mru_ghost->arcs_locks[i].arcs_lock, - NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mfu->arcs_locks[i].arcs_lock, - NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_mfu_ghost->arcs_locks[i].arcs_lock, - NULL, MUTEX_DEFAULT, NULL); - mutex_init(&arc_l2c_only->arcs_locks[i].arcs_lock, - NULL, MUTEX_DEFAULT, NULL); - - list_create(&arc_mru->arcs_lists[i], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mru_ghost->arcs_lists[i], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mfu->arcs_lists[i], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mfu_ghost->arcs_lists[i], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_mfu_ghost->arcs_lists[i], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - list_create(&arc_l2c_only->arcs_lists[i], - sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); - } + mutex_init(&arc_anon->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mru->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mru_ghost->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mfu->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_mfu_ghost->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&arc_l2c_only->arcs_mtx, NULL, MUTEX_DEFAULT, NULL); + + list_create(&arc_mru->arcs_list[ARC_BUFC_METADATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mru->arcs_list[ARC_BUFC_DATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mfu->arcs_list[ARC_BUFC_METADATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mfu->arcs_list[ARC_BUFC_DATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); + list_create(&arc_l2c_only->arcs_list[ARC_BUFC_DATA], + sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); buf_init(); @@ -4367,8 +4263,6 @@ arc_init(void) void arc_fini(void) { - int i; - mutex_enter(&arc_reclaim_thr_lock); arc_thread_exit = 1; cv_signal(&arc_reclaim_thr_cv); @@ -4389,20 +4283,21 @@ arc_fini(void) mutex_destroy(&arc_reclaim_thr_lock); cv_destroy(&arc_reclaim_thr_cv); - for (i = 0; i < ARC_BUFC_NUMLISTS; i++) { - list_destroy(&arc_mru->arcs_lists[i]); - list_destroy(&arc_mru_ghost->arcs_lists[i]); - list_destroy(&arc_mfu->arcs_lists[i]); - list_destroy(&arc_mfu_ghost->arcs_lists[i]); - list_destroy(&arc_l2c_only->arcs_lists[i]); - - mutex_destroy(&arc_anon->arcs_locks[i].arcs_lock); - mutex_destroy(&arc_mru->arcs_locks[i].arcs_lock); - mutex_destroy(&arc_mru_ghost->arcs_locks[i].arcs_lock); - mutex_destroy(&arc_mfu->arcs_locks[i].arcs_lock); - mutex_destroy(&arc_mfu_ghost->arcs_locks[i].arcs_lock); - mutex_destroy(&arc_l2c_only->arcs_locks[i].arcs_lock); - } + list_destroy(&arc_mru->arcs_list[ARC_BUFC_METADATA]); + list_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA]); + list_destroy(&arc_mfu->arcs_list[ARC_BUFC_METADATA]); + list_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA]); + list_destroy(&arc_mru->arcs_list[ARC_BUFC_DATA]); + list_destroy(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA]); + list_destroy(&arc_mfu->arcs_list[ARC_BUFC_DATA]); + list_destroy(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA]); + + mutex_destroy(&arc_anon->arcs_mtx); + mutex_destroy(&arc_mru->arcs_mtx); + mutex_destroy(&arc_mru_ghost->arcs_mtx); + mutex_destroy(&arc_mfu->arcs_mtx); + mutex_destroy(&arc_mfu_ghost->arcs_mtx); + mutex_destroy(&arc_l2c_only->arcs_mtx); buf_fini(); @@ -4916,27 +4811,26 @@ static list_t * l2arc_list_locked(int list_num, kmutex_t **lock) { list_t *list = NULL; - int idx; - ASSERT(list_num >= 0 && list_num < 2 * ARC_BUFC_NUMLISTS); + ASSERT(list_num >= 0 && list_num <= 3); - if (list_num < ARC_BUFC_NUMMETADATALISTS) { - idx = list_num; - list = &arc_mfu->arcs_lists[idx]; - *lock = ARCS_LOCK(arc_mfu, idx); - } else if (list_num < ARC_BUFC_NUMMETADATALISTS * 2) { - idx = list_num - ARC_BUFC_NUMMETADATALISTS; - list = &arc_mru->arcs_lists[idx]; - *lock = ARCS_LOCK(arc_mru, idx); - } else if (list_num < (ARC_BUFC_NUMMETADATALISTS * 2 + - ARC_BUFC_NUMDATALISTS)) { - idx = list_num - ARC_BUFC_NUMMETADATALISTS; - list = &arc_mfu->arcs_lists[idx]; - *lock = ARCS_LOCK(arc_mfu, idx); - } else { - idx = list_num - ARC_BUFC_NUMLISTS; - list = &arc_mru->arcs_lists[idx]; - *lock = ARCS_LOCK(arc_mru, idx); + switch (list_num) { + case 0: + list = &arc_mfu->arcs_list[ARC_BUFC_METADATA]; + *lock = &arc_mfu->arcs_mtx; + break; + case 1: + list = &arc_mru->arcs_list[ARC_BUFC_METADATA]; + *lock = &arc_mru->arcs_mtx; + break; + case 2: + list = &arc_mfu->arcs_list[ARC_BUFC_DATA]; + *lock = &arc_mfu->arcs_mtx; + break; + case 3: + list = &arc_mru->arcs_list[ARC_BUFC_DATA]; + *lock = &arc_mru->arcs_mtx; + break; } ASSERT(!(MUTEX_HELD(*lock))); @@ -5133,7 +5027,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_de * Copy buffers for L2ARC writing. */ mutex_enter(&l2arc_buflist_mtx); - for (try = 0; try < 2 * ARC_BUFC_NUMLISTS; try++) { + for (int try = 0; try <= 3; try++) { uint64_t passed_sz = 0; list = l2arc_list_locked(try, &list_lock); @@ -5152,7 +5046,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_de if (hdr == NULL) ARCSTAT_BUMP(arcstat_l2_write_buffer_list_null_iter); - headroom = target_sz * l2arc_headroom * 2 / ARC_BUFC_NUMLISTS; + headroom = target_sz * l2arc_headroom; if (do_headroom_boost) headroom = (headroom * l2arc_headroom_boost) / 100;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501282313.t0SNDC3B020590>