Commit 0b4989eb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'bcachefs-2024-06-12' of https://evilpiepirate.org/git/bcachefs

Pull bcachefs fixes from Kent Overstreet:

 - fix kworker explosion, due to calling submit_bio() (which can block)
   from a multithreaded workqueue

 - fix error handling in btree node scan

 - forward compat fix: kill an old debug assert

 - key cache shrinker fixes

   This is a partial fix for stalls doing multithreaded creates - there
   were various O(n^2) issues the key cache shrinker was hitting [1].

   There's more work coming here; I'm working on a patch to delete the
   key cache lock, which initial testing shows to be a pretty drastic
   performance improvement

 - assorted syzbot fixes

Link: https://lore.kernel.org/linux-bcachefs/CAGudoHGenxzk0ZqPXXi1_QDbfqQhGHu+wUwzyS6WmfkUZ1HiXA@mail.gmail.com/ [1]

* tag 'bcachefs-2024-06-12' of https://evilpiepirate.org/git/bcachefs:
  bcachefs: Fix rcu_read_lock() leak in drop_extra_replicas
  bcachefs: Add missing bch_inode_info.ei_flags init
  bcachefs: Add missing synchronize_srcu_expedited() call when shutting down
  bcachefs: Check for invalid bucket from bucket_gen(), gc_bucket()
  bcachefs: Replace bucket_valid() asserts in bucket lookup with proper checks
  bcachefs: Fix snapshot_create_lock lock ordering
  bcachefs: Fix refcount leak in check_fix_ptrs()
  bcachefs: Leave a buffer in the btree key cache to avoid lock thrashing
  bcachefs: Fix reporting of freed objects from key cache shrinker
  bcachefs: set sb->s_shrinker->seeks = 0
  bcachefs: increase key cache shrinker batch size
  bcachefs: Enable automatic shrinking for rhashtables
  bcachefs: fix the display format for show-super
  bcachefs: fix stack frame size in fsck.c
  bcachefs: Delete incorrect BTREE_ID_NR assertion
  bcachefs: Fix incorrect error handling found_btree_node_is_readable()
  bcachefs: Split out btree_write_submit_wq
parents cea2a265 f2736b9c
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -741,6 +741,7 @@ int bch2_trigger_alloc(struct btree_trans *trans,
		       enum btree_iter_update_trigger_flags flags)
{
	struct bch_fs *c = trans->c;
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	struct bch_dev *ca = bch2_dev_bucket_tryget(c, new.k->p);
@@ -860,8 +861,14 @@ int bch2_trigger_alloc(struct btree_trans *trans,
		}

		percpu_down_read(&c->mark_lock);
		if (new_a->gen != old_a->gen)
			*bucket_gen(ca, new.k->p.offset) = new_a->gen;
		if (new_a->gen != old_a->gen) {
			u8 *gen = bucket_gen(ca, new.k->p.offset);
			if (unlikely(!gen)) {
				percpu_up_read(&c->mark_lock);
				goto invalid_bucket;
			}
			*gen = new_a->gen;
		}

		bch2_dev_usage_update(c, ca, old_a, new_a, journal_seq, false);
		percpu_up_read(&c->mark_lock);
@@ -895,6 +902,11 @@ int bch2_trigger_alloc(struct btree_trans *trans,

		percpu_down_read(&c->mark_lock);
		struct bucket *g = gc_bucket(ca, new.k->p.offset);
		if (unlikely(!g)) {
			percpu_up_read(&c->mark_lock);
			goto invalid_bucket;
		}
		g->gen_valid	= 1;

		bucket_lock(g);

@@ -910,8 +922,14 @@ int bch2_trigger_alloc(struct btree_trans *trans,
		percpu_up_read(&c->mark_lock);
	}
err:
	printbuf_exit(&buf);
	bch2_dev_put(ca);
	return ret;
invalid_bucket:
	bch2_fs_inconsistent(c, "reference to invalid bucket\n  %s",
			     (bch2_bkey_val_to_text(&buf, c, new.s_c), buf.buf));
	ret = -EIO;
	goto err;
}

/*
+2 −1
Original line number Diff line number Diff line
@@ -790,7 +790,8 @@ struct bch_fs {

	/* BTREE CACHE */
	struct bio_set		btree_bio;
	struct workqueue_struct	*io_complete_wq;
	struct workqueue_struct	*btree_read_complete_wq;
	struct workqueue_struct	*btree_write_submit_wq;

	struct btree_root	btree_roots_known[BTREE_ID_NR];
	DARRAY(struct btree_root) btree_roots_extra;
+5 −4
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ static const struct rhashtable_params bch_btree_cache_params = {
	.key_offset		= offsetof(struct btree, hash_val),
	.key_len		= sizeof(u64),
	.obj_cmpfn		= bch2_btree_cache_cmp_fn,
	.automatic_shrinking	= true,
};

static int btree_node_data_alloc(struct bch_fs *c, struct btree *b, gfp_t gfp)
+12 −5
Original line number Diff line number Diff line
@@ -874,6 +874,9 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
	const struct bch_alloc_v4 *old;
	int ret;

	if (!bucket_valid(ca, k.k->p.offset))
		return 0;

	old = bch2_alloc_to_v4(k, &old_convert);
	gc = new = *old;

@@ -990,6 +993,8 @@ static int bch2_gc_alloc_start(struct bch_fs *c)

		buckets->first_bucket	= ca->mi.first_bucket;
		buckets->nbuckets	= ca->mi.nbuckets;
		buckets->nbuckets_minus_first =
			buckets->nbuckets - buckets->first_bucket;
		rcu_assign_pointer(ca->buckets_gc, buckets);
	}

@@ -1003,12 +1008,14 @@ static int bch2_gc_alloc_start(struct bch_fs *c)
				continue;
			}

			if (bucket_valid(ca, k.k->p.offset)) {
				struct bch_alloc_v4 a_convert;
				const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &a_convert);

				struct bucket *g = gc_bucket(ca, k.k->p.offset);
				g->gen_valid	= 1;
				g->gen		= a->gen;
			}
			0;
		})));
	bch2_dev_put(ca);
+4 −4
Original line number Diff line number Diff line
@@ -1389,7 +1389,7 @@ static void btree_node_read_endio(struct bio *bio)
		bch2_latency_acct(ca, rb->start_time, READ);
	}

	queue_work(c->io_complete_wq, &rb->work);
	queue_work(c->btree_read_complete_wq, &rb->work);
}

struct btree_node_read_all {
@@ -1656,7 +1656,7 @@ static int btree_node_read_all_replicas(struct bch_fs *c, struct btree *b, bool
		btree_node_read_all_replicas_done(&ra->cl.work);
	} else {
		continue_at(&ra->cl, btree_node_read_all_replicas_done,
			    c->io_complete_wq);
			    c->btree_read_complete_wq);
	}

	return 0;
@@ -1737,7 +1737,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b,
		if (sync)
			btree_node_read_work(&rb->work);
		else
			queue_work(c->io_complete_wq, &rb->work);
			queue_work(c->btree_read_complete_wq, &rb->work);
	}
}

@@ -2229,7 +2229,7 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b, unsigned flags)
	atomic64_add(bytes_to_write, &c->btree_write_stats[type].bytes);

	INIT_WORK(&wbio->work, btree_write_submit);
	queue_work(c->io_complete_wq, &wbio->work);
	queue_work(c->btree_write_submit_wq, &wbio->work);
	return;
err:
	set_btree_node_noevict(b);
Loading