|
|
@@ -1213,11 +1213,13 @@ static inline int pageblock_free(struct page *page)
|
|
|
return PageBuddy(page) && page_order(page) >= pageblock_order;
|
|
|
}
|
|
|
|
|
|
-/* Return the start of the next active pageblock after a given page */
|
|
|
-static struct page *next_active_pageblock(struct page *page)
|
|
|
+/* Return the pfn of the start of the next active pageblock after a given pfn */
|
|
|
+static unsigned long next_active_pageblock(unsigned long pfn)
|
|
|
{
|
|
|
+ struct page *page = pfn_to_page(pfn);
|
|
|
+
|
|
|
/* Ensure the starting page is pageblock-aligned */
|
|
|
- BUG_ON(page_to_pfn(page) & (pageblock_nr_pages - 1));
|
|
|
+ BUG_ON(pfn & (pageblock_nr_pages - 1));
|
|
|
|
|
|
/* If the entire pageblock is free, move to the end of free page */
|
|
|
if (pageblock_free(page)) {
|
|
|
@@ -1225,16 +1227,16 @@ static struct page *next_active_pageblock(struct page *page)
|
|
|
/* be careful. we don't have locks, page_order can be changed.*/
|
|
|
order = page_order(page);
|
|
|
if ((order < MAX_ORDER) && (order >= pageblock_order))
|
|
|
- return page + (1 << order);
|
|
|
+ return pfn + (1 << order);
|
|
|
}
|
|
|
|
|
|
- return page + pageblock_nr_pages;
|
|
|
+ return pfn + pageblock_nr_pages;
|
|
|
}
|
|
|
|
|
|
-static bool is_pageblock_removable_nolock(struct page *page)
|
|
|
+static bool is_pageblock_removable_nolock(unsigned long pfn)
|
|
|
{
|
|
|
+ struct page *page = pfn_to_page(pfn);
|
|
|
struct zone *zone;
|
|
|
- unsigned long pfn;
|
|
|
|
|
|
/*
|
|
|
* We have to be careful here because we are iterating over memory
|
|
|
@@ -1257,13 +1259,14 @@ static bool is_pageblock_removable_nolock(struct page *page)
|
|
|
/* Checks if this range of memory is likely to be hot-removable. */
|
|
|
bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages)
|
|
|
{
|
|
|
- struct page *page = pfn_to_page(start_pfn);
|
|
|
- unsigned long end_pfn = min(start_pfn + nr_pages, zone_end_pfn(page_zone(page)));
|
|
|
- struct page *end_page = pfn_to_page(end_pfn);
|
|
|
+ unsigned long end_pfn, pfn;
|
|
|
+
|
|
|
+ end_pfn = min(start_pfn + nr_pages,
|
|
|
+ zone_end_pfn(page_zone(pfn_to_page(start_pfn))));
|
|
|
|
|
|
/* Check the starting page of each pageblock within the range */
|
|
|
- for (; page < end_page; page = next_active_pageblock(page)) {
|
|
|
- if (!is_pageblock_removable_nolock(page))
|
|
|
+ for (pfn = start_pfn; pfn < end_pfn; pfn = next_active_pageblock(pfn)) {
|
|
|
+ if (!is_pageblock_removable_nolock(pfn))
|
|
|
return false;
|
|
|
cond_resched();
|
|
|
}
|