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 dweeezil committed Jan 10, 2016
1 parent e9e3d31 commit c0f091a
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,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 @@ -3179,6 +3180,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 @@ -3195,8 +3197,11 @@ arc_shrink(int64_t to_free)
ASSERT((int64_t)arc_p >= 0);
}

if (arc_size > arc_c)
if (arc_size > arc_c) {
mutex_exit(&arc_c_mtx);
(void) arc_adjust();
} else
mutex_exit(&arc_c_mtx);
}

typedef enum free_memory_reason_t {
Expand Down Expand Up @@ -3762,8 +3767,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 @@ -3773,6 +3778,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 @@ -5442,6 +5448,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 @@ -5542,6 +5549,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 c0f091a

Please sign in to comment.