Patch "gfs2: low-memory forced flush fixes" has been added to the 5.15-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

    gfs2: low-memory forced flush fixes

to the 5.15-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:
     gfs2-low-memory-forced-flush-fixes.patch
and it can be found in the queue-5.15 subdirectory.

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



commit 68f0cbd1b0ec4bd6464524f9bd47663cf73b6218
Author: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
Date:   Thu Aug 10 17:15:46 2023 +0200

    gfs2: low-memory forced flush fixes
    
    [ Upstream commit b74cd55aa9a9d0aca760028a51343ec79812e410 ]
    
    First, function gfs2_ail_flush_reqd checks the SDF_FORCE_AIL_FLUSH flag
    to determine if an AIL flush should be forced in low-memory situations.
    However, it also immediately clears the flag, and when called repeatedly
    as in function gfs2_logd, the flag will be lost.  Fix that by pulling
    the SDF_FORCE_AIL_FLUSH flag check out of gfs2_ail_flush_reqd.
    
    Second, function gfs2_writepages sets the SDF_FORCE_AIL_FLUSH flag
    whether or not enough pages were written.  If enough pages could be
    written, flushing the AIL is unnecessary, though.
    
    Third, gfs2_writepages doesn't wake up logd after setting the
    SDF_FORCE_AIL_FLUSH flag, so it can take a long time for logd to react.
    It would be preferable to wake up logd, but that hurts the performance
    of some workloads and we don't quite understand why so far, so don't
    wake up logd so far.
    
    Fixes: b066a4eebd4f ("gfs2: forcibly flush ail to relieve memory pressure")
    Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index ee212c9310ad0..2b654c3b918a3 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -207,13 +207,13 @@ static int gfs2_writepages(struct address_space *mapping,
 	int ret;
 
 	/*
-	 * Even if we didn't write any pages here, we might still be holding
+	 * Even if we didn't write enough pages here, we might still be holding
 	 * dirty pages in the ail. We forcibly flush the ail because we don't
 	 * want balance_dirty_pages() to loop indefinitely trying to write out
 	 * pages held in the ail that it can't find.
 	 */
 	ret = iomap_writepages(mapping, wbc, &wpc, &gfs2_writeback_ops);
-	if (ret == 0)
+	if (ret == 0 && wbc->nr_to_write > 0)
 		set_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags);
 	return ret;
 }
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 924d7f0de1e83..9a96842aeab3d 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -1277,9 +1277,6 @@ static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp)
 {
 	unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free);
 
-	if (test_and_clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags))
-		return 1;
-
 	return used_blocks + atomic_read(&sdp->sd_log_blks_needed) >=
 		atomic_read(&sdp->sd_log_thresh2);
 }
@@ -1320,7 +1317,9 @@ int gfs2_logd(void *data)
 						  GFS2_LFC_LOGD_JFLUSH_REQD);
 		}
 
-		if (gfs2_ail_flush_reqd(sdp)) {
+		if (test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) ||
+		    gfs2_ail_flush_reqd(sdp)) {
+			clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags);
 			gfs2_ail1_start(sdp);
 			gfs2_ail1_wait(sdp);
 			gfs2_ail1_empty(sdp, 0);
@@ -1333,6 +1332,7 @@ int gfs2_logd(void *data)
 		try_to_freeze();
 
 		t = wait_event_interruptible_timeout(sdp->sd_logd_waitq,
+				test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) ||
 				gfs2_ail_flush_reqd(sdp) ||
 				gfs2_jrnl_flush_reqd(sdp) ||
 				kthread_should_stop(),



[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