diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a44715e82058..d315e1127dc9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -4477,3 +4477,50 @@ void unset_migratetype_isolate(struct page *page) | |||
4477 | out: | 4477 | out: |
4478 | spin_unlock_irqrestore(&zone->lock, flags); | 4478 | spin_unlock_irqrestore(&zone->lock, flags); |
4479 | } | 4479 | } |
4480 | |||
4481 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
4482 | /* | ||
4483 | * All pages in the range must be isolated before calling this. | ||
4484 | */ | ||
4485 | void | ||
4486 | __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) | ||
4487 | { | ||
4488 | struct page *page; | ||
4489 | struct zone *zone; | ||
4490 | int order, i; | ||
4491 | unsigned long pfn; | ||
4492 | unsigned long flags; | ||
4493 | /* find the first valid pfn */ | ||
4494 | for (pfn = start_pfn; pfn < end_pfn; pfn++) | ||
4495 | if (pfn_valid(pfn)) | ||
4496 | break; | ||
4497 | if (pfn == end_pfn) | ||
4498 | return; | ||
4499 | zone = page_zone(pfn_to_page(pfn)); | ||
4500 | spin_lock_irqsave(&zone->lock, flags); | ||
4501 | pfn = start_pfn; | ||
4502 | while (pfn < end_pfn) { | ||
4503 | if (!pfn_valid(pfn)) { | ||
4504 | pfn++; | ||
4505 | continue; | ||
4506 | } | ||
4507 | page = pfn_to_page(pfn); | ||
4508 | BUG_ON(page_count(page)); | ||
4509 | BUG_ON(!PageBuddy(page)); | ||
4510 | order = page_order(page); | ||
4511 | #ifdef CONFIG_DEBUG_VM | ||
4512 | printk(KERN_INFO "remove from free list %lx %d %lx\n", | ||
4513 | pfn, 1 << order, end_pfn); | ||
4514 | #endif | ||
4515 | list_del(&page->lru); | ||
4516 | rmv_page_order(page); | ||
4517 | zone->free_area[order].nr_free--; | ||
4518 | __mod_zone_page_state(zone, NR_FREE_PAGES, | ||
4519 | - (1UL << order)); | ||
4520 | for (i = 0; i < (1 << order); i++) | ||
4521 | SetPageReserved((page+i)); | ||
4522 | pfn += (1 << order); | ||
4523 | } | ||
4524 | spin_unlock_irqrestore(&zone->lock, flags); | ||
4525 | } | ||
4526 | #endif | ||