mm: avoid livelock on !__GFP_FS allocations

Under the following conditions, __alloc_pages_slowpath can loop
forever:
gfp_mask & __GFP_WAIT is true
gfp_mask & __GFP_FS is false
reclaim and compaction make no progress
order <= PAGE_ALLOC_COSTLY_ORDER

The gfp conditions are normally invalid, because !__GFP_FS
disables most of the reclaim methods that __GFP_WAIT would
wait for.  However, these conditions happen very often during
suspend and resume, when pm_restrict_gfp_mask() effectively
converts all GFP_KERNEL allocations into __GFP_WAIT.

The oom killer is not run because gfp_mask & __GFP_FS is false,
but should_alloc_retry will always return true when order is less
than PAGE_ALLOC_COSTLY_ORDER.  __alloc_pages_slowpath will
loop forever between the rebalance label and should_alloc_retry,
unless another thread happens to release enough pages to satisfy
the allocation.

Add a check to detect when PM has disabled __GFP_FS, and do not
retry if reclaim is not making any progress.

[taken from patch on lkml by Mel Gorman, commit message by ccross]
Change-Id: I864a24e9d9fd98bd0e3d6e9c1e85b6c1b766850e
Signed-off-by: Colin Cross <ccross@android.com>
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index fef8dc3..a49d672 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -127,6 +127,20 @@
 	saved_gfp_mask = gfp_allowed_mask;
 	gfp_allowed_mask &= ~GFP_IOFS;
 }
+
+static bool pm_suspending(void)
+{
+	if ((gfp_allowed_mask & GFP_IOFS) == GFP_IOFS)
+		return false;
+	return true;
+}
+
+#else
+
+static bool pm_suspending(void)
+{
+	return false;
+}
 #endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
@@ -2194,6 +2208,14 @@
 
 			goto restart;
 		}
+
+		/*
+		 * Suspend converts GFP_KERNEL to __GFP_WAIT which can
+		 * prevent reclaim making forward progress without
+		 * invoking OOM. Bail if we are suspending
+		 */
+		if (pm_suspending())
+			goto nopage;
 	}
 
 	/* Check if we should retry the allocation */