Skip to content

Commit db73ee0

Browse files
Michal Hockotorvalds
authored andcommitted
mm, vmscan: do not loop on too_many_isolated for ever
Tetsuo Handa has reported[1][2][3] that direct reclaimers might get stuck in too_many_isolated loop basically for ever because the last few pages on the LRU lists are isolated by the kswapd which is stuck on fs locks when doing the pageout or slab reclaim. This in turn means that there is nobody to actually trigger the oom killer and the system is basically unusable. too_many_isolated has been introduced by commit 35cd781 ("vmscan: throttle direct reclaim when too many pages are isolated already") to prevent from pre-mature oom killer invocations because back then no reclaim progress could indeed trigger the OOM killer too early. But since the oom detection rework in commit 0a0337e ("mm, oom: rework oom detection") the allocation/reclaim retry loop considers all the reclaimable pages and throttles the allocation at that layer so we can loosen the direct reclaim throttling. Make shrink_inactive_list loop over too_many_isolated bounded and returns immediately when the situation hasn't resolved after the first sleep. Replace congestion_wait by a simple schedule_timeout_interruptible because we are not really waiting on the IO congestion in this path. Please note that this patch can theoretically cause the OOM killer to trigger earlier while there are many pages isolated for the reclaim which makes progress only very slowly. This would be obvious from the oom report as the number of isolated pages are printed there. If we ever hit this should_reclaim_retry should consider those numbers in the evaluation in one way or another. [1] http://lkml.kernel.org/r/[email protected] [2] http://lkml.kernel.org/r/[email protected] [3] http://lkml.kernel.org/r/[email protected] [[email protected]: switch to uninterruptible sleep] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Michal Hocko <[email protected]> Reported-by: Tetsuo Handa <[email protected]> Tested-by: Tetsuo Handa <[email protected]> Acked-by: Mel Gorman <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Acked-by: Rik van Riel <[email protected]> Acked-by: Johannes Weiner <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 77ff465 commit db73ee0

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

mm/vmscan.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1743,9 +1743,15 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
17431743
int file = is_file_lru(lru);
17441744
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
17451745
struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat;
1746+
bool stalled = false;
17461747

17471748
while (unlikely(too_many_isolated(pgdat, file, sc))) {
1748-
congestion_wait(BLK_RW_ASYNC, HZ/10);
1749+
if (stalled)
1750+
return 0;
1751+
1752+
/* wait a bit for the reclaimer. */
1753+
msleep(100);
1754+
stalled = true;
17491755

17501756
/* We are about to die and free our memory. Return now. */
17511757
if (fatal_signal_pending(current))

0 commit comments

Comments
 (0)