commit 7dda1203e65db143e2c88e3f325e3f6051628b93
Author: Kaihao Bai <carlo.bai@linux.alibaba.com>
Date:   Thu Apr 16 11:45:44 2026 +0800

    anolis: mm: exclude dirty pages from min_cache_kbytes protection
    
    ANBZ: #33265
    
    min_cache_kbytes is intended to protect hot code segments and shared
    libraries from reclaim, which are typically clean file pages. However,
    the current implementation counts both clean and dirty file pages toward
    the watermark, causing dirty pages to incorrectly consume the reserved
    quota and leaving hot clean file pages vulnerable to eviction.
    
    Only account clean file pages against the min_cache_kbytes watermark,
    excluding dirty pages which are handled independently via the writeback
    path.
    
    Signed-off-by: Kaihao Bai <carlo.bai@linux.alibaba.com>
    Link: https://code.alibaba-inc.com/alikernel/kernel-5.10/codereview/26989667

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5654ae4155ea..0b5ec71b7eca 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1227,6 +1227,9 @@ static enum page_references page_check_references(struct page *page,
 		return PAGEREF_KEEP;
 	}
 
+	if (sc->file_is_reserved && (vm_flags & VM_EXEC) && !PageSwapBacked(page))
+		return PAGEREF_ACTIVATE;
+
 	/* Reclaim if clean, defer dirty pages to writeback */
 	if (referenced_page && !PageSwapBacked(page))
 		return PAGEREF_RECLAIM_CLEAN;
@@ -2687,6 +2690,10 @@ static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc)
 		 */
 		min_cache_kbytes = READ_ONCE(sysctl_min_cache_kbytes);
 		if (min_cache_kbytes) {
+			unsigned long f_dirty;
+
+			f_dirty = node_page_state(pgdat, NR_FILE_DIRTY);
+			file = (file > f_dirty) ? file - f_dirty : 0;
 			sc->file_is_reserved = file <= pgdat->min_cache_pages;
 		}
 	}
@@ -2893,9 +2900,6 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
 			BUG();
 		}
 
-		if (sc->file_is_reserved && file)
-			scan = 0;
-
 		nr[lru] = scan;
 	}
 }
