mm: Add total_unmovable_pages global variable
Vmalloc will exit if the amount it needs to allocate is
greater than totalram_pages. Vmalloc cannot allocate
from the movable zone, so pages in the movable zone should
not be counted.
This change adds a new global variable: total_unmovable_pages.
It is calculated in init.c, based on totalram_pages minus
the pages in the movable zone. Vmalloc now looks at this new
global instead of totalram_pages.
total_unmovable_pages can be modified during memory_hotplug.
If the zone you are offlining/onlining is unmovable, then
you modify it similar to totalram_pages. If the zone is
movable, then no change is needed.
Change-Id: Ie55c41051e9ad4b921eb04ecbb4798a8bd2344d6
Signed-off-by: Jack Cheung <jackc@codeaurora.org>
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index faf318e..70ea0df 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -379,6 +379,10 @@
unsigned long pfn = page_to_pfn(page);
totalram_pages++;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ if (zone_idx(page_zone(page)) != ZONE_MOVABLE)
+ total_unmovable_pages++;
+#endif
if (pfn >= num_physpages)
num_physpages = pfn + 1;
@@ -965,6 +969,10 @@
zone->zone_pgdat->node_present_pages -= offlined_pages;
totalram_pages -= offlined_pages;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ if (zone_idx(zone) != ZONE_MOVABLE)
+ total_unmovable_pages -= offlined_pages;
+#endif
init_per_zone_wmark_min();
if (!node_present_pages(node)) {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5489c43..60ad5e9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -96,6 +96,9 @@
unsigned long totalram_pages __read_mostly;
unsigned long totalreserve_pages __read_mostly;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+unsigned long total_unmovable_pages __read_mostly;
+#endif
int percpu_pagelist_fraction;
gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
@@ -174,6 +177,9 @@
};
EXPORT_SYMBOL(totalram_pages);
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+EXPORT_SYMBOL(total_unmovable_pages);
+#endif
static char * const zone_names[MAX_NR_ZONES] = {
#ifdef CONFIG_ZONE_DMA
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 45ece89..c33d2ae 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1611,9 +1611,14 @@
struct vm_struct *area;
void *addr;
unsigned long real_size = size;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+ unsigned long total_pages = total_unmovable_pages;
+#else
+ unsigned long total_pages = totalram_pages;
+#endif
size = PAGE_ALIGN(size);
- if (!size || (size >> PAGE_SHIFT) > totalram_pages)
+ if (!size || (size >> PAGE_SHIFT) > total_pages)
return NULL;
area = __get_vm_area_node(size, align, VM_ALLOC, start, end, node,