Commit a0a466ea authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Split out btree_node_rewrite_worker

This fixes a deadlock due to using btree_interior_update_worker for non
interior updates - async btree node rewrites were blocking, and then
blocking other interior updates.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 37bb9c95
...@@ -849,6 +849,8 @@ struct bch_fs { ...@@ -849,6 +849,8 @@ struct bch_fs {
struct workqueue_struct *btree_interior_update_worker; struct workqueue_struct *btree_interior_update_worker;
struct work_struct btree_interior_update_work; struct work_struct btree_interior_update_work;
struct workqueue_struct *btree_node_rewrite_worker;
struct list_head pending_node_rewrites; struct list_head pending_node_rewrites;
struct mutex pending_node_rewrites_lock; struct mutex pending_node_rewrites_lock;
......
...@@ -2161,7 +2161,7 @@ void bch2_btree_node_rewrite_async(struct bch_fs *c, struct btree *b) ...@@ -2161,7 +2161,7 @@ void bch2_btree_node_rewrite_async(struct bch_fs *c, struct btree *b)
bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite); bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite);
} }
queue_work(c->btree_interior_update_worker, &a->work); queue_work(c->btree_node_rewrite_worker, &a->work);
} }
void bch2_do_pending_node_rewrites(struct bch_fs *c) void bch2_do_pending_node_rewrites(struct bch_fs *c)
...@@ -2173,7 +2173,7 @@ void bch2_do_pending_node_rewrites(struct bch_fs *c) ...@@ -2173,7 +2173,7 @@ void bch2_do_pending_node_rewrites(struct bch_fs *c)
list_del(&a->list); list_del(&a->list);
bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite); bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite);
queue_work(c->btree_interior_update_worker, &a->work); queue_work(c->btree_node_rewrite_worker, &a->work);
} }
mutex_unlock(&c->pending_node_rewrites_lock); mutex_unlock(&c->pending_node_rewrites_lock);
} }
...@@ -2510,6 +2510,8 @@ bch2_btree_roots_to_journal_entries(struct bch_fs *c, ...@@ -2510,6 +2510,8 @@ bch2_btree_roots_to_journal_entries(struct bch_fs *c,
void bch2_fs_btree_interior_update_exit(struct bch_fs *c) void bch2_fs_btree_interior_update_exit(struct bch_fs *c)
{ {
if (c->btree_node_rewrite_worker)
destroy_workqueue(c->btree_node_rewrite_worker);
if (c->btree_interior_update_worker) if (c->btree_interior_update_worker)
destroy_workqueue(c->btree_interior_update_worker); destroy_workqueue(c->btree_interior_update_worker);
mempool_exit(&c->btree_interior_update_pool); mempool_exit(&c->btree_interior_update_pool);
...@@ -2534,6 +2536,11 @@ int bch2_fs_btree_interior_update_init(struct bch_fs *c) ...@@ -2534,6 +2536,11 @@ int bch2_fs_btree_interior_update_init(struct bch_fs *c)
if (!c->btree_interior_update_worker) if (!c->btree_interior_update_worker)
return -BCH_ERR_ENOMEM_btree_interior_update_worker_init; return -BCH_ERR_ENOMEM_btree_interior_update_worker_init;
c->btree_node_rewrite_worker =
alloc_ordered_workqueue("btree_node_rewrite", WQ_UNBOUND);
if (!c->btree_node_rewrite_worker)
return -BCH_ERR_ENOMEM_btree_interior_update_worker_init;
if (mempool_init_kmalloc_pool(&c->btree_interior_update_pool, 1, if (mempool_init_kmalloc_pool(&c->btree_interior_update_pool, 1,
sizeof(struct btree_update))) sizeof(struct btree_update)))
return -BCH_ERR_ENOMEM_btree_interior_update_pool_init; return -BCH_ERR_ENOMEM_btree_interior_update_pool_init;
......
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