diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2006-07-06 11:26:02 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-07-13 16:26:08 -0400 |
commit | 565200a14641eb7ab7b96a726441f2e4d663d15c (patch) | |
tree | e9008e42975537314440c21b93b3d4a1f873f577 /arch | |
parent | 7de58fab9ccb63b4194ce39cf163a7491921d037 (diff) |
[MIPS] Do not count pages in holes with sparsemem
With some memory model other than FLATMEM, the single node can
contains some holes so there might be many invalid pages. For
example, with two 256M memory and one 256M hole, some variables
(num_physpage, totalpages, nr_kernel_pages, nr_all_pages, etc.) will
indicate that there are 768MB on this system. This is not desired
because, for example, alloc_large_system_hash() allocates too many
entries.
Use free_area_init_node() with counted zholes_size[] instead of
free_area_init().
For num_physpages, use number of ram pages instead of max_low_pfn.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/mm/init.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 802bdd32aa2b..c52497bb102a 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -139,10 +139,36 @@ void __init fixrange_init(unsigned long start, unsigned long end, | |||
139 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 139 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
140 | extern void pagetable_init(void); | 140 | extern void pagetable_init(void); |
141 | 141 | ||
142 | static int __init page_is_ram(unsigned long pagenr) | ||
143 | { | ||
144 | int i; | ||
145 | |||
146 | for (i = 0; i < boot_mem_map.nr_map; i++) { | ||
147 | unsigned long addr, end; | ||
148 | |||
149 | if (boot_mem_map.map[i].type != BOOT_MEM_RAM) | ||
150 | /* not usable memory */ | ||
151 | continue; | ||
152 | |||
153 | addr = PFN_UP(boot_mem_map.map[i].addr); | ||
154 | end = PFN_DOWN(boot_mem_map.map[i].addr + | ||
155 | boot_mem_map.map[i].size); | ||
156 | |||
157 | if (pagenr >= addr && pagenr < end) | ||
158 | return 1; | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
142 | void __init paging_init(void) | 164 | void __init paging_init(void) |
143 | { | 165 | { |
144 | unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; | 166 | unsigned long zones_size[] = { [0 ... MAX_NR_ZONES - 1] = 0 }; |
145 | unsigned long max_dma, high, low; | 167 | unsigned long max_dma, high, low; |
168 | #ifndef CONFIG_FLATMEM | ||
169 | unsigned long zholes_size[] = { [0 ... MAX_NR_ZONES - 1] = 0 }; | ||
170 | unsigned long i, j, pfn; | ||
171 | #endif | ||
146 | 172 | ||
147 | pagetable_init(); | 173 | pagetable_init(); |
148 | 174 | ||
@@ -174,29 +200,16 @@ void __init paging_init(void) | |||
174 | zones_size[ZONE_HIGHMEM] = high - low; | 200 | zones_size[ZONE_HIGHMEM] = high - low; |
175 | #endif | 201 | #endif |
176 | 202 | ||
203 | #ifdef CONFIG_FLATMEM | ||
177 | free_area_init(zones_size); | 204 | free_area_init(zones_size); |
178 | } | 205 | #else |
179 | 206 | pfn = 0; | |
180 | static inline int page_is_ram(unsigned long pagenr) | 207 | for (i = 0; i < MAX_NR_ZONES; i++) |
181 | { | 208 | for (j = 0; j < zones_size[i]; j++, pfn++) |
182 | int i; | 209 | if (!page_is_ram(pfn)) |
183 | 210 | zholes_size[i]++; | |
184 | for (i = 0; i < boot_mem_map.nr_map; i++) { | 211 | free_area_init_node(0, NODE_DATA(0), zones_size, 0, zholes_size); |
185 | unsigned long addr, end; | 212 | #endif |
186 | |||
187 | if (boot_mem_map.map[i].type != BOOT_MEM_RAM) | ||
188 | /* not usable memory */ | ||
189 | continue; | ||
190 | |||
191 | addr = PFN_UP(boot_mem_map.map[i].addr); | ||
192 | end = PFN_DOWN(boot_mem_map.map[i].addr + | ||
193 | boot_mem_map.map[i].size); | ||
194 | |||
195 | if (pagenr >= addr && pagenr < end) | ||
196 | return 1; | ||
197 | } | ||
198 | |||
199 | return 0; | ||
200 | } | 213 | } |
201 | 214 | ||
202 | static struct kcore_list kcore_mem, kcore_vmalloc; | 215 | static struct kcore_list kcore_mem, kcore_vmalloc; |
@@ -213,9 +226,9 @@ void __init mem_init(void) | |||
213 | #ifdef CONFIG_DISCONTIGMEM | 226 | #ifdef CONFIG_DISCONTIGMEM |
214 | #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet" | 227 | #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet" |
215 | #endif | 228 | #endif |
216 | max_mapnr = num_physpages = highend_pfn; | 229 | max_mapnr = highend_pfn; |
217 | #else | 230 | #else |
218 | max_mapnr = num_physpages = max_low_pfn; | 231 | max_mapnr = max_low_pfn; |
219 | #endif | 232 | #endif |
220 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | 233 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
221 | 234 | ||
@@ -229,6 +242,7 @@ void __init mem_init(void) | |||
229 | if (PageReserved(pfn_to_page(tmp))) | 242 | if (PageReserved(pfn_to_page(tmp))) |
230 | reservedpages++; | 243 | reservedpages++; |
231 | } | 244 | } |
245 | num_physpages = ram; | ||
232 | 246 | ||
233 | #ifdef CONFIG_HIGHMEM | 247 | #ifdef CONFIG_HIGHMEM |
234 | for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { | 248 | for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { |
@@ -247,6 +261,7 @@ void __init mem_init(void) | |||
247 | totalhigh_pages++; | 261 | totalhigh_pages++; |
248 | } | 262 | } |
249 | totalram_pages += totalhigh_pages; | 263 | totalram_pages += totalhigh_pages; |
264 | num_physpages += totalhigh_pages; | ||
250 | #endif | 265 | #endif |
251 | 266 | ||
252 | codesize = (unsigned long) &_etext - (unsigned long) &_text; | 267 | codesize = (unsigned long) &_etext - (unsigned long) &_text; |