|
@@ -661,7 +661,8 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
|
|
* Go through the free lists for the given migratetype and remove
|
|
* Go through the free lists for the given migratetype and remove
|
|
* the smallest available page from the freelists
|
|
* the smallest available page from the freelists
|
|
*/
|
|
*/
|
|
-static struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
|
|
|
|
|
|
+static inline
|
|
|
|
+struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
|
|
int migratetype)
|
|
int migratetype)
|
|
{
|
|
{
|
|
unsigned int current_order;
|
|
unsigned int current_order;
|
|
@@ -831,8 +832,7 @@ static struct page *__rmqueue_fallback(struct zone *zone, int order,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* Use MIGRATE_RESERVE rather than fail an allocation */
|
|
|
|
- return __rmqueue_smallest(zone, order, MIGRATE_RESERVE);
|
|
|
|
|
|
+ return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -844,11 +844,23 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order,
|
|
{
|
|
{
|
|
struct page *page;
|
|
struct page *page;
|
|
|
|
|
|
|
|
+retry_reserve:
|
|
page = __rmqueue_smallest(zone, order, migratetype);
|
|
page = __rmqueue_smallest(zone, order, migratetype);
|
|
|
|
|
|
- if (unlikely(!page))
|
|
|
|
|
|
+ if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
|
|
page = __rmqueue_fallback(zone, order, migratetype);
|
|
page = __rmqueue_fallback(zone, order, migratetype);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Use MIGRATE_RESERVE rather than fail an allocation. goto
|
|
|
|
+ * is used because __rmqueue_smallest is an inline function
|
|
|
|
+ * and we want just one call site
|
|
|
|
+ */
|
|
|
|
+ if (!page) {
|
|
|
|
+ migratetype = MIGRATE_RESERVE;
|
|
|
|
+ goto retry_reserve;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
return page;
|
|
return page;
|
|
}
|
|
}
|
|
|
|
|