aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/vmscan.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index ca43aa00ea0e..e37e68725090 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -723,23 +723,38 @@ static unsigned long shrink_page_list(struct list_head *page_list,
723 /* 723 /*
724 * memcg doesn't have any dirty pages throttling so we 724 * memcg doesn't have any dirty pages throttling so we
725 * could easily OOM just because too many pages are in 725 * could easily OOM just because too many pages are in
726 * writeback from reclaim and there is nothing else to 726 * writeback and there is nothing else to reclaim.
727 * reclaim.
728 * 727 *
729 * Check may_enter_fs, certainly because a loop driver 728 * Check __GFP_IO, certainly because a loop driver
730 * thread might enter reclaim, and deadlock if it waits 729 * thread might enter reclaim, and deadlock if it waits
731 * on a page for which it is needed to do the write 730 * on a page for which it is needed to do the write
732 * (loop masks off __GFP_IO|__GFP_FS for this reason); 731 * (loop masks off __GFP_IO|__GFP_FS for this reason);
733 * but more thought would probably show more reasons. 732 * but more thought would probably show more reasons.
733 *
734 * Don't require __GFP_FS, since we're not going into
735 * the FS, just waiting on its writeback completion.
736 * Worryingly, ext4 gfs2 and xfs allocate pages with
737 * grab_cache_page_write_begin(,,AOP_FLAG_NOFS), so
738 * testing may_enter_fs here is liable to OOM on them.
734 */ 739 */
735 if (!global_reclaim(sc) && PageReclaim(page) && 740 if (global_reclaim(sc) ||
736 may_enter_fs) 741 !PageReclaim(page) || !(sc->gfp_mask & __GFP_IO)) {
737 wait_on_page_writeback(page); 742 /*
738 else { 743 * This is slightly racy - end_page_writeback()
744 * might have just cleared PageReclaim, then
745 * setting PageReclaim here end up interpreted
746 * as PageReadahead - but that does not matter
747 * enough to care. What we do want is for this
748 * page to have PageReclaim set next time memcg
749 * reclaim reaches the tests above, so it will
750 * then wait_on_page_writeback() to avoid OOM;
751 * and it's also appropriate in global reclaim.
752 */
753 SetPageReclaim(page);
739 nr_writeback++; 754 nr_writeback++;
740 unlock_page(page); 755 goto keep_locked;
741 goto keep;
742 } 756 }
757 wait_on_page_writeback(page);
743 } 758 }
744 759
745 references = page_check_references(page, sc); 760 references = page_check_references(page, sc);