diff options
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r-- | mm/memory_hotplug.c | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 081b4d654ed6..f5ba127b2051 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -75,7 +75,7 @@ static struct resource *register_memory_resource(u64 start, u64 size) | |||
75 | res->end = start + size - 1; | 75 | res->end = start + size - 1; |
76 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | 76 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
77 | if (request_resource(&iomem_resource, res) < 0) { | 77 | if (request_resource(&iomem_resource, res) < 0) { |
78 | printk("System RAM resource %pR cannot be added\n", res); | 78 | pr_debug("System RAM resource %pR cannot be added\n", res); |
79 | kfree(res); | 79 | kfree(res); |
80 | res = NULL; | 80 | res = NULL; |
81 | } | 81 | } |
@@ -101,12 +101,9 @@ void get_page_bootmem(unsigned long info, struct page *page, | |||
101 | atomic_inc(&page->_count); | 101 | atomic_inc(&page->_count); |
102 | } | 102 | } |
103 | 103 | ||
104 | /* reference to __meminit __free_pages_bootmem is valid | 104 | void put_page_bootmem(struct page *page) |
105 | * so use __ref to tell modpost not to generate a warning */ | ||
106 | void __ref put_page_bootmem(struct page *page) | ||
107 | { | 105 | { |
108 | unsigned long type; | 106 | unsigned long type; |
109 | static DEFINE_MUTEX(ppb_lock); | ||
110 | 107 | ||
111 | type = (unsigned long) page->lru.next; | 108 | type = (unsigned long) page->lru.next; |
112 | BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE || | 109 | BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE || |
@@ -116,17 +113,8 @@ void __ref put_page_bootmem(struct page *page) | |||
116 | ClearPagePrivate(page); | 113 | ClearPagePrivate(page); |
117 | set_page_private(page, 0); | 114 | set_page_private(page, 0); |
118 | INIT_LIST_HEAD(&page->lru); | 115 | INIT_LIST_HEAD(&page->lru); |
119 | 116 | free_reserved_page(page); | |
120 | /* | ||
121 | * Please refer to comment for __free_pages_bootmem() | ||
122 | * for why we serialize here. | ||
123 | */ | ||
124 | mutex_lock(&ppb_lock); | ||
125 | __free_pages_bootmem(page, 0); | ||
126 | mutex_unlock(&ppb_lock); | ||
127 | totalram_pages++; | ||
128 | } | 117 | } |
129 | |||
130 | } | 118 | } |
131 | 119 | ||
132 | #ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE | 120 | #ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE |
@@ -309,7 +297,7 @@ static int __meminit move_pfn_range_left(struct zone *z1, struct zone *z2, | |||
309 | /* can't move pfns which are higher than @z2 */ | 297 | /* can't move pfns which are higher than @z2 */ |
310 | if (end_pfn > zone_end_pfn(z2)) | 298 | if (end_pfn > zone_end_pfn(z2)) |
311 | goto out_fail; | 299 | goto out_fail; |
312 | /* the move out part mast at the left most of @z2 */ | 300 | /* the move out part must be at the left most of @z2 */ |
313 | if (start_pfn > z2->zone_start_pfn) | 301 | if (start_pfn > z2->zone_start_pfn) |
314 | goto out_fail; | 302 | goto out_fail; |
315 | /* must included/overlap */ | 303 | /* must included/overlap */ |
@@ -775,29 +763,18 @@ EXPORT_SYMBOL_GPL(restore_online_page_callback); | |||
775 | 763 | ||
776 | void __online_page_set_limits(struct page *page) | 764 | void __online_page_set_limits(struct page *page) |
777 | { | 765 | { |
778 | unsigned long pfn = page_to_pfn(page); | ||
779 | |||
780 | if (pfn >= num_physpages) | ||
781 | num_physpages = pfn + 1; | ||
782 | } | 766 | } |
783 | EXPORT_SYMBOL_GPL(__online_page_set_limits); | 767 | EXPORT_SYMBOL_GPL(__online_page_set_limits); |
784 | 768 | ||
785 | void __online_page_increment_counters(struct page *page) | 769 | void __online_page_increment_counters(struct page *page) |
786 | { | 770 | { |
787 | totalram_pages++; | 771 | adjust_managed_page_count(page, 1); |
788 | |||
789 | #ifdef CONFIG_HIGHMEM | ||
790 | if (PageHighMem(page)) | ||
791 | totalhigh_pages++; | ||
792 | #endif | ||
793 | } | 772 | } |
794 | EXPORT_SYMBOL_GPL(__online_page_increment_counters); | 773 | EXPORT_SYMBOL_GPL(__online_page_increment_counters); |
795 | 774 | ||
796 | void __online_page_free(struct page *page) | 775 | void __online_page_free(struct page *page) |
797 | { | 776 | { |
798 | ClearPageReserved(page); | 777 | __free_reserved_page(page); |
799 | init_page_count(page); | ||
800 | __free_page(page); | ||
801 | } | 778 | } |
802 | EXPORT_SYMBOL_GPL(__online_page_free); | 779 | EXPORT_SYMBOL_GPL(__online_page_free); |
803 | 780 | ||
@@ -918,6 +895,7 @@ static void node_states_set_node(int node, struct memory_notify *arg) | |||
918 | 895 | ||
919 | int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_type) | 896 | int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_type) |
920 | { | 897 | { |
898 | unsigned long flags; | ||
921 | unsigned long onlined_pages = 0; | 899 | unsigned long onlined_pages = 0; |
922 | struct zone *zone; | 900 | struct zone *zone; |
923 | int need_zonelists_rebuild = 0; | 901 | int need_zonelists_rebuild = 0; |
@@ -994,9 +972,12 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ | |||
994 | return ret; | 972 | return ret; |
995 | } | 973 | } |
996 | 974 | ||
997 | zone->managed_pages += onlined_pages; | ||
998 | zone->present_pages += onlined_pages; | 975 | zone->present_pages += onlined_pages; |
976 | |||
977 | pgdat_resize_lock(zone->zone_pgdat, &flags); | ||
999 | zone->zone_pgdat->node_present_pages += onlined_pages; | 978 | zone->zone_pgdat->node_present_pages += onlined_pages; |
979 | pgdat_resize_unlock(zone->zone_pgdat, &flags); | ||
980 | |||
1000 | if (onlined_pages) { | 981 | if (onlined_pages) { |
1001 | node_states_set_node(zone_to_nid(zone), &arg); | 982 | node_states_set_node(zone_to_nid(zone), &arg); |
1002 | if (need_zonelists_rebuild) | 983 | if (need_zonelists_rebuild) |
@@ -1487,6 +1468,7 @@ static int __ref __offline_pages(unsigned long start_pfn, | |||
1487 | unsigned long pfn, nr_pages, expire; | 1468 | unsigned long pfn, nr_pages, expire; |
1488 | long offlined_pages; | 1469 | long offlined_pages; |
1489 | int ret, drain, retry_max, node; | 1470 | int ret, drain, retry_max, node; |
1471 | unsigned long flags; | ||
1490 | struct zone *zone; | 1472 | struct zone *zone; |
1491 | struct memory_notify arg; | 1473 | struct memory_notify arg; |
1492 | 1474 | ||
@@ -1578,10 +1560,12 @@ repeat: | |||
1578 | /* reset pagetype flags and makes migrate type to be MOVABLE */ | 1560 | /* reset pagetype flags and makes migrate type to be MOVABLE */ |
1579 | undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE); | 1561 | undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE); |
1580 | /* removal success */ | 1562 | /* removal success */ |
1581 | zone->managed_pages -= offlined_pages; | 1563 | adjust_managed_page_count(pfn_to_page(start_pfn), -offlined_pages); |
1582 | zone->present_pages -= offlined_pages; | 1564 | zone->present_pages -= offlined_pages; |
1565 | |||
1566 | pgdat_resize_lock(zone->zone_pgdat, &flags); | ||
1583 | zone->zone_pgdat->node_present_pages -= offlined_pages; | 1567 | zone->zone_pgdat->node_present_pages -= offlined_pages; |
1584 | totalram_pages -= offlined_pages; | 1568 | pgdat_resize_unlock(zone->zone_pgdat, &flags); |
1585 | 1569 | ||
1586 | init_per_zone_wmark_min(); | 1570 | init_per_zone_wmark_min(); |
1587 | 1571 | ||