@@ -714,7 +714,7 @@ static inline void rmv_page_order(struct page *page)
714
714
/*
715
715
* This function checks whether a page is free && is the buddy
716
716
* we can do coalesce a page and its buddy if
717
- * (a) the buddy is not in a hole &&
717
+ * (a) the buddy is not in a hole (check before calling!) &&
718
718
* (b) the buddy is in the buddy system &&
719
719
* (c) a page and its buddy have the same order &&
720
720
* (d) a page and its buddy are in the same zone.
@@ -729,9 +729,6 @@ static inline void rmv_page_order(struct page *page)
729
729
static inline int page_is_buddy (struct page * page , struct page * buddy ,
730
730
unsigned int order )
731
731
{
732
- if (!pfn_valid_within (page_to_pfn (buddy )))
733
- return 0 ;
734
-
735
732
if (page_is_guard (buddy ) && page_order (buddy ) == order ) {
736
733
if (page_zone_id (page ) != page_zone_id (buddy ))
737
734
return 0 ;
@@ -808,6 +805,9 @@ static inline void __free_one_page(struct page *page,
808
805
while (order < max_order - 1 ) {
809
806
buddy_pfn = __find_buddy_pfn (pfn , order );
810
807
buddy = page + (buddy_pfn - pfn );
808
+
809
+ if (!pfn_valid_within (buddy_pfn ))
810
+ goto done_merging ;
811
811
if (!page_is_buddy (page , buddy , order ))
812
812
goto done_merging ;
813
813
/*
@@ -862,7 +862,7 @@ static inline void __free_one_page(struct page *page,
862
862
* so it's less likely to be used soon and more likely to be merged
863
863
* as a higher order page
864
864
*/
865
- if ((order < MAX_ORDER - 2 ) && pfn_valid_within (page_to_pfn ( buddy ) )) {
865
+ if ((order < MAX_ORDER - 2 ) && pfn_valid_within (buddy_pfn )) {
866
866
struct page * higher_page , * higher_buddy ;
867
867
combined_pfn = buddy_pfn & pfn ;
868
868
higher_page = page + (combined_pfn - pfn );
0 commit comments