Commit ca71df31 authored by Tang Junhui's avatar Tang Junhui Committed by Jens Axboe

bcache: fix using of loop variable in memory shrink

In bch_mca_scan(), There are some confusion and logical error in the use of
loop variables. In this patch, we clarify them as:
1) nr: the number of btree nodes needs to scan, which will decrease after
we scan a btree node, and should not be less than 0;
2) i: the number of btree nodes have scanned, includes both
btree_cache_freeable and btree_cache, which should not be bigger than
btree_cache_used;
3) freed: the number of btree nodes have freed.
Signed-off-by: default avatarTang Junhui <tang.junhui@zte.com.cn>
Reviewed-by: default avatarMichael Lyle <mlyle@lyle.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent f3641c3a
...@@ -665,6 +665,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink, ...@@ -665,6 +665,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
struct btree *b, *t; struct btree *b, *t;
unsigned long i, nr = sc->nr_to_scan; unsigned long i, nr = sc->nr_to_scan;
unsigned long freed = 0; unsigned long freed = 0;
unsigned int btree_cache_used;
if (c->shrinker_disabled) if (c->shrinker_disabled)
return SHRINK_STOP; return SHRINK_STOP;
...@@ -689,9 +690,10 @@ static unsigned long bch_mca_scan(struct shrinker *shrink, ...@@ -689,9 +690,10 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
nr = min_t(unsigned long, nr, mca_can_free(c)); nr = min_t(unsigned long, nr, mca_can_free(c));
i = 0; i = 0;
btree_cache_used = c->btree_cache_used;
list_for_each_entry_safe(b, t, &c->btree_cache_freeable, list) { list_for_each_entry_safe(b, t, &c->btree_cache_freeable, list) {
if (freed >= nr) if (nr <= 0)
break; goto out;
if (++i > 3 && if (++i > 3 &&
!mca_reap(b, 0, false)) { !mca_reap(b, 0, false)) {
...@@ -699,9 +701,10 @@ static unsigned long bch_mca_scan(struct shrinker *shrink, ...@@ -699,9 +701,10 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
rw_unlock(true, b); rw_unlock(true, b);
freed++; freed++;
} }
nr--;
} }
for (i = 0; (nr--) && i < c->btree_cache_used; i++) { for (; (nr--) && i < btree_cache_used; i++) {
if (list_empty(&c->btree_cache)) if (list_empty(&c->btree_cache))
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment