Merge "android/lowmemorykiller: Only consider gfp_mask free pages"
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 91f4964..432abe5 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -62,6 +62,65 @@
 			printk(x);			\
 	} while (0)
 
+static int nr_free_zone_mtype_pages(struct zone *zone, int mtype)
+{
+	int order;
+	int sum = 0;
+
+	for (order = 0; order < MAX_ORDER; ++order) {
+		unsigned long freecount = 0;
+		struct free_area *area;
+		struct list_head *curr;
+
+		area = &(zone->free_area[order]);
+
+		list_for_each(curr, &area->free_list[mtype])
+			freecount++;
+
+		sum += freecount << order;
+	}
+	return sum;
+}
+
+static int nr_free_zone_pages(struct zone *zone, gfp_t gfp_mask)
+{
+	int sum = 0;
+	int mtype = allocflags_to_migratetype(gfp_mask);
+	int i = 0;
+	int *mtype_fallbacks = get_migratetype_fallbacks(mtype);
+
+	sum = nr_free_zone_mtype_pages(zone, mtype);
+
+	/*
+	 * Also count the fallback pages
+	 */
+	for (i = 0;; i++) {
+		int fallbacktype = mtype_fallbacks[i];
+		sum += nr_free_zone_mtype_pages(zone, fallbacktype);
+
+		if (fallbacktype == MIGRATE_RESERVE)
+			break;
+	}
+
+	return sum;
+}
+
+static int nr_free_pages(gfp_t gfp_mask)
+{
+	struct zoneref *z;
+	struct zone *zone;
+	int sum = 0;
+
+	struct zonelist *zonelist = node_zonelist(numa_node_id(), gfp_mask);
+
+	for_each_zone_zonelist(zone, z, zonelist, gfp_zone(gfp_mask)) {
+		sum += nr_free_zone_pages(zone, gfp_mask);
+	}
+
+	return sum;
+}
+
+
 static int test_task_flag(struct task_struct *p, int flag)
 {
 	struct task_struct *t = p;
@@ -93,6 +152,15 @@
 	int other_file = global_page_state(NR_FILE_PAGES) -
 						global_page_state(NR_SHMEM);
 
+	if (sc->nr_to_scan > 0 && other_free > other_file) {
+		/*
+		 * If the number of free pages is going to affect the decision
+		 * of which process is selected then ensure only free pages
+		 * which can satisfy the request are considered.
+		 */
+		other_free = nr_free_pages(sc->gfp_mask);
+	}
+
 	if (lowmem_adj_size < array_size)
 		array_size = lowmem_adj_size;
 	if (lowmem_minfree_size < array_size)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index f8a3a10..08f74e6 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -61,6 +61,14 @@
 	MIGRATE_TYPES
 };
 
+/*
+ * Returns a list which contains the migrate types on to which
+ * an allocation falls back when the free list for the migrate
+ * type mtype is depleted.
+ * The end of the list is delimited by the type MIGRATE_RESERVE.
+ */
+extern int *get_migratetype_fallbacks(int mtype);
+
 #ifdef CONFIG_CMA
 #  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
 #  define cma_wmark_pages(zone)	zone->min_cma_pages
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 831509c..c3142e8 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -913,6 +913,11 @@
 	[MIGRATE_ISOLATE]     = { MIGRATE_RESERVE }, /* Never used */
 };
 
+int *get_migratetype_fallbacks(int mtype)
+{
+	return fallbacks[mtype];
+}
+
 /*
  * Move the free pages in a range to the free lists of the requested type.
  * Note that start_page and end_pages are not aligned on a pageblock