Skip to content

Commit 25224e6

Browse files
Baolin Wang1Naim
authored andcommitted
mm: vmscan: fix dirty folios throttling on cgroup v1 for MGLRU
The balance_dirty_pages() won't do the dirty folios throttling on cgroupv1. See commit 9badce0 ("cgroup, writeback: don't enable cgroup writeback on traditional hierarchies"). Moreover, after commit 6b0dfab ("fs: Remove aops->writepage"), we no longer attempt to write back filesystem folios through reclaim. On large memory systems, the flusher may not be able to write back quickly enough. Consequently, MGLRU will encounter many folios that are already under writeback. Since we cannot reclaim these dirty folios, the system may run out of memory and trigger the OOM killer. Hence, for cgroup v1, let's throttle reclaim after waking up the flusher, which is similar to commit 81a70c2 ("mm/cgroup/reclaim: fix dirty pages throttling on cgroup v1"), to avoid unnecessary OOM. The following test program can easily reproduce the OOM issue. With this patch applied, the test passes successfully. $mkdir /sys/fs/cgroup/memory/test $echo 256M > /sys/fs/cgroup/memory/test/memory.limit_in_bytes $echo $$ > /sys/fs/cgroup/memory/test/cgroup.procs $dd if=/dev/zero of=/mnt/data.bin bs=1M count=800 Fixes: ac35a49 ("mm: multi-gen LRU: minimal implementation") Reviewed-by: Barry Song <baohua@kernel.org> Reviewed-by: Kairui Song <kasong@tencent.com> Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org>
1 parent c369299 commit 25224e6

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

mm/vmscan.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4896,9 +4896,24 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
48964896
* If too many file cache in the coldest generation can't be evicted
48974897
* due to being dirty, wake up the flusher.
48984898
*/
4899-
if (sc->nr.unqueued_dirty && sc->nr.unqueued_dirty == sc->nr.file_taken)
4899+
if (sc->nr.unqueued_dirty && sc->nr.unqueued_dirty == sc->nr.file_taken) {
4900+
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
4901+
49004902
wakeup_flusher_threads(WB_REASON_VMSCAN);
49014903

4904+
/*
4905+
* For cgroupv1 dirty throttling is achieved by waking up
4906+
* the kernel flusher here and later waiting on folios
4907+
* which are in writeback to finish (see shrink_folio_list()).
4908+
*
4909+
* Flusher may not be able to issue writeback quickly
4910+
* enough for cgroupv1 writeback throttling to work
4911+
* on a large system.
4912+
*/
4913+
if (!writeback_throttling_sane(sc))
4914+
reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK);
4915+
}
4916+
49024917
/* whether this lruvec should be rotated */
49034918
return nr_to_scan < 0;
49044919
}

0 commit comments

Comments
 (0)