Skip to content

Commit 55de40f

Browse files
ofaalandbehlendorf
authored andcommitted
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 <guss80@gmail.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Olaf Faaland <faaland1@llnl.gov> Closes #10873
1 parent 9cea5f0 commit 55de40f

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

module/zfs/mmp.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,6 @@ mmp_init(spa_t *spa)
198198
cv_init(&mmp->mmp_thread_cv, NULL, CV_DEFAULT, NULL);
199199
mutex_init(&mmp->mmp_io_lock, NULL, MUTEX_DEFAULT, NULL);
200200
mmp->mmp_kstat_id = 1;
201-
202-
/*
203-
* mmp_write_done() calculates mmp_delay based on prior mmp_delay and
204-
* the elapsed time since the last write. For the first mmp write,
205-
* there is no "last write", so we start with fake non-zero values.
206-
*/
207-
mmp->mmp_last_write = gethrtime();
208-
mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval));
209201
}
210202

211203
void
@@ -557,6 +549,18 @@ mmp_thread(void *arg)
557549

558550
mmp_thread_enter(mmp, &cpr);
559551

552+
/*
553+
* There have been no MMP writes yet. Setting mmp_last_write here gives
554+
* us one mmp_fail_ns period, which is consistent with the activity
555+
* check duration, to try to land an MMP write before MMP suspends the
556+
* pool (if so configured).
557+
*/
558+
559+
mutex_enter(&mmp->mmp_io_lock);
560+
mmp->mmp_last_write = gethrtime();
561+
mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval));
562+
mutex_exit(&mmp->mmp_io_lock);
563+
560564
while (!mmp->mmp_thread_exiting) {
561565
hrtime_t next_time = gethrtime() +
562566
MSEC2NSEC(MMP_DEFAULT_INTERVAL);

0 commit comments

Comments
 (0)