Lines Matching refs:trans

18 struct six_lock_count bch2_btree_node_lock_counts(struct btree_trans *trans,  in bch2_btree_node_lock_counts()  argument
32 trans_for_each_path(trans, path, i) in bch2_btree_node_lock_counts()
45 void bch2_btree_node_unlock_write(struct btree_trans *trans, in bch2_btree_node_unlock_write() argument
48 bch2_btree_node_unlock_write_inlined(trans, path, b); in bch2_btree_node_unlock_write()
57 struct btree_trans *trans; member
79 struct task_struct *task = READ_ONCE(i->trans->locking_wait.task); in print_cycle()
83 bch2_btree_trans_to_text(out, i->trans); in print_cycle()
93 struct task_struct *task = i->trans->locking_wait.task; in print_chain()
103 closure_put(&g->g[--g->nr].trans->ref); in lock_graph_up()
112 static void __lock_graph_down(struct lock_graph *g, struct btree_trans *trans) in __lock_graph_down() argument
115 .trans = trans, in __lock_graph_down()
116 .node_want = trans->locking, in __lock_graph_down()
117 .lock_want = trans->locking_wait.lock_want, in __lock_graph_down()
121 static void lock_graph_down(struct lock_graph *g, struct btree_trans *trans) in lock_graph_down() argument
123 closure_get(&trans->ref); in lock_graph_down()
124 __lock_graph_down(g, trans); in lock_graph_down()
132 if (i->trans->locking != i->node_want || in lock_graph_remove_non_waiters()
133 i->trans->locking_wait.start_time != i[-1].lock_start_time) { in lock_graph_remove_non_waiters()
142 static void trace_would_deadlock(struct lock_graph *g, struct btree_trans *trans) in trace_would_deadlock() argument
144 struct bch_fs *c = trans->c; in trace_would_deadlock()
154 trace_trans_restart_would_deadlock(trans, buf.buf); in trace_would_deadlock()
162 trace_would_deadlock(g, i->trans); in abort_lock()
163 return btree_trans_restart(i->trans, BCH_ERR_transaction_restart_would_deadlock); in abort_lock()
165 i->trans->lock_must_abort = true; in abort_lock()
166 wake_up_process(i->trans->locking_wait.task); in abort_lock()
171 static int btree_trans_abort_preference(struct btree_trans *trans) in btree_trans_abort_preference() argument
173 if (trans->lock_may_not_fail) in btree_trans_abort_preference()
175 if (trans->locking_wait.lock_want == SIX_LOCK_write) in btree_trans_abort_preference()
177 if (!trans->in_traverse_all) in btree_trans_abort_preference()
199 pref = btree_trans_abort_preference(i->trans); in break_cycle()
210 prt_printf(&buf, bch2_fmt(g->g->trans->c, "cycle of nofail locks")); in break_cycle()
213 struct btree_trans *trans = i->trans; in break_cycle() local
215 bch2_btree_trans_to_text(&buf, trans); in break_cycle()
219 bch2_prt_task_backtrace(&buf, trans->locking_wait.task, 2, GFP_NOWAIT); in break_cycle()
237 static int lock_graph_descend(struct lock_graph *g, struct btree_trans *trans, in lock_graph_descend() argument
240 struct btree_trans *orig_trans = g->g->trans; in lock_graph_descend()
244 if (i->trans == trans) { in lock_graph_descend()
245 closure_put(&trans->ref); in lock_graph_descend()
250 closure_put(&trans->ref); in lock_graph_descend()
261 trace_and_count(trans->c, trans_restart_would_deadlock_recursion_limit, trans, _RET_IP_); in lock_graph_descend()
265 __lock_graph_down(g, trans); in lock_graph_descend()
274 int bch2_check_for_deadlock(struct btree_trans *trans, struct printbuf *cycle) in bch2_check_for_deadlock() argument
284 if (trans->lock_must_abort) { in bch2_check_for_deadlock()
288 trace_would_deadlock(&g, trans); in bch2_check_for_deadlock()
289 return btree_trans_restart(trans, BCH_ERR_transaction_restart_would_deadlock); in bch2_check_for_deadlock()
292 lock_graph_down(&g, trans); in bch2_check_for_deadlock()
304 struct btree_path *paths = rcu_dereference(top->trans->paths); in bch2_check_for_deadlock()
359 list_for_each_entry(trans, &b->lock.wait_list, locking_wait.list) { in bch2_check_for_deadlock()
360 BUG_ON(b != trans->locking); in bch2_check_for_deadlock()
363 time_after_eq64(top->lock_start_time, trans->locking_wait.start_time)) in bch2_check_for_deadlock()
366 top->lock_start_time = trans->locking_wait.start_time; in bch2_check_for_deadlock()
369 if (trans == top->trans || in bch2_check_for_deadlock()
370 !lock_type_conflicts(lock_held, trans->locking_wait.lock_want)) in bch2_check_for_deadlock()
373 closure_get(&trans->ref); in bch2_check_for_deadlock()
376 ret = lock_graph_descend(&g, trans, cycle); in bch2_check_for_deadlock()
399 struct btree_trans *trans = p; in bch2_six_check_for_deadlock() local
401 return bch2_check_for_deadlock(trans, NULL); in bch2_six_check_for_deadlock()
404 int __bch2_btree_node_lock_write(struct btree_trans *trans, struct btree_path *path, in __bch2_btree_node_lock_write() argument
408 int readers = bch2_btree_node_lock_counts(trans, NULL, b, b->level).n[SIX_LOCK_read]; in __bch2_btree_node_lock_write()
418 ret = __btree_node_lock_nopath(trans, b, SIX_LOCK_write, in __bch2_btree_node_lock_write()
428 void bch2_btree_node_lock_write_nofail(struct btree_trans *trans, in bch2_btree_node_lock_write_nofail() argument
432 int ret = __btree_node_lock_write(trans, path, b, true); in bch2_btree_node_lock_write_nofail()
438 static inline bool btree_path_get_locks(struct btree_trans *trans, in btree_path_get_locks() argument
451 ? bch2_btree_node_upgrade(trans, path, l) in btree_path_get_locks()
452 : bch2_btree_node_relock(trans, path, l))) { in btree_path_get_locks()
470 __bch2_btree_path_unlock(trans, path); in btree_path_get_locks()
487 bool __bch2_btree_node_relock(struct btree_trans *trans, in __bch2_btree_node_relock() argument
499 btree_node_lock_increment(trans, &b->c, level, want))) { in __bch2_btree_node_relock()
500 mark_btree_node_locked(trans, path, level, want); in __bch2_btree_node_relock()
504 if (trace && !trans->notrace_relock_fail) in __bch2_btree_node_relock()
505 trace_and_count(trans->c, btree_path_relock_fail, trans, _RET_IP_, path, level); in __bch2_btree_node_relock()
511 bool bch2_btree_node_upgrade(struct btree_trans *trans, in bch2_btree_node_upgrade() argument
515 struct six_lock_count count = bch2_btree_node_lock_counts(trans, path, &b->c, level); in bch2_btree_node_upgrade()
526 return bch2_btree_node_relock(trans, path, level); in bch2_btree_node_upgrade()
558 btree_node_lock_increment(trans, &b->c, level, BTREE_NODE_INTENT_LOCKED)) { in bch2_btree_node_upgrade()
559 btree_node_unlock(trans, path, level); in bch2_btree_node_upgrade()
563 trace_and_count(trans->c, btree_path_upgrade_fail, trans, _RET_IP_, path, level); in bch2_btree_node_upgrade()
575 int bch2_btree_path_relock_intent(struct btree_trans *trans, in bch2_btree_path_relock_intent() argument
583 if (!bch2_btree_node_relock(trans, path, l)) { in bch2_btree_path_relock_intent()
584 __bch2_btree_path_unlock(trans, path); in bch2_btree_path_relock_intent()
586 trace_and_count(trans->c, trans_restart_relock_path_intent, trans, _RET_IP_, path); in bch2_btree_path_relock_intent()
587 return btree_trans_restart(trans, BCH_ERR_transaction_restart_relock_path_intent); in bch2_btree_path_relock_intent()
595 bool bch2_btree_path_relock_norestart(struct btree_trans *trans, struct btree_path *path) in bch2_btree_path_relock_norestart() argument
599 bool ret = btree_path_get_locks(trans, path, false, &f); in bch2_btree_path_relock_norestart()
600 bch2_trans_verify_locks(trans); in bch2_btree_path_relock_norestart()
604 int __bch2_btree_path_relock(struct btree_trans *trans, in __bch2_btree_path_relock() argument
607 if (!bch2_btree_path_relock_norestart(trans, path)) { in __bch2_btree_path_relock()
608 trace_and_count(trans->c, trans_restart_relock_path, trans, trace_ip, path); in __bch2_btree_path_relock()
609 return btree_trans_restart(trans, BCH_ERR_transaction_restart_relock_path); in __bch2_btree_path_relock()
615 bool bch2_btree_path_upgrade_noupgrade_sibs(struct btree_trans *trans, in bch2_btree_path_upgrade_noupgrade_sibs() argument
624 bool ret = btree_path_get_locks(trans, path, true, f); in bch2_btree_path_upgrade_noupgrade_sibs()
625 bch2_trans_verify_locks(trans); in bch2_btree_path_upgrade_noupgrade_sibs()
629 bool __bch2_btree_path_upgrade(struct btree_trans *trans, in __bch2_btree_path_upgrade() argument
634 bool ret = bch2_btree_path_upgrade_noupgrade_sibs(trans, path, new_locks_want, f); in __bch2_btree_path_upgrade()
657 if (!path->cached && !trans->in_traverse_all) { in __bch2_btree_path_upgrade()
661 trans_for_each_path(trans, linked, i) in __bch2_btree_path_upgrade()
667 btree_path_get_locks(trans, linked, true, NULL); in __bch2_btree_path_upgrade()
671 bch2_trans_verify_locks(trans); in __bch2_btree_path_upgrade()
675 void __bch2_btree_path_downgrade(struct btree_trans *trans, in __bch2_btree_path_downgrade() argument
681 if (trans->restarted) in __bch2_btree_path_downgrade()
691 btree_node_unlock(trans, path, l); in __bch2_btree_path_downgrade()
703 trace_path_downgrade(trans, _RET_IP_, path, old_locks_want); in __bch2_btree_path_downgrade()
708 void bch2_trans_downgrade(struct btree_trans *trans) in bch2_trans_downgrade() argument
713 if (trans->restarted) in bch2_trans_downgrade()
716 trans_for_each_path(trans, path, i) in bch2_trans_downgrade()
718 bch2_btree_path_downgrade(trans, path); in bch2_trans_downgrade()
721 static inline void __bch2_trans_unlock(struct btree_trans *trans) in __bch2_trans_unlock() argument
726 trans_for_each_path(trans, path, i) in __bch2_trans_unlock()
727 __bch2_btree_path_unlock(trans, path); in __bch2_trans_unlock()
730 static noinline __cold int bch2_trans_relock_fail(struct btree_trans *trans, struct btree_path *pat… in bch2_trans_relock_fail() argument
747 bch2_btree_node_lock_counts(trans, NULL, &f->b->c, f->l); in bch2_trans_relock_fail()
754 trace_trans_restart_relock(trans, _RET_IP_, buf.buf); in bch2_trans_relock_fail()
758 count_event(trans->c, trans_restart_relock); in bch2_trans_relock_fail()
760 __bch2_trans_unlock(trans); in bch2_trans_relock_fail()
761 bch2_trans_verify_locks(trans); in bch2_trans_relock_fail()
762 return btree_trans_restart(trans, BCH_ERR_transaction_restart_relock); in bch2_trans_relock_fail()
765 static inline int __bch2_trans_relock(struct btree_trans *trans, bool trace) in __bch2_trans_relock() argument
767 bch2_trans_verify_locks(trans); in __bch2_trans_relock()
769 if (unlikely(trans->restarted)) in __bch2_trans_relock()
770 return -((int) trans->restarted); in __bch2_trans_relock()
771 if (unlikely(trans->locked)) in __bch2_trans_relock()
777 trans_for_each_path(trans, path, i) { in __bch2_trans_relock()
781 !btree_path_get_locks(trans, path, false, &f)) in __bch2_trans_relock()
782 return bch2_trans_relock_fail(trans, path, &f, trace); in __bch2_trans_relock()
785 trans_set_locked(trans); in __bch2_trans_relock()
787 bch2_trans_verify_locks(trans); in __bch2_trans_relock()
791 int bch2_trans_relock(struct btree_trans *trans) in bch2_trans_relock() argument
793 return __bch2_trans_relock(trans, true); in bch2_trans_relock()
796 int bch2_trans_relock_notrace(struct btree_trans *trans) in bch2_trans_relock_notrace() argument
798 return __bch2_trans_relock(trans, false); in bch2_trans_relock_notrace()
801 void bch2_trans_unlock_noassert(struct btree_trans *trans) in bch2_trans_unlock_noassert() argument
803 __bch2_trans_unlock(trans); in bch2_trans_unlock_noassert()
805 trans_set_unlocked(trans); in bch2_trans_unlock_noassert()
808 void bch2_trans_unlock(struct btree_trans *trans) in bch2_trans_unlock() argument
810 __bch2_trans_unlock(trans); in bch2_trans_unlock()
812 trans_set_unlocked(trans); in bch2_trans_unlock()
815 void bch2_trans_unlock_long(struct btree_trans *trans) in bch2_trans_unlock_long() argument
817 bch2_trans_unlock(trans); in bch2_trans_unlock_long()
818 bch2_trans_srcu_unlock(trans); in bch2_trans_unlock_long()
821 int __bch2_trans_mutex_lock(struct btree_trans *trans, in __bch2_trans_mutex_lock() argument
824 int ret = drop_locks_do(trans, (mutex_lock(lock), 0)); in __bch2_trans_mutex_lock()
862 static bool bch2_trans_locked(struct btree_trans *trans) in bch2_trans_locked() argument
867 trans_for_each_path(trans, path, i) in bch2_trans_locked()
873 void bch2_trans_verify_locks(struct btree_trans *trans) in bch2_trans_verify_locks() argument
875 if (!trans->locked) { in bch2_trans_verify_locks()
876 BUG_ON(bch2_trans_locked(trans)); in bch2_trans_verify_locks()
883 trans_for_each_path(trans, path, i) in bch2_trans_verify_locks()