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, 3 insertions, 45 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 855e0fc928b3..2e916c308ae6 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -24,28 +24,6 @@
24 24
25#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
26 26
27static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
28{
29 struct page *page, *ret;
30 unsigned long memmap_size = sizeof(struct page) * nr_pages;
31
32 page = alloc_pages(GFP_KERNEL, get_order(memmap_size));
33 if (page)
34 goto got_map_page;
35
36 ret = vmalloc(memmap_size);
37 if (ret)
38 goto got_map_ptr;
39
40 return NULL;
41got_map_page:
42 ret = (struct page *)pfn_to_kaddr(page_to_pfn(page));
43got_map_ptr:
44 memset(ret, 0, memmap_size);
45
46 return ret;
47}
48
49extern void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn, 27extern void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
50 unsigned long size); 28 unsigned long size);
51static void __add_zone(struct zone *zone, unsigned long phys_start_pfn) 29static void __add_zone(struct zone *zone, unsigned long phys_start_pfn)
@@ -60,35 +38,15 @@ static void __add_zone(struct zone *zone, unsigned long phys_start_pfn)
60 zonetable_add(zone, nid, zone_type, phys_start_pfn, nr_pages); 38 zonetable_add(zone, nid, zone_type, phys_start_pfn, nr_pages);
61} 39}
62 40
63extern int sparse_add_one_section(struct zone *, unsigned long, 41extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
64 struct page *mem_map); 42 int nr_pages);
65static int __add_section(struct zone *zone, unsigned long phys_start_pfn) 43static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
66{ 44{
67 struct pglist_data *pgdat = zone->zone_pgdat; 45 struct pglist_data *pgdat = zone->zone_pgdat;
68 int nr_pages = PAGES_PER_SECTION; 46 int nr_pages = PAGES_PER_SECTION;
69 struct page *memmap;
70 int ret; 47 int ret;
71 48
72 /* 49 ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages);
73 * This can potentially allocate memory, and does its own
74 * internal locking.
75 */
76 sparse_index_init(pfn_to_section_nr(phys_start_pfn), pgdat->node_id);
77
78 pgdat_resize_lock(pgdat, &flags);
79 memmap = __kmalloc_section_memmap(nr_pages);
80 ret = sparse_add_one_section(zone, phys_start_pfn, memmap);
81 pgdat_resize_unlock(pgdat, &flags);
82
83 if (ret <= 0) {
84 /* the mem_map didn't get used */
85 if (memmap >= (struct page *)VMALLOC_START &&
86 memmap < (struct page *)VMALLOC_END)
87 vfree(memmap);
88 else
89 free_pages((unsigned long)memmap,
90 get_order(sizeof(struct page) * nr_pages));
91 }
92 50
93 if (ret < 0) 51 if (ret < 0)
94 return ret; 52 return ret;