Whamcloud - gitweb
LU-9679 lov: annotate nested locking of obd_dev_mutex 48/39248/2
authorMr NeilBrown <neilb@suse.de>
Thu, 2 Jul 2020 21:43:45 +0000 (07:43 +1000)
committerOleg Drokin <green@whamcloud.com>
Fri, 17 Jul 2020 19:29:20 +0000 (19:29 +0000)
obd_statfs() can call lmv_statfs() with ->obd_dev_mutex helds.
lmv_statfs will then call obd_statfs() on a different device
and ->obd_dev_mutex will be taken again.  This is a *different*
mutex, but lockdep cannot see the difference, so it complains.

We can tell lockdep not to worry in this case using
mutex_lock_interruptible_nested().

Test-Parameters: trivial
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Change-Id: I0776407b722dd29ab1321289953b63f76fce7ceb
Reviewed-on: https://review.whamcloud.com/39248
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/obd_class.h
lustre/lmv/lmv_obd.c

index 2b2f2fa..d624c27 100644 (file)
 #include <uapi/linux/lustre/lustre_idl.h>
 #include <lprocfs_status.h>
 
-#define OBD_STATFS_NODELAY      0x0001  /* requests should be send without delay
-                                         * and resends for avoid deadlocks */
-#define OBD_STATFS_FROM_CACHE   0x0002  /* the statfs callback should not update
-                                         * obd_osfs_age */
+#define OBD_STATFS_NODELAY     0x0001  /* requests should be send without delay
+                                        * and resends for avoid deadlocks */
+#define OBD_STATFS_FROM_CACHE  0x0002  /* the statfs callback should not update
+                                        * obd_osfs_age */
 #define OBD_STATFS_FOR_MDT0    0x0004  /* The statfs is only for retrieving
                                         * information from MDT0. */
 #define OBD_STATFS_SUM         0x0008  /* get aggregated statfs from MDT */
+#define OBD_STATFS_NESTED      0x0010  /* Call while already holding
+                                        * obd_dev_mutex of a difference
+                                        * device.
+                                        */
 
 extern rwlock_t obd_dev_lock;
 
@@ -1063,7 +1067,9 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp,
            ((obd->obd_osfs.os_state & OS_STATFS_SUM) &&
             !(flags & OBD_STATFS_SUM))) {
                /* the RPC will block anyway, so avoid sending many at once */
-               rc = mutex_lock_interruptible(&obd->obd_dev_mutex);
+               rc = mutex_lock_interruptible_nested(&obd->obd_dev_mutex,
+                                                    (flags & OBD_STATFS_NESTED)
+                                                    ? SINGLE_DEPTH_NESTING : 0);
                if (rc)
                        RETURN(rc);
                if (obd->obd_osfs_age < max_age ||
index 1f470b3..9c4da99 100644 (file)
@@ -1256,7 +1256,8 @@ static int lmv_statfs(const struct lu_env *env, struct obd_export *exp,
                if (!tgt || !tgt->ltd_exp)
                        continue;
 
-               rc = obd_statfs(env, tgt->ltd_exp, temp, max_age, flags);
+               rc = obd_statfs(env, tgt->ltd_exp, temp, max_age,
+                               flags | OBD_STATFS_NESTED);
                if (rc) {
                        CERROR("%s: can't stat MDS #%d: rc = %d\n",
                               tgt->ltd_exp->exp_obd->obd_name, i, rc);