summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-06-19 17:51:18 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2020-06-28 18:12:46 -0400
commit9facbb021240c6f57a950eda10ffb760c973daff (patch)
treee7bd34c69a98be02a701d2843a961a0f8856d95c
parent1e66bb1860dd117073730dd73603961e1e8fbb51 (diff)
foo
-rw-r--r--fs/bcachefs/btree_cache.c65
-rw-r--r--fs/bcachefs/debug.c9
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,