X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=mm%2Fvmscan.c;h=828530e2794a352055eecdcaaff1db79aaafdd3c;hb=7f2de8171ddf28fdb2ca7f9a683ee1207849f718;hp=7f3096137b8a4dc288ba509a98429a1b048bc55f;hpb=9228ff90387e276ad67b10c0eb525c9d6a57d5e9;p=~andy%2Flinux diff --git a/mm/vmscan.c b/mm/vmscan.c index 7f3096137b8..828530e2794 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1177,7 +1177,11 @@ int isolate_lru_page(struct page *page) } /* - * Are there way too many processes in the direct reclaim path already? + * A direct reclaimer may isolate SWAP_CLUSTER_MAX pages from the LRU list and + * then get resheduled. When there are massive number of tasks doing page + * allocation, such sleeping direct reclaimers may keep piling up on each CPU, + * the LRU list will go small and be scanned faster than necessary, leading to + * unnecessary swapping, thrashing and OOM. */ static int too_many_isolated(struct zone *zone, int file, struct scan_control *sc) @@ -1198,6 +1202,14 @@ static int too_many_isolated(struct zone *zone, int file, isolated = zone_page_state(zone, NR_ISOLATED_ANON); } + /* + * GFP_NOIO/GFP_NOFS callers are allowed to isolate more pages, so they + * won't get blocked by normal direct-reclaimers, forming a circular + * deadlock. + */ + if ((sc->gfp_mask & GFP_IOFS) == GFP_IOFS) + inactive >>= 3; + return isolated > inactive; }