From c30e716c8149b7df7cf968373c22aa00b48d17b8 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 12 Mar 2018 11:26:05 -0700 Subject: [PATCH] Fix MMP write frequency for large pools When a single pool contains more vdevs than the CONFIG_HZ for for the kernel the mmp thread will not delay properly. Switch to using cv_timedwait_sig_hires() to handle higher resolution delays. This issue was reported on Arch Linux where HZ defaults to only 100 and this could be fairly easily reproduced with a reasonably large pool. Most distribution kernels set CONFIG_HZ=250 or CONFIG_HZ=1000 and thus are unlikely to be impacted. Reviewed-by: George Melikov Reviewed-by: Giuseppe Di Natale Reviewed-by: Olaf Faaland Reviewed-by: Tony Hutter Signed-off-by: Brian Behlendorf Closes #7205 Closes #7289 --- lib/libspl/include/sys/time.h | 6 +++++- module/zfs/mmp.c | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/libspl/include/sys/time.h b/lib/libspl/include/sys/time.h index f05fcaa1c..dc645fa5c 100644 --- a/lib/libspl/include/sys/time.h +++ b/lib/libspl/include/sys/time.h @@ -54,10 +54,14 @@ #define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC)) #endif -#ifndef NSEC2MSEC +#ifndef NSEC2MSEC #define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC)) #endif +#ifndef USEC2NSEC +#define USEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MICROSEC)) +#endif + #ifndef NSEC2SEC #define NSEC2SEC(n) ((n) / (NANOSEC / SEC)) #endif diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c index 15eea41ab..dc5c6a74f 100644 --- a/module/zfs/mmp.c +++ b/module/zfs/mmp.c @@ -462,9 +462,9 @@ mmp_thread(spa_t *spa) mmp_write_uberblock(spa); CALLB_CPR_SAFE_BEGIN(&cpr); - (void) cv_timedwait_sig(&mmp->mmp_thread_cv, - &mmp->mmp_thread_lock, ddi_get_lbolt() + - ((next_time - gethrtime()) / (NANOSEC / hz))); + (void) cv_timedwait_sig_hires(&mmp->mmp_thread_cv, + &mmp->mmp_thread_lock, next_time, USEC2NSEC(1), + CALLOUT_FLAG_ABSOLUTE); CALLB_CPR_SAFE_END(&cpr, &mmp->mmp_thread_lock); }