Patch "md: fix soft lockup in status_resync" has been added to the 6.3-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    md: fix soft lockup in status_resync

to the 6.3-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     md-fix-soft-lockup-in-status_resync.patch
and it can be found in the queue-6.3 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 68e3ac4aa49ad328de3307334e4b011ee0dcc35c
Author: Yu Kuai <yukuai3@xxxxxxxxxx>
Date:   Fri Mar 10 15:38:51 2023 +0800

    md: fix soft lockup in status_resync
    
    [ Upstream commit 6efddf1e32e2a264694766ca485a4f5e04ee82a7 ]
    
    status_resync() will calculate 'curr_resync - recovery_active' to show
    user a progress bar like following:
    
    [============>........]  resync = 61.4%
    
    'curr_resync' and 'recovery_active' is updated in md_do_sync(), and
    status_resync() can read them concurrently, hence it's possible that
    'curr_resync - recovery_active' can overflow to a huge number. In this
    case status_resync() will be stuck in the loop to print a large amount
    of '=', which will end up soft lockup.
    
    Fix the problem by setting 'resync' to MD_RESYNC_ACTIVE in this case,
    this way resync in progress will be reported to user.
    
    Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx>
    Signed-off-by: Song Liu <song@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20230310073855.1337560-3-yukuai1@xxxxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 13321dbb5fbcf..d479e1656ef33 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -8029,16 +8029,16 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
 	} else if (resync > max_sectors) {
 		resync = max_sectors;
 	} else {
-		resync -= atomic_read(&mddev->recovery_active);
-		if (resync < MD_RESYNC_ACTIVE) {
-			/*
-			 * Resync has started, but the subtraction has
-			 * yielded one of the special values. Force it
-			 * to active to ensure the status reports an
-			 * active resync.
-			 */
+		res = atomic_read(&mddev->recovery_active);
+		/*
+		 * Resync has started, but the subtraction has overflowed or
+		 * yielded one of the special values. Force it to active to
+		 * ensure the status reports an active resync.
+		 */
+		if (resync < res || resync - res < MD_RESYNC_ACTIVE)
 			resync = MD_RESYNC_ACTIVE;
-		}
+		else
+			resync -= res;
 	}
 
 	if (resync == MD_RESYNC_NONE) {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux