|
@@ -714,7 +714,7 @@ static inline void rmv_page_order(struct page *page)
|
|
|
/*
|
|
|
* This function checks whether a page is free && is the buddy
|
|
|
* we can do coalesce a page and its buddy if
|
|
|
- * (a) the buddy is not in a hole &&
|
|
|
+ * (a) the buddy is not in a hole (check before calling!) &&
|
|
|
* (b) the buddy is in the buddy system &&
|
|
|
* (c) a page and its buddy have the same order &&
|
|
|
* (d) a page and its buddy are in the same zone.
|
|
@@ -729,9 +729,6 @@ static inline void rmv_page_order(struct page *page)
|
|
|
static inline int page_is_buddy(struct page *page, struct page *buddy,
|
|
|
unsigned int order)
|
|
|
{
|
|
|
- if (!pfn_valid_within(page_to_pfn(buddy)))
|
|
|
- return 0;
|
|
|
-
|
|
|
if (page_is_guard(buddy) && page_order(buddy) == order) {
|
|
|
if (page_zone_id(page) != page_zone_id(buddy))
|
|
|
return 0;
|
|
@@ -808,6 +805,9 @@ continue_merging:
|
|
|
while (order < max_order - 1) {
|
|
|
buddy_pfn = __find_buddy_pfn(pfn, order);
|
|
|
buddy = page + (buddy_pfn - pfn);
|
|
|
+
|
|
|
+ if (!pfn_valid_within(buddy_pfn))
|
|
|
+ goto done_merging;
|
|
|
if (!page_is_buddy(page, buddy, order))
|
|
|
goto done_merging;
|
|
|
/*
|
|
@@ -862,7 +862,7 @@ done_merging:
|
|
|
* so it's less likely to be used soon and more likely to be merged
|
|
|
* as a higher order page
|
|
|
*/
|
|
|
- if ((order < MAX_ORDER-2) && pfn_valid_within(page_to_pfn(buddy))) {
|
|
|
+ if ((order < MAX_ORDER-2) && pfn_valid_within(buddy_pfn)) {
|
|
|
struct page *higher_page, *higher_buddy;
|
|
|
combined_pfn = buddy_pfn & pfn;
|
|
|
higher_page = page + (combined_pfn - pfn);
|