Index: linux-2.6.21-rc5-mm3/mm/sparse.c =================================================================== --- linux-2.6.21-rc5-mm3.orig/mm/sparse.c 2007-03-31 14:58:19.000000000 -0700 +++ linux-2.6.21-rc5-mm3/mm/sparse.c 2007-03-31 22:33:02.000000000 -0700 @@ -224,8 +224,8 @@ BUG_ON(!page); return page_address(page); } else - return alloc_bootmem_node(NODE_DATA(node), - size); + return __alloc_bootmem_node(NODE_DATA(node), size, size, + __pa(MAX_DMA_ADDRESS)); } @@ -239,11 +239,12 @@ static void vmemmap_pop_pmd(pud_t *pud, unsigned long addr, unsigned long end, int node) { - pmd_t *pmd = pmd_offset(pud, addr); - unsigned long next; + pmd_t *pmd; - do { - next = pmd_addr_end(addr, end); + end = pmd_addr_end(addr, end); + + for (pmd = pmd_offset(pud, addr); addr < end; + pmd++, addr += PMD_SIZE) { if (pmd_none(*pmd)) { void *block; pte_t pte; @@ -256,48 +257,50 @@ pte_mkyoung(pte); mk_pte_huge(pte); set_pmd(pmd, __pmd(pte_val(pte))); + printk(KERN_ERR "Installed addr=%lx block=%p " + "pmd=%lx pud=%lx\n", addr, block, + pmd_val(*pmd), pud_val(*pud)); } - pmd++; - addr = next; - } while (addr < end); + } } -static void vmemmap_pop_pud(pgd_t *pgd, unsigned long addr, unsigned long end, int node) +static void vmemmap_pop_pud(pgd_t *pgd, unsigned long addr, + unsigned long end, int node) { - pud_t *pud = pud_offset(pgd, addr); - unsigned long next; + pud_t *pud; + + end = pud_addr_end(addr, end); + for (pud = pud_offset(pgd, addr); addr < end; + pud++, addr += PUD_SIZE) { - do { if (pud_none(*pud)) pud_populate(&init_mm, pud, vmemmap_alloc_block(PAGE_SIZE, node)); - next = pud_addr_end(addr, end); - vmemmap_pop_pmd(pud, addr, next, node); - pud++; - addr = next; - } while (addr < end); + vmemmap_pop_pmd(pud, addr, end, node); + } } - static void vmemmap_populate(struct page *start_page, unsigned long nr, int node) { - unsigned long addr = (unsigned long)start_page; - unsigned long end = (unsigned long)(start_page + nr); - unsigned long next; pgd_t *pgd; + unsigned long addr = (unsigned long)(start_page); + unsigned long end = pgd_addr_end(addr, + (unsigned long)((start_page + nr))); + + printk(KERN_ERR "vmemmap_populate(%p,%ld, %d) size=%d %lx-%lx\n", + start_page, nr, node, end - addr, + addr, end); + + for (pgd = pgd_offset_k(addr); addr < end; + pgd++, addr += PGDIR_SIZE) { - pgd = pgd_offset_k(addr); - do { if (pgd_none(*pgd)) pgd_populate(&init_mm, pgd, vmemmap_alloc_block(PAGE_SIZE, node)); - next = pgd_addr_end(addr, end); vmemmap_pop_pud(pgd, addr, end, node); - pgd++; - addr = next; - } while (addr < end); + } } #endif #endif /* CONFIG_SPARSE_VIRTUAL */