aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/memory_hotplug.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 124e794867c5..1ad28323fb9f 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1188,11 +1188,13 @@ static inline int pageblock_free(struct page *page)
1188 return PageBuddy(page) && page_order(page) >= pageblock_order; 1188 return PageBuddy(page) && page_order(page) >= pageblock_order;
1189} 1189}
1190 1190
1191/* Return the start of the next active pageblock after a given page */ 1191/* Return the pfn of the start of the next active pageblock after a given pfn */
1192static struct page *next_active_pageblock(struct page *page) 1192static unsigned long next_active_pageblock(unsigned long pfn)
1193{ 1193{
1194 struct page *page = pfn_to_page(pfn);
1195
1194 /* Ensure the starting page is pageblock-aligned */ 1196 /* Ensure the starting page is pageblock-aligned */
1195 BUG_ON(page_to_pfn(page) & (pageblock_nr_pages - 1)); 1197 BUG_ON(pfn & (pageblock_nr_pages - 1));
1196 1198
1197 /* If the entire pageblock is free, move to the end of free page */ 1199 /* If the entire pageblock is free, move to the end of free page */
1198 if (pageblock_free(page)) { 1200 if (pageblock_free(page)) {
@@ -1200,16 +1202,16 @@ static struct page *next_active_pageblock(struct page *page)
1200 /* be careful. we don't have locks, page_order can be changed.*/ 1202 /* be careful. we don't have locks, page_order can be changed.*/
1201 order = page_order(page); 1203 order = page_order(page);
1202 if ((order < MAX_ORDER) && (order >= pageblock_order)) 1204 if ((order < MAX_ORDER) && (order >= pageblock_order))
1203 return page + (1 << order); 1205 return pfn + (1 << order);
1204 } 1206 }
1205 1207
1206 return page + pageblock_nr_pages; 1208 return pfn + pageblock_nr_pages;
1207} 1209}
1208 1210
1209static bool is_pageblock_removable_nolock(struct page *page) 1211static bool is_pageblock_removable_nolock(unsigned long pfn)
1210{ 1212{
1213 struct page *page = pfn_to_page(pfn);
1211 struct zone *zone; 1214 struct zone *zone;
1212 unsigned long pfn;
1213 1215
1214 /* 1216 /*
1215 * We have to be careful here because we are iterating over memory 1217 * We have to be careful here because we are iterating over memory
@@ -1232,13 +1234,14 @@ static bool is_pageblock_removable_nolock(struct page *page)
1232/* Checks if this range of memory is likely to be hot-removable. */ 1234/* Checks if this range of memory is likely to be hot-removable. */
1233bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages) 1235bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages)
1234{ 1236{
1235 struct page *page = pfn_to_page(start_pfn); 1237 unsigned long end_pfn, pfn;
1236 unsigned long end_pfn = min(start_pfn + nr_pages, zone_end_pfn(page_zone(page))); 1238
1237 struct page *end_page = pfn_to_page(end_pfn); 1239 end_pfn = min(start_pfn + nr_pages,
1240 zone_end_pfn(page_zone(pfn_to_page(start_pfn))));
1238 1241
1239 /* Check the starting page of each pageblock within the range */ 1242 /* Check the starting page of each pageblock within the range */
1240 for (; page < end_page; page = next_active_pageblock(page)) { 1243 for (pfn = start_pfn; pfn < end_pfn; pfn = next_active_pageblock(pfn)) {
1241 if (!is_pageblock_removable_nolock(page)) 1244 if (!is_pageblock_removable_nolock(pfn))
1242 return false; 1245 return false;
1243 cond_resched(); 1246 cond_resched();
1244 } 1247 }