diff options
author | Olaf Faaland <[email protected]> | 2015-10-15 13:08:27 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-12-22 10:21:33 -0800 |
commit | 448d7aaabc55b43663c597b91b221bed982d81dd (patch) | |
tree | 89e12793ce08d38389662ff18c9336ba4be7fb9c | |
parent | e0553a74adf1b1035e1ae25ca7feacacdeb93931 (diff) |
Identify locks flagged by lockdep
When running a kernel with CONFIG_LOCKDEP=y, lockdep reports possible
recursive locking in some cases and possible circular locking dependency
in others, within the SPL and ZFS modules.
This patch uses a mutex type defined in SPL, MUTEX_NOLOCKDEP, to mark
such mutexes when they are initialized. This mutex type causes
attempts to take or release those locks to be wrapped in lockdep_off()
and lockdep_on() calls to silence the dependency checker and allow the
use of lock_stats to examine contention.
For RW locks, it uses an analogous lock type, RW_NOLOCKDEP.
The goal is that these locks are ultimately changed back to type
MUTEX_DEFAULT or RW_DEFAULT, after the locks are annotated to reflect
their relationship (e.g. z_name_lock below) or any real problem with the
lock dependencies are fixed.
Some of the affected locks are:
tc_open_lock:
=============
This is an array of locks, all with same name, which txg_quiesce must
take all of in order to move txg to next state. All default to the same
lockdep class, and so to lockdep appears recursive.
zp->z_name_lock:
================
In zfs_rmdir,
dzp = znode for the directory (input to zfs_dirent_lock)
zp = znode for the entry being removed (output of zfs_dirent_lock)
zfs_rmdir()->zfs_dirent_lock() takes z_name_lock in dzp
zfs_rmdir() takes z_name_lock in zp
Since both dzp and zp are type znode_t, the locks have the same default
class, and lockdep considers it a possible recursive lock attempt.
l->l_rwlock:
============
zap_expand_leaf() sometimes creates two new zap leaf structures, via
these call paths:
zap_deref_leaf()->zap_get_leaf_byblk()->zap_leaf_open()
zap_expand_leaf()->zap_create_leaf()->zap_expand_leaf()->zap_create_leaf()
Because both zap_leaf_open() and zap_create_leaf() initialize
l->l_rwlock in their (separate) leaf structures, the lockdep class is
the same, and the linux kernel believes these might both be the same
lock, and emits a possible recursive lock warning.
Signed-off-by: Olaf Faaland <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #3895
-rw-r--r-- | module/zfs/dbuf.c | 2 | ||||
-rw-r--r-- | module/zfs/dnode.c | 2 | ||||
-rw-r--r-- | module/zfs/multilist.c | 2 | ||||
-rw-r--r-- | module/zfs/txg.c | 2 | ||||
-rw-r--r-- | module/zfs/vdev.c | 2 | ||||
-rw-r--r-- | module/zfs/zap.c | 2 | ||||
-rw-r--r-- | module/zfs/zfs_znode.c | 2 | ||||
-rw-r--r-- | module/zfs/zio.c | 2 |
8 files changed, 8 insertions, 8 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 31242d601..fe0ffa2d8 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -1320,7 +1320,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) } dr->dt.dl.dr_data = data_old; } else { - mutex_init(&dr->dt.di.dr_mtx, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&dr->dt.di.dr_mtx, NULL, MUTEX_NOLOCKDEP, NULL); list_create(&dr->dt.di.dr_children, sizeof (dbuf_dirty_record_t), offsetof(dbuf_dirty_record_t, dr_dirty_node)); diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index 2858bbfb4..1d587b6f5 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -107,7 +107,7 @@ dnode_cons(void *arg, void *unused, int kmflag) dnode_t *dn = arg; int i; - rw_init(&dn->dn_struct_rwlock, NULL, RW_DEFAULT, NULL); + rw_init(&dn->dn_struct_rwlock, NULL, RW_NOLOCKDEP, NULL); mutex_init(&dn->dn_mtx, NULL, MUTEX_DEFAULT, NULL); mutex_init(&dn->dn_dbufs_mtx, NULL, MUTEX_DEFAULT, NULL); cv_init(&dn->dn_notxholds, NULL, CV_DEFAULT, NULL); diff --git a/module/zfs/multilist.c b/module/zfs/multilist.c index e4446ded2..e02a4bae3 100644 --- a/module/zfs/multilist.c +++ b/module/zfs/multilist.c @@ -85,7 +85,7 @@ multilist_create(multilist_t *ml, size_t size, size_t offset, unsigned int num, for (i = 0; i < ml->ml_num_sublists; i++) { multilist_sublist_t *mls = &ml->ml_sublists[i]; - mutex_init(&mls->mls_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&mls->mls_lock, NULL, MUTEX_NOLOCKDEP, NULL); list_create(&mls->mls_list, size, offset); } } diff --git a/module/zfs/txg.c b/module/zfs/txg.c index 1d5ee97b1..d5dff58ab 100644 --- a/module/zfs/txg.c +++ b/module/zfs/txg.c @@ -128,7 +128,7 @@ txg_init(dsl_pool_t *dp, uint64_t txg) int i; mutex_init(&tx->tx_cpu[c].tc_lock, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&tx->tx_cpu[c].tc_open_lock, NULL, MUTEX_DEFAULT, + mutex_init(&tx->tx_cpu[c].tc_open_lock, NULL, MUTEX_NOLOCKDEP, NULL); for (i = 0; i < TXG_SIZE; i++) { cv_init(&tx->tx_cpu[c].tc_cv[i], NULL, CV_DEFAULT, diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index 7aff5455b..cf0d9b7d0 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -348,7 +348,7 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops) list_link_init(&vd->vdev_config_dirty_node); list_link_init(&vd->vdev_state_dirty_node); - mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_NOLOCKDEP, NULL); mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&vd->vdev_probe_lock, NULL, MUTEX_DEFAULT, NULL); for (t = 0; t < DTL_TYPES; t++) { diff --git a/module/zfs/zap.c b/module/zfs/zap.c index c5ea392b6..4640fb98c 100644 --- a/module/zfs/zap.c +++ b/module/zfs/zap.c @@ -404,7 +404,7 @@ zap_create_leaf(zap_t *zap, dmu_tx_t *tx) ASSERT(RW_WRITE_HELD(&zap->zap_rwlock)); - rw_init(&l->l_rwlock, NULL, RW_DEFAULT, NULL); + rw_init(&l->l_rwlock, NULL, RW_NOLOCKDEP, NULL); rw_enter(&l->l_rwlock, RW_WRITER); l->l_blkid = zap_allocate_blocks(zap, 1); l->l_dbuf = NULL; diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 6fda78e5f..a3371b733 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -107,7 +107,7 @@ zfs_znode_cache_constructor(void *buf, void *arg, int kmflags) mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL); rw_init(&zp->z_parent_lock, NULL, RW_DEFAULT, NULL); - rw_init(&zp->z_name_lock, NULL, RW_DEFAULT, NULL); + rw_init(&zp->z_name_lock, NULL, RW_NOLOCKDEP, NULL); mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL); rw_init(&zp->z_xattr_lock, NULL, RW_DEFAULT, NULL); diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 2bc88c52c..fef56ef7b 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -533,7 +533,7 @@ zio_create(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp, zio = kmem_cache_alloc(zio_cache, KM_SLEEP); bzero(zio, sizeof (zio_t)); - mutex_init(&zio->io_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&zio->io_lock, NULL, MUTEX_NOLOCKDEP, NULL); cv_init(&zio->io_cv, NULL, CV_DEFAULT, NULL); list_create(&zio->io_parent_list, sizeof (zio_link_t), |