aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorOlaf Faaland <[email protected]>2020-09-09 10:12:54 -0700
committerGitHub <[email protected]>2020-09-09 10:12:54 -0700
commita74259cea063704622b7f3329bef3eadb13ab8b7 (patch)
treeadbf5c1cd59bbf7b19c68a90233bd1389cbc79fc /module
parentcba6d86638811adaebf4c88441c22575d1194821 (diff)
Initialize mmp_last_write when the mmp thread starts
A great deal of time may go by between when mmp_init() is called and the MMP thread starts, particularly if there are bad devices, because there is I/O checking configs etc. If this time is too long, (gethrtime() - mmp_last_write) > mmp_fail_ns at the time the MMP thread starts. If MMP is configured to suspend the pool, the pool will be suspended immediately. This can be seen in issue #10838 The value of mmp_last_write doesn't matter before the mmp thread starts. To give the MMP thread time to issue and land MMP writes, initialize mmp_last_write when the MMP thread starts. Reviewed-by: Giuseppe Di Natale <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Olaf Faaland <[email protected]> Closes #10873
Diffstat (limited to 'module')
-rw-r--r--module/zfs/mmp.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c
index 1b97de468..99852521b 100644
--- a/module/zfs/mmp.c
+++ b/module/zfs/mmp.c
@@ -198,14 +198,6 @@ mmp_init(spa_t *spa)
cv_init(&mmp->mmp_thread_cv, NULL, CV_DEFAULT, NULL);
mutex_init(&mmp->mmp_io_lock, NULL, MUTEX_DEFAULT, NULL);
mmp->mmp_kstat_id = 1;
-
- /*
- * mmp_write_done() calculates mmp_delay based on prior mmp_delay and
- * the elapsed time since the last write. For the first mmp write,
- * there is no "last write", so we start with fake non-zero values.
- */
- mmp->mmp_last_write = gethrtime();
- mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval));
}
void
@@ -557,6 +549,18 @@ mmp_thread(void *arg)
mmp_thread_enter(mmp, &cpr);
+ /*
+ * There have been no MMP writes yet. Setting mmp_last_write here gives
+ * us one mmp_fail_ns period, which is consistent with the activity
+ * check duration, to try to land an MMP write before MMP suspends the
+ * pool (if so configured).
+ */
+
+ mutex_enter(&mmp->mmp_io_lock);
+ mmp->mmp_last_write = gethrtime();
+ mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval));
+ mutex_exit(&mmp->mmp_io_lock);
+
while (!mmp->mmp_thread_exiting) {
hrtime_t next_time = gethrtime() +
MSEC2NSEC(MMP_DEFAULT_INTERVAL);