summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-12-22 20:47:24 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-12-22 20:47:24 -0500
commit0e8cc7b5b3a46ea16f74c161f0fd12966deb4d93 (patch)
treedfef6032de2f7758135d376b10369f28ea328771
parentaaa55da315fcbb0387271d473303f52b5f7f3d45 (diff)
lockdep_debuglockdep_debug
-rw-r--r--fs/bcachefs/btree_iter.c49
-rw-r--r--fs/bcachefs/btree_locking.c8
-rw-r--r--fs/bcachefs/btree_locking.h9
-rw-r--r--fs/bcachefs/darray.h1
-rw-r--r--fs/bcachefs/fs.c16
-rw-r--r--include/linux/lockdep.h2
-rw-r--r--kernel/locking/lockdep.c10
7 files changed, 75 insertions, 20 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index f1f4efc94589..401cfd727a12 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -2913,6 +2913,8 @@ unsigned bch2_trans_get_fn_idx(const char *fn)
return i;
}
+static struct lock_class_key key;
+
struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx)
__acquires(&c->btree_trans_barrier)
{
@@ -2976,8 +2978,8 @@ 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);
+ //lockdep_init_map(&trans->dep_map, "bcachefs_btree", &key, 0);
+ lockdep_init_map_wait(&trans->dep_map, "bcachefs_btree", &key, 0, LD_WAIT_SLEEP);
if (fn_idx < BCH_TRANSACTIONS_NR) {
trans->fn = bch2_btree_transaction_fns[fn_idx];
@@ -3226,6 +3228,10 @@ void bch2_fs_btree_iter_init_early(struct bch_fs *c)
seqmutex_init(&c->btree_trans_lock);
}
+#include <linux/delay.h>
+
+static DEFINE_MUTEX(test_mutex);
+
int bch2_fs_btree_iter_init(struct bch_fs *c)
{
int ret;
@@ -3242,15 +3248,46 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
if (ret)
return ret;
-#ifdef CONFIG_LOCKDEP
+ struct btree_trans *trans;
+#if 0
fs_reclaim_acquire(GFP_KERNEL);
- struct btree_trans *trans = bch2_trans_get(c);
- lock_acquire_exclusive(&trans->dep_map, 0, 0, NULL, _THIS_IP_);
+ mutex_lock(&test_mutex);
+ mutex_unlock(&test_mutex);
+ fs_reclaim_release(GFP_KERNEL);
+
+ mutex_lock(&test_mutex);
+ fs_reclaim_acquire(GFP_KERNEL);
+ fs_reclaim_release(GFP_KERNEL);
+ mutex_unlock(&test_mutex);
+
+ mutex_lock(&test_mutex);
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
trans->locks_held = true;
bch2_trans_put(trans);
- fs_reclaim_release(GFP_KERNEL);
+ mutex_unlock(&test_mutex);
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ mutex_lock(&test_mutex);
+ mutex_unlock(&test_mutex);
+ bch2_trans_put(trans);
#endif
+ fs_reclaim_acquire(GFP_KERNEL);
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ bch2_trans_put(trans);
+ fs_reclaim_release(GFP_KERNEL);
+
+ trans = bch2_trans_get(c);
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ fs_reclaim_acquire(GFP_KERNEL);
+ fs_reclaim_release(GFP_KERNEL);
+ bch2_trans_put(trans);
+
c->btree_trans_barrier_initialized = true;
return 0;
diff --git a/fs/bcachefs/btree_locking.c b/fs/bcachefs/btree_locking.c
index a5ae421073d0..707ef5872b6c 100644
--- a/fs/bcachefs/btree_locking.c
+++ b/fs/bcachefs/btree_locking.c
@@ -629,6 +629,12 @@ __flatten
bool bch2_btree_path_relock_norestart(struct btree_trans *trans,
struct btree_path *path, unsigned long trace_ip)
{
+#ifdef CONFIG_LOCKDEP
+ if (!trans->locks_held) {
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ }
+#endif
struct get_locks_fail f;
return btree_path_get_locks(trans, path, false, &f);
@@ -805,7 +811,7 @@ void bch2_trans_unlock(struct btree_trans *trans)
#ifdef CONFIG_LOCKDEP
if (trans->locks_held) {
- lock_release(&trans->dep_map, _THIS_IP_);
+ lock_map_release(&trans->dep_map);
trans->locks_held = false;
}
#endif
diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h
index 962fa8f5cf0b..5d9b5f9e3e3b 100644
--- a/fs/bcachefs/btree_locking.h
+++ b/fs/bcachefs/btree_locking.h
@@ -204,7 +204,7 @@ static inline int __btree_node_lock_nopath(struct btree_trans *trans,
{
#ifdef CONFIG_LOCKDEP
if (!trans->locks_held) {
- lock_acquire_exclusive(&trans->dep_map, 0, 0, NULL, ip);
+ lock_map_acquire(&trans->dep_map);
trans->locks_held = true;
}
#endif
@@ -271,6 +271,13 @@ static inline int btree_node_lock(struct btree_trans *trans,
EBUG_ON(level >= BTREE_MAX_DEPTH);
+#ifdef CONFIG_LOCKDEP
+ if (!trans->locks_held) {
+ lock_map_acquire(&trans->dep_map);
+ trans->locks_held = true;
+ }
+#endif
+
if (likely(six_trylock_type(&b->lock, type)) ||
btree_node_lock_increment(trans, b, level, (enum btree_node_locked_type) type) ||
!(ret = btree_node_lock_nopath(trans, b, type, btree_path_ip_allocated(path)))) {
diff --git a/fs/bcachefs/darray.h b/fs/bcachefs/darray.h
index e3aba5b61d19..e43987987047 100644
--- a/fs/bcachefs/darray.h
+++ b/fs/bcachefs/darray.h
@@ -17,6 +17,7 @@ struct { \
}
typedef DARRAY(void) darray_void;
+typedef DARRAY(char *) darray_string;
int __bch2_darray_resize(darray_void *, size_t, size_t, gfp_t);
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index bc280a0a957d..e006807bc260 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -1596,26 +1596,20 @@ static struct bch_fs *bch2_path_to_fs(const char *path)
return c ?: ERR_PTR(-ENOENT);
}
-static char **split_devs(const char *_dev_name, unsigned *nr)
+static darray_string bch2_split_devs(const char *_dev_name, unsigned *nr)
{
char *dev_name = NULL, **devs = NULL, *s;
size_t i = 0, nr_devs = 0;
+ DARRAY(
- dev_name = kstrdup(_dev_name, GFP_KERNEL);
+ char *dev_name = kstrdup(_dev_name, GFP_KERNEL), *s = dev_name;
if (!dev_name)
return NULL;
- for (s = dev_name; s; s = strchr(s + 1, ':'))
- nr_devs++;
+ while ((s = strsep(&dev_name, ":"))) {
- devs = kcalloc(nr_devs + 1, sizeof(const char *), GFP_KERNEL);
- if (!devs) {
- kfree(dev_name);
- return NULL;
- }
-
- while ((s = strsep(&dev_name, ":")))
devs[i++] = s;
+ }
*nr = nr_devs;
return devs;
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index dc2844b071c2..1f43a8770c71 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -106,7 +106,7 @@ struct held_lock {
struct lockdep_map *instance;
struct lockdep_map *nest_lock;
#ifdef CONFIG_LOCK_STAT
- u64 waittime_stamp;
+ u64 waittime_stamp;
u64 holdtime_stamp;
#endif
/*
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 151bd3de5936..7ea4a5793421 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1410,6 +1410,7 @@ static int add_lock_to_list(struct lock_class *this,
u16 distance, u8 dep,
const struct lock_trace *trace)
{
+ trace_printk("%s -> %s\n", links_to->name, this->name);
struct lock_list *entry;
/*
* Lock not present yet - get a new dependency struct and
@@ -1784,6 +1785,15 @@ static enum bfs_result __bfs(struct lock_list *source_entry,
if (skip && skip(lock, data))
continue;
+ {
+ struct lock_class *next = hlock_class((struct held_lock *)data);
+
+ if (!strcmp("bcachefs_btree", lock->class->name) ||
+ !strcmp("bcachefs_btree", next->name))
+ trace_printk("considering %s -> %s\n",
+ lock->class->name, next->name);
+ }
+
if (match(lock, data)) {
*target_entry = lock;
return BFS_RMATCH;