mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-01 09:34:10 -04:00
fixup bcachefs: Deadlock cycle detector
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
@@ -99,6 +99,12 @@ static void lock_graph_up(struct lock_graph *g)
|
||||
closure_put(&g->g[--g->nr].trans->ref);
|
||||
}
|
||||
|
||||
static noinline void lock_graph_pop_all(struct lock_graph *g)
|
||||
{
|
||||
while (g->nr)
|
||||
lock_graph_up(g);
|
||||
}
|
||||
|
||||
static void lock_graph_down(struct lock_graph *g, struct btree_trans *trans)
|
||||
{
|
||||
closure_get(&trans->ref);
|
||||
@@ -274,8 +280,26 @@ int bch2_check_for_deadlock(struct btree_trans *trans, struct printbuf *cycle)
|
||||
|
||||
b = &READ_ONCE(path->l[top->level].b)->c;
|
||||
|
||||
if (unlikely(IS_ERR_OR_NULL(b))) {
|
||||
BUG_ON(!lock_graph_remove_non_waiters(&g));
|
||||
if (IS_ERR_OR_NULL(b)) {
|
||||
/*
|
||||
* If we get here, it means we raced with the
|
||||
* other thread updating its btree_path
|
||||
* structures - which means it can't be blocked
|
||||
* waiting on a lock:
|
||||
*/
|
||||
if (!lock_graph_remove_non_waiters(&g)) {
|
||||
/*
|
||||
* If lock_graph_remove_non_waiters()
|
||||
* didn't do anything, it must be
|
||||
* because we're being called by debugfs
|
||||
* checking for lock cycles, which
|
||||
* invokes us on btree_transactions that
|
||||
* aren't actually waiting on anything.
|
||||
* Just bail out:
|
||||
*/
|
||||
lock_graph_pop_all(&g);
|
||||
}
|
||||
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user