aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c48
1 files changed, 18 insertions, 30 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index d4e940a26945..9260314a221e 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -602,27 +602,14 @@ static struct page *next_active_pageblock(struct page *page)
602/* Checks if this range of memory is likely to be hot-removable. */ 602/* Checks if this range of memory is likely to be hot-removable. */
603int is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages) 603int is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages)
604{ 604{
605 int type;
606 struct page *page = pfn_to_page(start_pfn); 605 struct page *page = pfn_to_page(start_pfn);
607 struct page *end_page = page + nr_pages; 606 struct page *end_page = page + nr_pages;
608 607
609 /* Check the starting page of each pageblock within the range */ 608 /* Check the starting page of each pageblock within the range */
610 for (; page < end_page; page = next_active_pageblock(page)) { 609 for (; page < end_page; page = next_active_pageblock(page)) {
611 type = get_pageblock_migratetype(page); 610 if (!is_pageblock_removable_nolock(page))
612
613 /*
614 * A pageblock containing MOVABLE or free pages is considered
615 * removable
616 */
617 if (type != MIGRATE_MOVABLE && !pageblock_free(page))
618 return 0;
619
620 /*
621 * A pageblock starting with a PageReserved page is not
622 * considered removable.
623 */
624 if (PageReserved(page))
625 return 0; 611 return 0;
612 cond_resched();
626 } 613 }
627 614
628 /* All pageblocks in the memory block are likely to be hot-removable */ 615 /* All pageblocks in the memory block are likely to be hot-removable */
@@ -659,7 +646,7 @@ static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
659 * Scanning pfn is much easier than scanning lru list. 646 * Scanning pfn is much easier than scanning lru list.
660 * Scan pfn from start to end and Find LRU page. 647 * Scan pfn from start to end and Find LRU page.
661 */ 648 */
662int scan_lru_pages(unsigned long start, unsigned long end) 649static unsigned long scan_lru_pages(unsigned long start, unsigned long end)
663{ 650{
664 unsigned long pfn; 651 unsigned long pfn;
665 struct page *page; 652 struct page *page;
@@ -709,29 +696,30 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
709 page_is_file_cache(page)); 696 page_is_file_cache(page));
710 697
711 } else { 698 } else {
712 /* Becasue we don't have big zone->lock. we should
713 check this again here. */
714 if (page_count(page))
715 not_managed++;
716#ifdef CONFIG_DEBUG_VM 699#ifdef CONFIG_DEBUG_VM
717 printk(KERN_ALERT "removing pfn %lx from LRU failed\n", 700 printk(KERN_ALERT "removing pfn %lx from LRU failed\n",
718 pfn); 701 pfn);
719 dump_page(page); 702 dump_page(page);
720#endif 703#endif
704 /* Becasue we don't have big zone->lock. we should
705 check this again here. */
706 if (page_count(page)) {
707 not_managed++;
708 ret = -EBUSY;
709 break;
710 }
721 } 711 }
722 } 712 }
723 ret = -EBUSY; 713 if (!list_empty(&source)) {
724 if (not_managed) { 714 if (not_managed) {
725 if (!list_empty(&source)) 715 putback_lru_pages(&source);
716 goto out;
717 }
718 /* this function returns # of failed pages */
719 ret = migrate_pages(&source, hotremove_migrate_alloc, 0, 1);
720 if (ret)
726 putback_lru_pages(&source); 721 putback_lru_pages(&source);
727 goto out;
728 } 722 }
729 ret = 0;
730 if (list_empty(&source))
731 goto out;
732 /* this function returns # of failed pages */
733 ret = migrate_pages(&source, hotremove_migrate_alloc, 0, 1);
734
735out: 723out:
736 return ret; 724 return ret;
737} 725}