aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2013-04-29 18:07:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 18:54:35 -0400
commit0aad818b2de455f1bfd7ef87c28cdbbaaed9a699 (patch)
treea86fe62f7c740d431f76bd2262abae5825e1a21e /arch/x86/mm
parent055e4fd96e95b0eee0d92fd54a26be7f0d3bcad0 (diff)
sparse-vmemmap: specify vmemmap population range in bytes
The sparse code, when asking the architecture to populate the vmemmap, specifies the section range as a starting page and a number of pages. This is an awkward interface, because none of the arch-specific code actually thinks of the range in terms of 'struct page' units and always translates it to bytes first. In addition, later patches mix huge page and regular page backing for the vmemmap. For this, they need to call vmemmap_populate_basepages() on sub-section ranges with PAGE_SIZE and PMD_SIZE in mind. But these are not necessarily multiples of the 'struct page' size and so this unit is too coarse. Just translate the section range into bytes once in the generic sparse code, then pass byte ranges down the stack. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Ben Hutchings <ben@decadent.org.uk> Cc: Bernhard Schmidt <Bernhard.Schmidt@lrz.de> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: "Luck, Tony" <tony.luck@intel.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Acked-by: David S. Miller <davem@davemloft.net> Tested-by: David S. Miller <davem@davemloft.net> Cc: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/init_64.c15
1 files changed, 5 insertions, 10 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 2ef81f19bd6c..528c143f467c 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1011,11 +1011,8 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct)
1011 flush_tlb_all(); 1011 flush_tlb_all();
1012} 1012}
1013 1013
1014void __ref vmemmap_free(struct page *memmap, unsigned long nr_pages) 1014void __ref vmemmap_free(unsigned long start, unsigned long end)
1015{ 1015{
1016 unsigned long start = (unsigned long)memmap;
1017 unsigned long end = (unsigned long)(memmap + nr_pages);
1018
1019 remove_pagetable(start, end, false); 1016 remove_pagetable(start, end, false);
1020} 1017}
1021 1018
@@ -1284,17 +1281,15 @@ static long __meminitdata addr_start, addr_end;
1284static void __meminitdata *p_start, *p_end; 1281static void __meminitdata *p_start, *p_end;
1285static int __meminitdata node_start; 1282static int __meminitdata node_start;
1286 1283
1287int __meminit 1284int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
1288vmemmap_populate(struct page *start_page, unsigned long size, int node)
1289{ 1285{
1290 unsigned long addr = (unsigned long)start_page; 1286 unsigned long addr;
1291 unsigned long end = (unsigned long)(start_page + size);
1292 unsigned long next; 1287 unsigned long next;
1293 pgd_t *pgd; 1288 pgd_t *pgd;
1294 pud_t *pud; 1289 pud_t *pud;
1295 pmd_t *pmd; 1290 pmd_t *pmd;
1296 1291
1297 for (; addr < end; addr = next) { 1292 for (addr = start; addr < end; addr = next) {
1298 void *p = NULL; 1293 void *p = NULL;
1299 1294
1300 pgd = vmemmap_pgd_populate(addr, node); 1295 pgd = vmemmap_pgd_populate(addr, node);
@@ -1351,7 +1346,7 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
1351 } 1346 }
1352 1347
1353 } 1348 }
1354 sync_global_pgds((unsigned long)start_page, end - 1); 1349 sync_global_pgds(start, end - 1);
1355 return 0; 1350 return 0;
1356} 1351}
1357 1352