Skip to content

Commit

Permalink
Fixed endless loop for ARC_EVICT_ALL eviction
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-stetsenko committed Jan 14, 2025
1 parent 58974b0 commit a70c007
Showing 1 changed file with 25 additions and 10 deletions.
35 changes: 25 additions & 10 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4077,22 +4077,21 @@ typedef struct evict_arg {
arc_buf_hdr_t *marker;
uint64_t spa;
uint64_t bytes;
uint64_t *evicted_ptr;
uint64_t evicted;
} evict_arg_t;

static void
arc_evict_task(void *arg)
{
evict_arg_t *eva = arg;
uint64_t *evictedp = eva->evicted_ptr;
multilist_t *ml = eva->ml;
arc_buf_hdr_t *marker = eva->marker;
int idx = eva->idx;
uint64_t spa = eva->spa;
uint64_t evict = eva->bytes;
uint64_t bytes_evicted = arc_evict_state_impl(ml, idx, marker, spa,

eva->evicted = arc_evict_state_impl(ml, idx, marker, spa,
evict);
atomic_add_64(evictedp, bytes_evicted);
}

/*
Expand Down Expand Up @@ -4172,21 +4171,33 @@ arc_evict_state(arc_state_t *state, arc_buf_contents_t type, uint64_t spa,
bytes - total_evicted);
uint64_t evict;
uint_t ntasks;
uint_t m = 0;

if (use_evcttq) {
if (left > nthreads * MIN_EVICT_SIZE) {
evict = DIV_ROUND_UP(left, nthreads);
/*
* Scaling algorithm:
* 1. Divide the left bytes by chunks each
* MIN_EVICT_SIZE.
* 2. Equaly distribute the chunks between the threads.
* 3. First (m) threads get an additional chunk each.
*/
if (left == ARC_EVICT_ALL) {
ntasks = nthreads;
evict = left;
} else if (left > nthreads * MIN_EVICT_SIZE) {
ntasks = nthreads;
uint64_t n = DIV_ROUND_UP(left, MIN_EVICT_SIZE);
evict = (n / nthreads) * MIN_EVICT_SIZE;
m = n % nthreads; /* additional chunks */
} else {
evict = MIN_EVICT_SIZE;
ntasks = DIV_ROUND_UP(left, MIN_EVICT_SIZE);
evict = MIN_EVICT_SIZE;
}
} else {
ntasks = num_sublists;
evict = left;
}


/*
* Start eviction using a randomly selected sublist,
* this is to try and evenly balance eviction across all
Expand All @@ -4207,9 +4218,10 @@ arc_evict_state(arc_state_t *state, arc_buf_contents_t type, uint64_t spa,
evarg[i].ml = ml;
evarg[i].marker = markers[sublist_idx];
evarg[i].spa = spa;
evarg[i].evicted_ptr = &scan_evicted;
evarg[i].idx = sublist_idx;
evarg[i].bytes = evict;
if (i < m)
evarg[i].bytes += MIN_EVICT_SIZE;

taskq_dispatch_ent(arc_evict_taskq,
arc_evict_task,
Expand All @@ -4231,7 +4243,10 @@ arc_evict_state(arc_state_t *state, arc_buf_contents_t type, uint64_t spa,

if (use_evcttq) {
taskq_wait(arc_evict_taskq);
total_evicted += scan_evicted;
for (unsigned i = 0; i < ntasks; i++) {
scan_evicted += evarg[i].evicted;
total_evicted += evarg[i].evicted;
}
}

/*
Expand Down

0 comments on commit a70c007

Please sign in to comment.