Skip to content

Couple minor ARC optimizations. #12348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/sys/arc.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ extern "C" {
* Used by arc_flush() to inform arc_evict_state() that it should evict
* all available buffers from the arc state being passed in.
*/
#define ARC_EVICT_ALL -1ULL
#define ARC_EVICT_ALL UINT64_MAX

#define HDR_SET_LSIZE(hdr, x) do { \
ASSERT(IS_P2ALIGNED(x, 1U << SPA_MINBLOCKSHIFT)); \
Expand Down
11 changes: 9 additions & 2 deletions include/sys/arc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,13 @@ typedef struct arc_evict_waiter {
#define arc_c_max ARCSTAT(arcstat_c_max) /* max target cache size */
#define arc_sys_free ARCSTAT(arcstat_sys_free) /* target system free bytes */

#define arc_anon (&ARC_anon)
#define arc_mru (&ARC_mru)
#define arc_mru_ghost (&ARC_mru_ghost)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this style of macros make the code harder to read. Since they are already all over the ARC, I'm OK with the change as-is, but if you or anyone else would like to improve the code, it would be great to either:

  • change all the users to do &ARC_anon, etc. instead of arc_anon

or

  • make these inline functions, like inline arc_state_t* arc_anon() {return (&ARC_anon);)

#define arc_mfu (&ARC_mfu)
#define arc_mfu_ghost (&ARC_mfu_ghost)
#define arc_l2c_only (&ARC_l2c_only)

extern taskq_t *arc_prune_taskq;
extern arc_stats_t arc_stats;
extern arc_sums_t arc_sums;
Expand All @@ -974,8 +981,8 @@ extern int arc_no_grow_shift;
extern int arc_shrink_shift;
extern kmutex_t arc_prune_mtx;
extern list_t arc_prune_list;
extern arc_state_t *arc_mfu;
extern arc_state_t *arc_mru;
extern arc_state_t ARC_mfu;
extern arc_state_t ARC_mru;
extern uint_t zfs_arc_pc_percent;
extern int arc_lotsfree_percent;
extern unsigned long zfs_arc_min;
Expand Down
40 changes: 9 additions & 31 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,6 @@ arc_sums_t arc_sums;
} while (0)

kstat_t *arc_ksp;
static arc_state_t *arc_anon;
static arc_state_t *arc_mru_ghost;
static arc_state_t *arc_mfu_ghost;
static arc_state_t *arc_l2c_only;

arc_state_t *arc_mru;
arc_state_t *arc_mfu;

/*
* There are several ARC variables that are critical to export as kstats --
Expand Down Expand Up @@ -2197,7 +2190,6 @@ arc_evictable_space_increment(arc_buf_hdr_t *hdr, arc_state_t *state)
return;
}

ASSERT(!GHOST_STATE(state));
if (hdr->b_l1hdr.b_pabd != NULL) {
(void) zfs_refcount_add_many(&state->arcs_esize[type],
arc_hdr_size(hdr), hdr);
Expand Down Expand Up @@ -2238,7 +2230,6 @@ arc_evictable_space_decrement(arc_buf_hdr_t *hdr, arc_state_t *state)
return;
}

ASSERT(!GHOST_STATE(state));
if (hdr->b_l1hdr.b_pabd != NULL) {
(void) zfs_refcount_remove_many(&state->arcs_esize[type],
arc_hdr_size(hdr), hdr);
Expand Down Expand Up @@ -4010,23 +4001,21 @@ arc_set_need_free(void)

static uint64_t
arc_evict_state_impl(multilist_t *ml, int idx, arc_buf_hdr_t *marker,
uint64_t spa, int64_t bytes)
uint64_t spa, uint64_t bytes)
{
multilist_sublist_t *mls;
uint64_t bytes_evicted = 0;
arc_buf_hdr_t *hdr;
kmutex_t *hash_lock;
int evict_count = 0;
int evict_count = zfs_arc_evict_batch_limit;

ASSERT3P(marker, !=, NULL);
IMPLY(bytes < 0, bytes == ARC_EVICT_ALL);

mls = multilist_sublist_lock(ml, idx);

for (hdr = multilist_sublist_prev(mls, marker); hdr != NULL;
for (hdr = multilist_sublist_prev(mls, marker); likely(hdr != NULL);
hdr = multilist_sublist_prev(mls, marker)) {
if ((bytes != ARC_EVICT_ALL && bytes_evicted >= bytes) ||
(evict_count >= zfs_arc_evict_batch_limit))
if ((evict_count <= 0) || (bytes_evicted >= bytes))
break;

/*
Expand Down Expand Up @@ -4085,7 +4074,7 @@ arc_evict_state_impl(multilist_t *ml, int idx, arc_buf_hdr_t *marker,
* evict_count in this case.
*/
if (evicted != 0)
evict_count++;
evict_count--;

} else {
ARCSTAT_BUMP(arcstat_mutex_miss);
Expand Down Expand Up @@ -4146,16 +4135,14 @@ arc_evict_state_impl(multilist_t *ml, int idx, arc_buf_hdr_t *marker,
* the given arc state; which is used by arc_flush().
*/
static uint64_t
arc_evict_state(arc_state_t *state, uint64_t spa, int64_t bytes,
arc_evict_state(arc_state_t *state, uint64_t spa, uint64_t bytes,
arc_buf_contents_t type)
{
uint64_t total_evicted = 0;
multilist_t *ml = &state->arcs_list[type];
int num_sublists;
arc_buf_hdr_t **markers;

IMPLY(bytes < 0, bytes == ARC_EVICT_ALL);

num_sublists = multilist_get_num_sublists(ml);

/*
Expand Down Expand Up @@ -4187,7 +4174,7 @@ arc_evict_state(arc_state_t *state, uint64_t spa, int64_t bytes,
* While we haven't hit our target number of bytes to evict, or
* we're evicting all available buffers.
*/
while (total_evicted < bytes || bytes == ARC_EVICT_ALL) {
while (total_evicted < bytes) {
int sublist_idx = multilist_get_random_index(ml);
uint64_t scan_evicted = 0;

Expand Down Expand Up @@ -4215,9 +4202,7 @@ arc_evict_state(arc_state_t *state, uint64_t spa, int64_t bytes,
uint64_t bytes_remaining;
uint64_t bytes_evicted;

if (bytes == ARC_EVICT_ALL)
bytes_remaining = ARC_EVICT_ALL;
else if (total_evicted < bytes)
if (total_evicted < bytes)
bytes_remaining = bytes - total_evicted;
else
break;
Expand Down Expand Up @@ -4312,7 +4297,7 @@ static uint64_t
arc_evict_impl(arc_state_t *state, uint64_t spa, int64_t bytes,
arc_buf_contents_t type)
{
int64_t delta;
uint64_t delta;

if (bytes > 0 && zfs_refcount_count(&state->arcs_esize[type]) > 0) {
delta = MIN(zfs_refcount_count(&state->arcs_esize[type]),
Expand Down Expand Up @@ -7563,13 +7548,6 @@ arc_tuning_update(boolean_t verbose)
static void
arc_state_init(void)
{
arc_anon = &ARC_anon;
arc_mru = &ARC_mru;
arc_mru_ghost = &ARC_mru_ghost;
arc_mfu = &ARC_mfu;
arc_mfu_ghost = &ARC_mfu_ghost;
arc_l2c_only = &ARC_l2c_only;

multilist_create(&arc_mru->arcs_list[ARC_BUFC_METADATA],
sizeof (arc_buf_hdr_t),
offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
Expand Down