diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-26 04:14:43 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-29 05:49:49 -0400 |
commit | 22adb358e816ce6aa0afb231ae9d826b0bddc8b0 (patch) | |
tree | 6f9886bf5b4e5c916c72d8d5733211813873c5fc /arch/sparc64/mm/init.c | |
parent | 5cbc30737398b49f62ae8603129ce43ac7db1a41 (diff) |
[SPARC64]: Eliminate NR_CPUS limitations.
Cheetah systems can have cpuids as large as 1023, although physical
systems don't have that many cpus.
Only three limitations existed in the kernel preventing arbitrary
NR_CPUS values:
1) dcache dirty cpu state stored in page->flags on
D-cache aliasing platforms. With some build time
calculations and some build-time BUG checks on
page->flags layout, this one was easily solved.
2) The cheetah XCALL delivery code could only handle
a cpumask with up to 32 cpus set. Some simple looping
logic clears that up too.
3) thread_info->cpu was a u8, easily changed to a u16.
There are a few spots in the kernel that still put NR_CPUS
sized arrays on the kernel stack, but that's not a sparc64
specific problem.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/mm/init.c')
-rw-r--r-- | arch/sparc64/mm/init.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 977698269d3a..087cbf09d0b7 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -191,12 +191,9 @@ inline void flush_dcache_page_impl(struct page *page) | |||
191 | } | 191 | } |
192 | 192 | ||
193 | #define PG_dcache_dirty PG_arch_1 | 193 | #define PG_dcache_dirty PG_arch_1 |
194 | #define PG_dcache_cpu_shift 24UL | 194 | #define PG_dcache_cpu_shift 32UL |
195 | #define PG_dcache_cpu_mask (256UL - 1UL) | 195 | #define PG_dcache_cpu_mask \ |
196 | 196 | ((1UL<<ilog2(roundup_pow_of_two(NR_CPUS)))-1UL) | |
197 | #if NR_CPUS > 256 | ||
198 | #error D-cache dirty tracking and thread_info->cpu need fixing for > 256 cpus | ||
199 | #endif | ||
200 | 197 | ||
201 | #define dcache_dirty_cpu(page) \ | 198 | #define dcache_dirty_cpu(page) \ |
202 | (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask) | 199 | (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask) |
@@ -1349,6 +1346,19 @@ void __init paging_init(void) | |||
1349 | unsigned long end_pfn, pages_avail, shift, phys_base; | 1346 | unsigned long end_pfn, pages_avail, shift, phys_base; |
1350 | unsigned long real_end, i; | 1347 | unsigned long real_end, i; |
1351 | 1348 | ||
1349 | /* These build time checkes make sure that the dcache_dirty_cpu() | ||
1350 | * page->flags usage will work. | ||
1351 | * | ||
1352 | * When a page gets marked as dcache-dirty, we store the | ||
1353 | * cpu number starting at bit 32 in the page->flags. Also, | ||
1354 | * functions like clear_dcache_dirty_cpu use the cpu mask | ||
1355 | * in 13-bit signed-immediate instruction fields. | ||
1356 | */ | ||
1357 | BUILD_BUG_ON(FLAGS_RESERVED != 32); | ||
1358 | BUILD_BUG_ON(SECTIONS_WIDTH + NODES_WIDTH + ZONES_WIDTH + | ||
1359 | ilog2(roundup_pow_of_two(NR_CPUS)) > FLAGS_RESERVED); | ||
1360 | BUILD_BUG_ON(NR_CPUS > 4096); | ||
1361 | |||
1352 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | 1362 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; |
1353 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; | 1363 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; |
1354 | 1364 | ||