diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-06-19 17:51:18 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2020-06-28 18:12:46 -0400 |
commit | 9facbb021240c6f57a950eda10ffb760c973daff (patch) | |
tree | e7bd34c69a98be02a701d2843a961a0f8856d95c | |
parent | 1e66bb1860dd117073730dd73603961e1e8fbb51 (diff) |
foo
-rw-r--r-- | fs/bcachefs/btree_cache.c | 65 | ||||
-rw-r--r-- | fs/bcachefs/debug.c | 9 |
2 files changed, 39 insertions, 35 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index d3addd3a8964..c7030b0fd689 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -242,9 +242,8 @@ static unsigned long bch2_btree_cache_scan(struct shrinker *shrink, struct btree *b, *t; unsigned long nr = sc->nr_to_scan; unsigned long can_free; - unsigned long touched = 0; unsigned long freed = 0; - unsigned i; + unsigned long freeable = 0, live = 0, accessed = 0; if (btree_shrinker_disabled(c)) return SHRINK_STOP; @@ -266,60 +265,56 @@ static unsigned long bch2_btree_cache_scan(struct shrinker *shrink, can_free = btree_cache_can_free(bc); nr = min_t(unsigned long, nr, can_free); - i = 0; + pr_info("trying to free %lu/%lu", nr, can_free); + list_for_each_entry_safe(b, t, &bc->freeable, list) { - touched++; + freeable++; - if (freed >= nr) - break; + /* + * Leave a few on the freeable list, this significantly reduces + * the number of btree node memory allocations we have to do: + */ + if (freeable <= 3) + continue; - if (++i > 3 && - !btree_node_reclaim(c, b)) { + if (!btree_node_reclaim(c, b)) { btree_node_data_free(c, b); six_unlock_write(&b->c.lock); six_unlock_intent(&b->c.lock); freed++; } - } -restart: - list_for_each_entry_safe(b, t, &bc->live, list) { - touched++; - if (freed >= nr) { - /* Save position */ - if (&t->list != &bc->live) - list_move_tail(&bc->live, &t->list); + if (freed >= nr) break; - } + } - if (!btree_node_accessed(b) && - !btree_node_reclaim(c, b)) { - /* can't call bch2_btree_node_hash_remove under lock */ - freed++; - if (&t->list != &bc->live) - list_move_tail(&bc->live, &t->list); + list_for_each_entry_safe(b, t, &bc->live, list) { + live++; + if (btree_node_accessed(b)) { + clear_btree_node_accessed(b); + accessed++; + } else if (!btree_node_reclaim(c, b)) { btree_node_data_free(c, b); - mutex_unlock(&bc->lock); - bch2_btree_node_hash_remove(bc, b); six_unlock_write(&b->c.lock); six_unlock_intent(&b->c.lock); - if (freed >= nr) - goto out; + freed++; + } - if (sc->gfp_mask & __GFP_FS) - mutex_lock(&bc->lock); - else if (!mutex_trylock(&bc->lock)) - goto out; - goto restart; - } else - clear_btree_node_accessed(b); + if (freed >= nr) { + /* Save position */ + if (&t->list != &bc->live) + list_move_tail(&bc->live, &t->list); + break; + } } mutex_unlock(&bc->lock); -out: + + pr_info("freeable %lu live %lu accessed %lu freed %lu", + freeable, live, accessed, freed); return (unsigned long) freed * btree_pages(c); } diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c index aa10591a3b1a..8db1d4ce901a 100644 --- a/fs/bcachefs/debug.c +++ b/fs/bcachefs/debug.c @@ -86,6 +86,15 @@ void __bch2_btree_verify(struct bch_fs *c, struct btree *b) sorted = &n_sorted->keys; inmemory = &n_inmemory->keys; + { + struct bkey_packed *k; + + vstruct_for_each(inmemory, k) + if (k->type == KEY_TYPE_btree_ptr_v2) + ((struct bch_btree_ptr_v2 *) + bkeyp_val(&b->format, k))->mem_ptr = 0; + } + if (inmemory->u64s != sorted->u64s || memcmp(inmemory->start, sorted->start, |