Index: linux-2.6.21-rc5-mm4/mm/sparse.c =================================================================== --- linux-2.6.21-rc5-mm4.orig/mm/sparse.c 2007-04-04 12:21:31.000000000 -0700 +++ linux-2.6.21-rc5-mm4/mm/sparse.c 2007-04-04 15:29:56.000000000 -0700 @@ -271,9 +271,24 @@ #ifndef CONFIG_ARCH_POPULATES_VIRTUAL_MEMMAP +static int vmemmap_verify(pte_t *pte, int node, + unsigned long start, unsigned long end) +{ + unsigned long pfn = pte_pfn(*pte); + int actual_node = early_pfn_to_nid(pfn); + + if (actual_node != node) + printk(KERN_WARNING " [%lx-%lx] offnode page_structs\n", + start, end - 1); + return 0; +} + #ifndef CONFIG_ARCH_SUPPORTS_PMD_MAPPING -static int vmemmap_pte_setup(pte_t *pte, int node) +#define VIRTUAL_MEMMAP_SIZE PAGE_SIZE +#define VIRTUAL_MEMMAP_MASK PAGE_MASK + +static int vmemmap_pte_setup(pte_t *pte, int node, unsigned long addr) { void *block; pte_t entry; @@ -284,6 +299,9 @@ entry = pfn_pte(__pa(block) >> PAGE_SHIFT, PAGE_KERNEL); set_pte(pte, entry); + addr &= ~(PAGE_SIZE - 1); + printk(KERN_INFO " [%lx-%lx]->%p on node %d\n", + addr, addr + PAGE_SIZE -1, block, node); return 0; } @@ -296,7 +314,10 @@ for (pte = pte_offset_map(pmd, addr); addr < end && !error; pte++, addr += PAGE_SIZE) if (pte_none(*pte)) - error = vmemmap_pte_setup(pte, node); + error = vmemmap_pte_setup(pte, node, addr); + else + error = vmemmap_verify(pte, node, + addr + PAGE_SIZE, end); return error; } @@ -313,13 +334,16 @@ #else /* CONFIG_ARCH_SUPPORTS_PMD_MAPPING */ +#define VIRTUAL_MEMMAP_SIZE PMD_SIZE +#define VIRTUAL_MEMMAP_MASK PMD_MASK + static int vmemmap_pop_pte(pmd_t *pmd, unsigned long addr, unsigned long end, int node) { return 0; } -static int vmemmap_pmd_setup(pmd_t *pmd, int node) +static int vmemmap_pmd_setup(pmd_t *pmd, int node, unsigned long addr) { void *block; pte_t entry; @@ -331,6 +355,9 @@ entry = pfn_pte(__pa(block) >> PAGE_SHIFT, PAGE_KERNEL); mk_pte_huge(entry); set_pmd(pmd, __pmd(pte_val(entry))); + addr &= ~(PMD_SIZE - 1); + printk(KERN_INFO " [%lx-%lx]->%p on node %d\n", + addr, addr + PMD_SIZE - 1, block, node); return 0; } @@ -342,15 +369,17 @@ pmd_t *pmd; int error = 0; - end = pmd_addr_end(addr, end); - for (pmd = pmd_offset(pud, addr); addr < end && !error; pmd++, addr += PMD_SIZE) { if (pmd_none(*pmd)) - error = vmemmap_pmd_setup(pmd, node); + error = vmemmap_pmd_setup(pmd, node, addr); + else + error = vmemmap_verify((pte_t *)pmd, node, + pmd_addr_end(addr, end), end); if (!error) - error = vmemmap_pop_pte(pmd, addr, end, node); + error = vmemmap_pop_pte(pmd, addr, + pmd_addr_end(addr, end), node); } return error; } @@ -361,7 +390,6 @@ pud_t *pud; int error = 0; - end = pud_addr_end(addr, end); for (pud = pud_offset(pgd, addr); addr < end && !error; pud++, addr += PUD_SIZE) { @@ -374,7 +402,8 @@ pud_populate(&init_mm, pud, p); } - error = vmemmap_pop_pmd(pud, addr, end, node); + error = vmemmap_pop_pmd(pud, addr, + pud_addr_end(addr, end), node); } return error; } @@ -383,11 +412,17 @@ int node) { pgd_t *pgd; - unsigned long addr = (unsigned long)start_page; - unsigned long end = pgd_addr_end(addr, - (unsigned long)(start_page + nr)); + unsigned long addr = (unsigned long)start_page & VIRTUAL_MEMMAP_MASK; + unsigned long end = + ((unsigned long)(start_page + nr) & VIRTUAL_MEMMAP_MASK) + + VIRTUAL_MEMMAP_SIZE; int error = 0; + printk(KERN_INFO "[%lx-%lx] Virtual memory section" + " (%ld pages) node %d\n", + (unsigned long)start_page, + (unsigned long)(start_page + nr) - 1, nr, node); + for (pgd = pgd_offset_k(addr); addr < end && !error; pgd++, addr += PGDIR_SIZE) { @@ -397,7 +432,8 @@ pgd_populate(&init_mm, pgd, p); } - error = vmemmap_pop_pud(pgd, addr, end, node); + error = vmemmap_pop_pud(pgd, addr, + pgd_addr_end(addr, end), node); } return error; }