Commit 0b4fd567 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: btree_trans_restart_foreign_task()



In debug mode, we save the call stack on transaction restart - but
there's no locking, so we can't touch it if we're issuing the restart
from another thread.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent f4a584f4
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -335,13 +335,20 @@ static inline void bch2_trans_verify_not_unlocked_or_in_restart(struct btree_tra
}

__always_inline
static int btree_trans_restart_ip(struct btree_trans *trans, int err, unsigned long ip)
static int btree_trans_restart_foreign_task(struct btree_trans *trans, int err, unsigned long ip)
{
	BUG_ON(err <= 0);
	BUG_ON(!bch2_err_matches(-err, BCH_ERR_transaction_restart));

	trans->restarted = err;
	trans->last_restarted_ip = ip;
	return -err;
}

__always_inline
static int btree_trans_restart_ip(struct btree_trans *trans, int err, unsigned long ip)
{
	btree_trans_restart_foreign_task(trans, err, ip);
#ifdef CONFIG_BCACHEFS_DEBUG
	darray_exit(&trans->last_restarted_trace);
	bch2_save_backtrace(&trans->last_restarted_trace, current, 0, GFP_NOWAIT);
+3 −1
Original line number Diff line number Diff line
@@ -172,7 +172,9 @@ static int abort_lock(struct lock_graph *g, struct trans_waiting_for_lock *i)
{
	if (i == g->g) {
		trace_would_deadlock(g, i->trans);
		return btree_trans_restart(i->trans, BCH_ERR_transaction_restart_would_deadlock);
		return btree_trans_restart_foreign_task(i->trans,
					BCH_ERR_transaction_restart_would_deadlock,
					_THIS_IP_);
	} else {
		i->trans->lock_must_abort = true;
		wake_up_process(i->trans->locking_wait.task);