Skip to content

Commit

Permalink
Update arc_c under a mutex
Browse files Browse the repository at this point in the history
The arc_c value can be updated concurrently by multiple threads including
the arc reclaim thread, kswapd, kthreadd and user processes.  This patch
updates it under a mutex to close the race between the checking of its
value and subsequent updates.

Reverts: 935434e
Fixes: openzfs#3904
Fixes: openzfs#4161
  • Loading branch information
Tim Chase authored and kernelOfTruth committed Jan 16, 2016
1 parent d21f279 commit ecc4ec0
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ static kmutex_t arc_prune_mtx;
static taskq_t *arc_prune_taskq;
static arc_buf_t *arc_eviction_list;
static arc_buf_hdr_t arc_eviction_hdr;
static kmutex_t arc_c_mtx;

#define GHOST_STATE(state) \
((state) == arc_mru_ghost || (state) == arc_mfu_ghost || \
Expand Down Expand Up @@ -3183,6 +3184,7 @@ arc_flush(spa_t *spa, boolean_t retry)
void
arc_shrink(int64_t to_free)
{
mutex_enter(&arc_c_mtx);
if (arc_c > arc_c_min) {

if (arc_c > arc_c_min + to_free)
Expand All @@ -3198,6 +3200,7 @@ arc_shrink(int64_t to_free)
ASSERT(arc_c >= arc_c_min);
ASSERT((int64_t)arc_p >= 0);
}
mutex_exit(&arc_c_mtx);

if (arc_size > arc_c)
(void) arc_adjust();
Expand Down Expand Up @@ -3766,8 +3769,8 @@ arc_adapt(int bytes, arc_state_t *state)
* If we're within (2 * maxblocksize) bytes of the target
* cache size, increment the target cache size
*/
ASSERT3U(arc_c, >=, 2ULL << SPA_MAXBLOCKSHIFT);
arc_c = MAX(arc_c, 2ULL << SPA_MAXBLOCKSHIFT);
VERIFY3U(arc_c, >=, 2ULL << SPA_MAXBLOCKSHIFT);
mutex_enter(&arc_c_mtx);
if (arc_size >= arc_c - (2ULL << SPA_MAXBLOCKSHIFT)) {
atomic_add_64(&arc_c, (int64_t)bytes);
if (arc_c > arc_c_max)
Expand All @@ -3777,6 +3780,7 @@ arc_adapt(int bytes, arc_state_t *state)
if (arc_p > arc_c)
arc_p = arc_c;
}
mutex_exit(&arc_c_mtx);
ASSERT((int64_t)arc_p >= 0);
}

Expand Down Expand Up @@ -5160,8 +5164,10 @@ arc_tempreserve_space(uint64_t reserve, uint64_t txg)
int error;
uint64_t anon_size;

mutex_enter(&arc_c_mtx);
if (reserve > arc_c/4 && !arc_no_grow)
arc_c = MIN(arc_c_max, reserve * 4);
mutex_exit(&arc_c_mtx);

/*
* Throttle when the calculated memory footprint for the TXG
Expand Down Expand Up @@ -5512,6 +5518,7 @@ arc_init(void)
arc_eviction_list = NULL;
mutex_init(&arc_prune_mtx, NULL, MUTEX_DEFAULT, NULL);
bzero(&arc_eviction_hdr, sizeof (arc_buf_hdr_t));
mutex_init(&arc_c_mtx, NULL, MUTEX_DEFAULT, NULL);

arc_prune_taskq = taskq_create("arc_prune", max_ncpus, defclsyspri,
max_ncpus, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
Expand Down Expand Up @@ -5612,6 +5619,7 @@ arc_fini(void)
list_destroy(&arc_prune_list);
mutex_destroy(&arc_prune_mtx);
mutex_destroy(&arc_reclaim_lock);
mutex_destroy(&arc_c_mtx);
cv_destroy(&arc_reclaim_thread_cv);
cv_destroy(&arc_reclaim_waiters_cv);

Expand Down

0 comments on commit ecc4ec0

Please sign in to comment.