default 0 if BASE_FULL
default 1 if !BASE_FULL
+config PAGE_GROUP_BY_MOBILITY
+ bool "Group pages based on their mobility in the page allocator"
+ def_bool y
+ help
+ The standard allocator will fragment memory over time which means
+ that high order allocations will fail even if kswapd is running. If
+ this option is set, the allocator will try and group page types
+ based on their ability to migrate or reclaim. This is a best effort
+ attempt at lowering fragmentation which a few workloads care about.
+ The loss is a more complex allocator that may perform slower. If
+ you are interested in working with large pages, say Y and set
+ /proc/sys/vm/min_free_bytes to 16374. Otherwise say N
+
menuconfig MODULES
bool "Enable loadable module support"
help
EXPORT_SYMBOL(nr_node_ids);
#endif
+#ifdef CONFIG_PAGE_GROUP_BY_MOBILITY
static inline int get_pageblock_migratetype(struct page *page)
{
return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
return ((gfp_flags & __GFP_MOVABLE) != 0);
}
+#else
+static inline int get_pageblock_migratetype(struct page *page)
+{
+ return MIGRATE_UNMOVABLE;
+}
+
+static void set_pageblock_migratetype(struct page *page, int migratetype)
+{
+}
+
+static inline int gfpflags_to_migratetype(gfp_t gfp_flags)
+{
+ return MIGRATE_UNMOVABLE;
+}
+#endif /* CONFIG_PAGE_GROUP_BY_MOBILITY */
+
#ifdef CONFIG_DEBUG_VM
static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
{
return 0;
}
+#ifdef CONFIG_PAGE_GROUP_BY_MOBILITY
/*
* This array describes the order lists are fallen back to when
* the free lists for the desirable migrate type are depleted
return NULL;
}
+#else
+static struct page *__rmqueue_fallback(struct zone *zone, int order,
+ int start_migratetype)
+{
+ return NULL;
+}
+#endif /* CONFIG_PAGE_GROUP_BY_MOBILITY */
/*
* Do the hard work of removing an element from the buddy allocator.
if (unlikely(!pcp->count))
goto failed;
}
+
+#ifdef CONFIG_PAGE_GROUP_BY_MOBILITY
/* Find a page of the appropriate migrate type */
- list_for_each_entry(page, &pcp->list, lru) {
- if (page_private(page) == migratetype) {
- list_del(&page->lru);
- pcp->count--;
+ list_for_each_entry(page, &pcp->list, lru)
+ if (page_private(page) == migratetype)
break;
- }
- }
- /*
- * Check if a page of the appropriate migrate type
- * was found. If not, allocate more to the pcp list
- */
- if (&page->lru == &pcp->list) {
+ /* Allocate more to the pcp list if necessary */
+ if (unlikely(&page->lru == &pcp->list)) {
pcp->count += rmqueue_bulk(zone, 0,
pcp->batch, &pcp->list, migratetype);
page = list_entry(pcp->list.next, struct page, lru);
- VM_BUG_ON(page_private(page) != migratetype);
- list_del(&page->lru);
- pcp->count--;
}
+#else
+ page = list_entry(pcp->list.next, struct page, lru);
+#endif /* CONFIG_PAGE_GROUP_BY_MOBILITY */
+
+ list_del(&page->lru);
+ pcp->count--;
} else {
spin_lock_irqsave(&zone->lock, flags);
page = __rmqueue(zone, order, migratetype);