Viewing: ext4-adjust-mmp-wait-time.patch

From b2772e48e110a6412dfe300df95016f5b9c28c6f Mon Sep 17 00:00:00 2001
From: Li Dongyang <dongyangli@ddn.com>
Date: Thu, 19 Feb 2026 22:23:13 -0800
Subject: [PATCH] LU-13932 ldiskfs: mmp wait time adjustments

Introduce a small delay of 2 seconds between write and read
back of the mmp block for the SEQ_CLEAN case,
currently there is no delay at all and could potentially
break mmp proction when 2 nodes mounts the same fs
simultaneously and both see SEQ_CLEAN from the initial read.

Reduce the max wait time from mmp_check_interval + 60 to
mmp_check_interval + 20.

In kmmpd thread, slowly decay mmp_check_interval to
EXT4_MMP_MIN_CHECK_INTERVAL according to IO completion time
to avoid fluctuations.

Signed-off-by: Li Dongyang <dongyangli@ddn.com>
Change-Id: I9d08e0f62c89e041275f3edc53e1da496b8c0444
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/63479
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@thelustrecollective.com>

---
 fs/ext4/mmp.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -140,6 +140,7 @@ static int kmmpd(void *data)
 	unsigned long failed_writes = 0;
 	int mmp_update_interval = le16_to_cpu(es->s_mmp_update_interval);
 	unsigned mmp_check_interval;
+	unsigned new_check_interval;
 	unsigned long last_update_time;
 	unsigned long diff;
 	int retval = 0;
@@ -185,6 +186,8 @@ static int kmmpd(void *data)
 		}
 
 		diff = jiffies - last_update_time;
+		new_check_interval = EXT4_MMP_CHECK_MULT * diff / HZ;
+
 		if (diff < mmp_update_interval * HZ)
 			schedule_timeout_interruptible(mmp_update_interval *
 						       HZ - diff);
@@ -224,12 +227,16 @@ static int kmmpd(void *data)
 		}
 
 		 /*
-		 * Adjust the mmp_check_interval depending on how much time
-		 * it took for the MMP block to be written.
+		 * Increase mmp_check_interval immediately if IO completion time
+		 * is longer, but decay slowly to minimum if it is shorter.
 		 */
-		mmp_check_interval = clamp(EXT4_MMP_CHECK_MULT * diff / HZ,
-					   EXT4_MMP_MIN_CHECK_INTERVAL,
-					   EXT4_MMP_MAX_CHECK_INTERVAL);
+		if (new_check_interval >= mmp_check_interval)
+			mmp_check_interval = min_t(unsigned, new_check_interval,
+						   EXT4_MMP_MAX_CHECK_INTERVAL);
+		else
+			mmp_check_interval = (mmp_check_interval * 15 +
+					      max_t(unsigned, new_check_interval,
+						    EXT4_MMP_MIN_CHECK_INTERVAL)) / 16;
 		mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
 	}
 
@@ -280,7 +287,7 @@ int ext4_multi_mount_protect(struct super_block *sb,
 	struct mmp_struct *mmp = NULL;
 	u32 seq;
 	unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval);
-	unsigned int wait_time = 0;
+	unsigned int wait_time = 2;
 	int retval;
 
 	if (mmp_block < le32_to_cpu(es->s_first_data_block) ||
@@ -317,7 +324,7 @@ int ext4_multi_mount_protect(struct super_block *sb,
 	}
 
 	wait_time = min(mmp_check_interval * 2 + 1,
-			mmp_check_interval + 60);
+			mmp_check_interval + 20);
 
 	/* Print MMP interval if more than 20 secs. */
 	if (wait_time > EXT4_MMP_MIN_CHECK_INTERVAL * 4)
--