diff options
Diffstat (limited to 'mm/sparse.c')
| -rw-r--r-- | mm/sparse.c | 38 | 
1 files changed, 32 insertions, 6 deletions
| diff --git a/mm/sparse.c b/mm/sparse.c index b54e304df4a7..b2b456bf0a5d 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
| @@ -13,7 +13,26 @@ | |||
| 13 | * | 13 | * | 
| 14 | * 1) mem_section - memory sections, mem_map's for valid memory | 14 | * 1) mem_section - memory sections, mem_map's for valid memory | 
| 15 | */ | 15 | */ | 
| 16 | struct mem_section mem_section[NR_MEM_SECTIONS]; | 16 | #ifdef CONFIG_ARCH_SPARSEMEM_EXTREME | 
| 17 | struct mem_section *mem_section[NR_SECTION_ROOTS] | ||
| 18 | ____cacheline_maxaligned_in_smp; | ||
| 19 | |||
| 20 | static void sparse_index_init(unsigned long section, int nid) | ||
| 21 | { | ||
| 22 | unsigned long root = SECTION_TO_ROOT(section); | ||
| 23 | |||
| 24 | if (mem_section[root]) | ||
| 25 | return; | ||
| 26 | mem_section[root] = alloc_bootmem_node(NODE_DATA(nid), PAGE_SIZE); | ||
| 27 | if (mem_section[root]) | ||
| 28 | memset(mem_section[root], 0, PAGE_SIZE); | ||
| 29 | else | ||
| 30 | panic("memory_present: NO MEMORY\n"); | ||
| 31 | } | ||
| 32 | #else | ||
| 33 | struct mem_section mem_section[NR_MEM_SECTIONS] | ||
| 34 | ____cacheline_maxaligned_in_smp; | ||
| 35 | #endif | ||
| 17 | EXPORT_SYMBOL(mem_section); | 36 | EXPORT_SYMBOL(mem_section); | 
| 18 | 37 | ||
| 19 | /* Record a memory area against a node. */ | 38 | /* Record a memory area against a node. */ | 
| @@ -24,8 +43,13 @@ void memory_present(int nid, unsigned long start, unsigned long end) | |||
| 24 | start &= PAGE_SECTION_MASK; | 43 | start &= PAGE_SECTION_MASK; | 
| 25 | for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { | 44 | for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { | 
| 26 | unsigned long section = pfn_to_section_nr(pfn); | 45 | unsigned long section = pfn_to_section_nr(pfn); | 
| 27 | if (!mem_section[section].section_mem_map) | 46 | struct mem_section *ms; | 
| 28 | mem_section[section].section_mem_map = SECTION_MARKED_PRESENT; | 47 | |
| 48 | sparse_index_init(section, nid); | ||
| 49 | |||
| 50 | ms = __nr_to_section(section); | ||
| 51 | if (!ms->section_mem_map) | ||
| 52 | ms->section_mem_map = SECTION_MARKED_PRESENT; | ||
| 29 | } | 53 | } | 
| 30 | } | 54 | } | 
| 31 | 55 | ||
| @@ -85,6 +109,7 @@ static struct page *sparse_early_mem_map_alloc(unsigned long pnum) | |||
| 85 | { | 109 | { | 
| 86 | struct page *map; | 110 | struct page *map; | 
| 87 | int nid = early_pfn_to_nid(section_nr_to_pfn(pnum)); | 111 | int nid = early_pfn_to_nid(section_nr_to_pfn(pnum)); | 
| 112 | struct mem_section *ms = __nr_to_section(pnum); | ||
| 88 | 113 | ||
| 89 | map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION); | 114 | map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION); | 
| 90 | if (map) | 115 | if (map) | 
| @@ -96,7 +121,7 @@ static struct page *sparse_early_mem_map_alloc(unsigned long pnum) | |||
| 96 | return map; | 121 | return map; | 
| 97 | 122 | ||
| 98 | printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__); | 123 | printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__); | 
| 99 | mem_section[pnum].section_mem_map = 0; | 124 | ms->section_mem_map = 0; | 
| 100 | return NULL; | 125 | return NULL; | 
| 101 | } | 126 | } | 
| 102 | 127 | ||
| @@ -114,8 +139,9 @@ void sparse_init(void) | |||
| 114 | continue; | 139 | continue; | 
| 115 | 140 | ||
| 116 | map = sparse_early_mem_map_alloc(pnum); | 141 | map = sparse_early_mem_map_alloc(pnum); | 
| 117 | if (map) | 142 | if (!map) | 
| 118 | sparse_init_one_section(&mem_section[pnum], pnum, map); | 143 | continue; | 
| 144 | sparse_init_one_section(__nr_to_section(pnum), pnum, map); | ||
| 119 | } | 145 | } | 
| 120 | } | 146 | } | 
| 121 | 147 | ||
