diff mbox series

回复: [PATCH v6] mm/vmscan: wake up flushers conditionally to avoid cgroup OOM

Message ID ME0P300MB04146FFE344E7E6248092BF78E552@ME0P300MB0414.AUSP300.PROD.OUTLOOK.COM (mailing list archive)
State New
Headers show
Series 回复: [PATCH v6] mm/vmscan: wake up flushers conditionally to avoid cgroup OOM | expand

Commit Message

解 咏梅 Oct. 31, 2024, 10:37 a.m. UTC
Hi, Jingxiang,


  if (type == LRU_GEN_FILE && dirty) ==>
  if (type == LRU_GEN_FILE && (dirty || writeback)) 

Since, writeback is set when flusher starts to work on it and clear dirty flag.

Best Regards,
Yongmei.

@@ -4327,9 +4328,17 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c
                 return true;
         }
 
+       dirty = folio_test_dirty(folio);
+       writeback = folio_test_writeback(folio);
+       if (type == LRU_GEN_FILE && dirty) {
+               sc->nr.file_taken += delta;
+               if (!writeback)
+                       sc->nr.unqueued_dirty += delta;
+       }
+
diff mbox series

Patch

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 084de0efe59b..794730c8c1de 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4282,6 +4282,7 @@  static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c
                        int tier_idx)
 {
         bool success;
+       bool dirty, writeback;
         int gen = folio_lru_gen(folio);
         int type = folio_is_file_lru(folio);
         int zone = folio_zonenum(folio);
@@ -4327,9 +4328,17 @@  static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c
                 return true;
         }
 
+       dirty = folio_test_dirty(folio);
+       writeback = folio_test_writeback(folio);
+       if (type == LRU_GEN_FILE && dirty) {
+               sc->nr.file_taken += delta;
+               if (!writeback)
+                       sc->nr.unqueued_dirty += delta;
+       }
+
         /* waiting for writeback */
-       if (folio_test_locked(folio) || folio_test_writeback(folio) ||
-           (type == LRU_GEN_FILE && folio_test_dirty(folio))) {
+       if (folio_test_locked(folio) || writeback ||
+           (type == LRU_GEN_FILE && dirty)) {
                 gen = folio_inc_gen(lruvec, folio, true);
                 list_move(&folio->lru, &lrugen->folios[gen][type][zone]);
                 return true;
@@ -4445,7 +4454,8 @@  static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
         trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, MAX_LRU_BATCH,
                                 scanned, skipped, isolated,
                                 type ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON);
-
+       if (type == LRU_GEN_FILE)
+               sc->nr.file_taken += isolated;
         /*
          * There might not be eligible folios due to reclaim_idx. Check the
          * remaining to prevent livelock if it's not making progress.
@@ -4579,6 +4589,7 @@  static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
                 return scanned;
 retry:
         reclaimed = shrink_folio_list(&list, pgdat, sc, &stat, false);
+       sc->nr.unqueued_dirty += stat.nr_unqueued_dirty;
         sc->nr_reclaimed += reclaimed;
         trace_mm_vmscan_lru_shrink_inactive(pgdat->node_id,
                         scanned, reclaimed, &stat, sc->priority,
@@ -4787,6 +4798,13 @@  static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
                 cond_resched();
         }
 
+       /*
+        * If too many file cache in the coldest generation can't be evicted
+        * due to being dirty, wake up the flusher.
+        */
+       if (sc->nr.unqueued_dirty && sc->nr.unqueued_dirty == sc->nr.file_taken)
+               wakeup_flusher_threads(WB_REASON_VMSCAN);
+
         /* whether this lruvec should be rotated */
         return nr_to_scan < 0;
 }
@@ -5932,6 +5950,7 @@  static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
         bool reclaimable = false;
 
         if (lru_gen_enabled() && root_reclaim(sc)) {
+               memset(&sc->nr, 0, sizeof(sc->nr));
                 lru_gen_shrink_node(pgdat, sc);
                 return;
         }