Commit c2b2c7d1 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Tweak btree cache helpers for use by btree node scan



btree node scan needs to not use the btree node cache: that causes
interference from prior failed reads and parallel workers.

Instead we need to allocate btree nodes that don't live in the btree
cache, so that we can call bch2_btree_node_read_done() directly.

This patch tweaks the low level helpers so they don't touch the btree
cache lists.

Cc: Nikita Ofitserov <himikof@gmail.com>
Reviewed-by: default avatarNikita Ofitserov <himikof@gmail.com>
Reported-and-tested-by: default avatarEdoardo Codeglia <bcachefs@404.blue>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent c72d6284
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ void bch2_btree_node_to_freelist(struct bch_fs *c, struct btree *b)
	six_unlock_intent(&b->c.lock);
}

static void __btree_node_data_free(struct btree_cache *bc, struct btree *b)
void __btree_node_data_free(struct btree *b)
{
	BUG_ON(!list_empty(&b->list));
	BUG_ON(btree_node_hashed(b));
@@ -112,16 +112,17 @@ static void __btree_node_data_free(struct btree_cache *bc, struct btree *b)
	munmap(b->aux_data, btree_aux_data_bytes(b));
#endif
	b->aux_data = NULL;

	btree_node_to_freedlist(bc, b);
}

static void btree_node_data_free(struct btree_cache *bc, struct btree *b)
{
	BUG_ON(list_empty(&b->list));
	list_del_init(&b->list);

	__btree_node_data_free(b);

	--bc->nr_freeable;
	__btree_node_data_free(bc, b);
	btree_node_to_freedlist(bc, b);
}

static int bch2_btree_cache_cmp_fn(struct rhashtable_compare_arg *arg,
@@ -185,10 +186,7 @@ static struct btree *__btree_node_mem_alloc(struct bch_fs *c, gfp_t gfp)

struct btree *__bch2_btree_node_mem_alloc(struct bch_fs *c)
{
	struct btree_cache *bc = &c->btree_cache;
	struct btree *b;

	b = __btree_node_mem_alloc(c, GFP_KERNEL);
	struct btree *b = __btree_node_mem_alloc(c, GFP_KERNEL);
	if (!b)
		return NULL;

@@ -198,8 +196,6 @@ struct btree *__bch2_btree_node_mem_alloc(struct bch_fs *c)
	}

	bch2_btree_lock_init(&b->c, 0, GFP_KERNEL);

	__bch2_btree_node_to_freelist(bc, b);
	return b;
}

@@ -524,7 +520,8 @@ static unsigned long bch2_btree_cache_scan(struct shrinker *shrink,
			--touched;;
		} else if (!btree_node_reclaim(c, b)) {
			__bch2_btree_node_hash_remove(bc, b);
			__btree_node_data_free(bc, b);
			__btree_node_data_free(b);
			btree_node_to_freedlist(bc, b);

			freed++;
			bc->nr_freed++;
@@ -652,9 +649,12 @@ int bch2_fs_btree_cache_init(struct bch_fs *c)

	bch2_recalc_btree_reserve(c);

	for (i = 0; i < bc->nr_reserve; i++)
		if (!__bch2_btree_node_mem_alloc(c))
	for (i = 0; i < bc->nr_reserve; i++) {
		struct btree *b = __bch2_btree_node_mem_alloc(c);
		if (!b)
			goto err;
		__bch2_btree_node_to_freelist(bc, b);
	}

	list_splice_init(&bc->live[0].list, &bc->freeable);

+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ void bch2_btree_node_update_key_early(struct btree_trans *, enum btree_id, unsig
void bch2_btree_cache_cannibalize_unlock(struct btree_trans *);
int bch2_btree_cache_cannibalize_lock(struct btree_trans *, struct closure *);

void __btree_node_data_free(struct btree *);
struct btree *__bch2_btree_node_mem_alloc(struct bch_fs *);
struct btree *bch2_btree_node_mem_alloc(struct btree_trans *, bool);

+0 −2
Original line number Diff line number Diff line
@@ -153,8 +153,6 @@ void __bch2_btree_verify(struct bch_fs *c, struct btree *b)
		c->verify_data = __bch2_btree_node_mem_alloc(c);
		if (!c->verify_data)
			goto out;

		list_del_init(&c->verify_data->list);
	}

	BUG_ON(b->nsets != 1);