From: Mr NeilBrown Date: Thu, 2 Jul 2020 21:43:45 +0000 (+1000) Subject: LU-9679 lov: annotate nested locking of obd_dev_mutex X-Git-Tag: 2.13.55~19 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=10dae4c3b68ebc2509d7089037eccc9f4460c08f LU-9679 lov: annotate nested locking of obd_dev_mutex 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 Change-Id: I0776407b722dd29ab1321289953b63f76fce7ceb Reviewed-on: https://review.whamcloud.com/39248 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Shaun Tancheff Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 2b2f2fa..d624c27 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -41,13 +41,17 @@ #include #include -#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 || diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 1f470b3..9c4da99 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -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);