diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-12-22 20:47:24 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-12-22 20:47:24 -0500 |
commit | 0e8cc7b5b3a46ea16f74c161f0fd12966deb4d93 (patch) | |
tree | dfef6032de2f7758135d376b10369f28ea328771 | |
parent | aaa55da315fcbb0387271d473303f52b5f7f3d45 (diff) |
lockdep_debuglockdep_debug
-rw-r--r-- | fs/bcachefs/btree_iter.c | 49 | ||||
-rw-r--r-- | fs/bcachefs/btree_locking.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/btree_locking.h | 9 | ||||
-rw-r--r-- | fs/bcachefs/darray.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/fs.c | 16 | ||||
-rw-r--r-- | include/linux/lockdep.h | 2 | ||||
-rw-r--r-- | kernel/locking/lockdep.c | 10 |
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; |