]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Identify locks flagged by lockdep
authorOlaf Faaland <faaland1@llnl.gov>
Thu, 15 Oct 2015 20:08:27 +0000 (13:08 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 22 Dec 2015 18:21:33 +0000 (10:21 -0800)
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 <faaland1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #3895

module/zfs/dbuf.c
module/zfs/dnode.c
module/zfs/multilist.c
module/zfs/txg.c
module/zfs/vdev.c
module/zfs/zap.c
module/zfs/zfs_znode.c
module/zfs/zio.c

index 31242d60154e77872db0217b0a8c3339ce8e1e65..fe0ffa2d8c68720ffb3cf86a2b76ff2a61d3b62d 100644 (file)
@@ -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));
index 2858bbfb492ea74f81e241cab6fb84f9f94f931e..1d587b6f5042261dabde29e473bc47d6867b9b2d 100644 (file)
@@ -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);
index e4446ded22089bf743dab72770d0db292f378e10..e02a4bae33830cb591632df7dbf4c652ce2c9475 100644 (file)
@@ -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);
        }
 }
index 1d5ee97b1368d9c5fe56274abed4cae4b2c74002..d5dff58abb772a40b4187ddde638cff25a0f0f0d 100644 (file)
@@ -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,
index 7aff5455b10b8a871c4869a3999146ae746333ce..cf0d9b7d0b6f97d6a45ba3f46180cb33cb624a60 100644 (file)
@@ -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++) {
index c5ea392b6a1d510637a0dc15bc1f5aed720f5fd9..4640fb98cc6952c715818e6fced4f39ba559bde5 100644 (file)
@@ -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;
index 6fda78e5f45166df34eab2f5dfbc8d5d04e19878..a3371b73340fb50e65012bbf1fbe821d76428eb5 100644 (file)
@@ -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);
 
index 2bc88c52c9b0fe0696c4899f8a773e3f1d2e4890..fef56ef7bb16e190f683cac0ba6e394f80c24975 100644 (file)
@@ -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),