Lines Matching full:g
69 struct trans_waiting_for_lock g[8]; member
73 static noinline void print_cycle(struct printbuf *out, struct lock_graph *g) in print_cycle() argument
77 prt_printf(out, "Found lock cycle (%u entries):\n", g->nr); in print_cycle()
79 for (i = g->g; i < g->g + g->nr; i++) { in print_cycle()
85 bch2_prt_task_backtrace(out, task, i == g->g ? 5 : 1, GFP_NOWAIT); in print_cycle()
89 static noinline void print_chain(struct printbuf *out, struct lock_graph *g) in print_chain() argument
93 for (i = g->g; i != g->g + g->nr; i++) { in print_chain()
95 if (i != g->g) in print_chain()
102 static void lock_graph_up(struct lock_graph *g) in lock_graph_up() argument
104 closure_put(&g->g[--g->nr].trans->ref); in lock_graph_up()
107 static noinline void lock_graph_pop_all(struct lock_graph *g) in lock_graph_pop_all() argument
109 while (g->nr) in lock_graph_pop_all()
110 lock_graph_up(g); in lock_graph_pop_all()
113 static noinline void lock_graph_pop_from(struct lock_graph *g, struct trans_waiting_for_lock *i) in lock_graph_pop_from() argument
115 while (g->g + g->nr > i) in lock_graph_pop_from()
116 lock_graph_up(g); in lock_graph_pop_from()
119 static void __lock_graph_down(struct lock_graph *g, struct btree_trans *trans) in __lock_graph_down() argument
121 g->g[g->nr++] = (struct trans_waiting_for_lock) { in __lock_graph_down()
128 static void lock_graph_down(struct lock_graph *g, struct btree_trans *trans) in lock_graph_down() argument
131 __lock_graph_down(g, trans); in lock_graph_down()
134 static bool lock_graph_remove_non_waiters(struct lock_graph *g, in lock_graph_remove_non_waiters() argument
140 lock_graph_pop_from(g, from); in lock_graph_remove_non_waiters()
144 for (i = from + 1; i < g->g + g->nr; i++) in lock_graph_remove_non_waiters()
147 lock_graph_pop_from(g, i); in lock_graph_remove_non_waiters()
154 static void trace_would_deadlock(struct lock_graph *g, struct btree_trans *trans) in trace_would_deadlock() argument
164 print_cycle(&buf, g); in trace_would_deadlock()
171 static int abort_lock(struct lock_graph *g, struct trans_waiting_for_lock *i) in abort_lock() argument
173 if (i == g->g) { in abort_lock()
174 trace_would_deadlock(g, i->trans); in abort_lock()
196 static noinline int break_cycle(struct lock_graph *g, struct printbuf *cycle, in break_cycle() argument
203 if (lock_graph_remove_non_waiters(g, from)) in break_cycle()
208 print_cycle(cycle, g); in break_cycle()
213 for (i = from; i < g->g + g->nr; i++) { in break_cycle()
225 prt_printf(&buf, bch2_fmt(g->g->trans->c, "cycle of nofail locks")); in break_cycle()
227 for (i = g->g; i < g->g + g->nr; i++) { in break_cycle()
244 ret = abort_lock(g, abort); in break_cycle()
247 lock_graph_pop_all(g); in break_cycle()
249 lock_graph_pop_from(g, abort); in break_cycle()
253 static int lock_graph_descend(struct lock_graph *g, struct btree_trans *trans, in lock_graph_descend() argument
256 struct btree_trans *orig_trans = g->g->trans; in lock_graph_descend()
259 for (i = g->g; i < g->g + g->nr; i++) in lock_graph_descend()
262 return break_cycle(g, cycle, i); in lock_graph_descend()
265 if (g->nr == ARRAY_SIZE(g->g)) { in lock_graph_descend()
271 lock_graph_pop_all(g); in lock_graph_descend()
280 __lock_graph_down(g, trans); in lock_graph_descend()
291 struct lock_graph g; in bch2_check_for_deadlock() local
297 g.nr = 0; in bch2_check_for_deadlock()
303 trace_would_deadlock(&g, trans); in bch2_check_for_deadlock()
307 lock_graph_down(&g, trans); in bch2_check_for_deadlock()
314 if (!g.nr) in bch2_check_for_deadlock()
317 top = &g.g[g.nr - 1]; in bch2_check_for_deadlock()
354 if (!lock_graph_remove_non_waiters(&g, g.g)) { in bch2_check_for_deadlock()
364 lock_graph_pop_all(&g); in bch2_check_for_deadlock()
391 ret = lock_graph_descend(&g, trans, cycle); in bch2_check_for_deadlock()
401 if (g.nr > 1 && cycle) in bch2_check_for_deadlock()
402 print_chain(cycle, &g); in bch2_check_for_deadlock()
403 lock_graph_up(&g); in bch2_check_for_deadlock()