diff options
Diffstat (limited to 'mm/sparse.c')
-rw-r--r-- | mm/sparse.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/mm/sparse.c b/mm/sparse.c index 100040c0dfb6..e0a3fe48aa37 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -99,6 +99,22 @@ int __section_nr(struct mem_section* ms) | |||
99 | return (root_nr * SECTIONS_PER_ROOT) + (ms - root); | 99 | return (root_nr * SECTIONS_PER_ROOT) + (ms - root); |
100 | } | 100 | } |
101 | 101 | ||
102 | /* | ||
103 | * During early boot, before section_mem_map is used for an actual | ||
104 | * mem_map, we use section_mem_map to store the section's NUMA | ||
105 | * node. This keeps us from having to use another data structure. The | ||
106 | * node information is cleared just before we store the real mem_map. | ||
107 | */ | ||
108 | static inline unsigned long sparse_encode_early_nid(int nid) | ||
109 | { | ||
110 | return (nid << SECTION_NID_SHIFT); | ||
111 | } | ||
112 | |||
113 | static inline int sparse_early_nid(struct mem_section *section) | ||
114 | { | ||
115 | return (section->section_mem_map >> SECTION_NID_SHIFT); | ||
116 | } | ||
117 | |||
102 | /* Record a memory area against a node. */ | 118 | /* Record a memory area against a node. */ |
103 | void memory_present(int nid, unsigned long start, unsigned long end) | 119 | void memory_present(int nid, unsigned long start, unsigned long end) |
104 | { | 120 | { |
@@ -113,7 +129,8 @@ void memory_present(int nid, unsigned long start, unsigned long end) | |||
113 | 129 | ||
114 | ms = __nr_to_section(section); | 130 | ms = __nr_to_section(section); |
115 | if (!ms->section_mem_map) | 131 | if (!ms->section_mem_map) |
116 | ms->section_mem_map = SECTION_MARKED_PRESENT; | 132 | ms->section_mem_map = sparse_encode_early_nid(nid) | |
133 | SECTION_MARKED_PRESENT; | ||
117 | } | 134 | } |
118 | } | 135 | } |
119 | 136 | ||
@@ -164,6 +181,7 @@ static int sparse_init_one_section(struct mem_section *ms, | |||
164 | if (!valid_section(ms)) | 181 | if (!valid_section(ms)) |
165 | return -EINVAL; | 182 | return -EINVAL; |
166 | 183 | ||
184 | ms->section_mem_map &= ~SECTION_MAP_MASK; | ||
167 | ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum); | 185 | ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum); |
168 | 186 | ||
169 | return 1; | 187 | return 1; |
@@ -172,8 +190,8 @@ static int sparse_init_one_section(struct mem_section *ms, | |||
172 | static struct page *sparse_early_mem_map_alloc(unsigned long pnum) | 190 | static struct page *sparse_early_mem_map_alloc(unsigned long pnum) |
173 | { | 191 | { |
174 | struct page *map; | 192 | struct page *map; |
175 | int nid = early_pfn_to_nid(section_nr_to_pfn(pnum)); | ||
176 | struct mem_section *ms = __nr_to_section(pnum); | 193 | struct mem_section *ms = __nr_to_section(pnum); |
194 | int nid = sparse_early_nid(ms); | ||
177 | 195 | ||
178 | map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION); | 196 | map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION); |
179 | if (map) | 197 | if (map) |