summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/btree_iter.c21
-rw-r--r--fs/bcachefs/btree_locking.c14
-rw-r--r--fs/bcachefs/btree_locking.h9
-rw-r--r--fs/bcachefs/btree_types.h6
4 files changed, 45 insertions, 5 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 47d203cdb7b2..f1f4efc94589 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -2976,6 +2976,9 @@ got_trans:
trans->paths_allocated[0] = 1;
+ static struct lock_class_key lockdep_key;
+ lockdep_init_map(&trans->dep_map, "bcachefs_btree", &lockdep_key, 0);
+
if (fn_idx < BCH_TRANSACTIONS_NR) {
trans->fn = bch2_btree_transaction_fns[fn_idx];
@@ -3236,7 +3239,19 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
mempool_init_kmalloc_pool(&c->btree_trans_mem_pool, 1,
BTREE_TRANS_MEM_MAX) ?:
init_srcu_struct(&c->btree_trans_barrier);
- if (!ret)
- c->btree_trans_barrier_initialized = true;
- return ret;
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_LOCKDEP
+ fs_reclaim_acquire(GFP_KERNEL);
+ struct btree_trans *trans = bch2_trans_get(c);
+ lock_acquire_exclusive(&trans->dep_map, 0, 0, NULL, _THIS_IP_);
+ trans->locks_held = true;
+ bch2_trans_put(trans);
+ fs_reclaim_release(GFP_KERNEL);
+
+#endif
+ c->btree_trans_barrier_initialized = true;
+ return 0;
+
}
diff --git a/fs/bcachefs/btree_locking.c b/fs/bcachefs/btree_locking.c
index 1ed8327a9fa2..a5ae421073d0 100644
--- a/fs/bcachefs/btree_locking.c
+++ b/fs/bcachefs/btree_locking.c
@@ -786,6 +786,13 @@ void bch2_trans_unlock_noassert(struct btree_trans *trans)
trans_for_each_path(trans, path, i)
__bch2_btree_path_unlock(trans, path);
+
+#ifdef CONFIG_LOCKDEP
+ if (trans->locks_held) {
+ lock_release(&trans->dep_map, _THIS_IP_);
+ trans->locks_held = false;
+ }
+#endif
}
void bch2_trans_unlock(struct btree_trans *trans)
@@ -795,6 +802,13 @@ void bch2_trans_unlock(struct btree_trans *trans)
trans_for_each_path(trans, path, i)
__bch2_btree_path_unlock(trans, path);
+
+#ifdef CONFIG_LOCKDEP
+ if (trans->locks_held) {
+ lock_release(&trans->dep_map, _THIS_IP_);
+ trans->locks_held = false;
+ }
+#endif
}
void bch2_trans_unlock_long(struct btree_trans *trans)
diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h
index 64810ea544c9..962fa8f5cf0b 100644
--- a/fs/bcachefs/btree_locking.h
+++ b/fs/bcachefs/btree_locking.h
@@ -202,13 +202,18 @@ static inline int __btree_node_lock_nopath(struct btree_trans *trans,
bool lock_may_not_fail,
unsigned long ip)
{
- int ret;
+#ifdef CONFIG_LOCKDEP
+ if (!trans->locks_held) {
+ lock_acquire_exclusive(&trans->dep_map, 0, 0, NULL, ip);
+ trans->locks_held = true;
+ }
+#endif
trans->lock_may_not_fail = lock_may_not_fail;
trans->lock_must_abort = false;
trans->locking = b;
- ret = six_lock_ip_waiter(&b->lock, type, &trans->locking_wait,
+ int ret = six_lock_ip_waiter(&b->lock, type, &trans->locking_wait,
bch2_six_check_for_deadlock, trans, ip);
WRITE_ONCE(trans->locking, NULL);
WRITE_ONCE(trans->locking_wait.start_time, 0);
diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h
index e4ebfc25df8e..b2d428bbcf73 100644
--- a/fs/bcachefs/btree_types.h
+++ b/fs/bcachefs/btree_types.h
@@ -397,6 +397,9 @@ struct btree_trans {
u8 lock_must_abort;
bool lock_may_not_fail:1;
bool srcu_held:1;
+#ifdef CONFIG_LOCKDEP
+ bool locks_held:1;
+#endif
bool used_mempool:1;
bool in_traverse_all:1;
bool paths_sorted:1;
@@ -433,6 +436,9 @@ struct btree_trans {
unsigned extra_disk_res; /* XXX kill */
struct replicas_delta_list *fs_usage_deltas;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+#endif
/* Entries before this are zeroed out on every bch2_trans_get() call */
struct list_head list;