diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-08-30 23:30:38 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-08-30 23:30:38 +0100 |
commit | 0a7d5f8ce960e74fa22986bda4af488539796e49 (patch) | |
tree | e29ad17808a5c3410518e22dae8dfe94801b59f3 /arch/ia64/mm | |
parent | 0165508c80a2b5d5268d9c5dfa9b30c534a33693 (diff) | |
parent | dc709bd190c130b299ac19d596594256265c042a (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/ia64/mm')
-rw-r--r-- | arch/ia64/mm/contig.c | 16 | ||||
-rw-r--r-- | arch/ia64/mm/discontig.c | 68 | ||||
-rw-r--r-- | arch/ia64/mm/init.c | 55 | ||||
-rw-r--r-- | arch/ia64/mm/ioremap.c | 6 |
4 files changed, 73 insertions, 72 deletions
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 2a88cdd6d92..e004143ba86 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -27,6 +27,7 @@ #ifdef CONFIG_VIRTUAL_MEM_MAP static unsigned long num_dma_physpages; +static unsigned long max_gap; #endif /** @@ -45,9 +46,15 @@ show_mem (void) printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; - while (i-- > 0) { - if (!pfn_valid(i)) + for (i = 0; i < max_mapnr; i++) { + if (!pfn_valid(i)) { +#ifdef CONFIG_VIRTUAL_MEM_MAP + if (max_gap < LARGE_GAP) + continue; + i = vmemmap_find_next_valid_pfn(0, i) - 1; +#endif continue; + } total++; if (PageReserved(mem_map+i)) reserved++; @@ -234,7 +241,6 @@ paging_init (void) unsigned long zones_size[MAX_NR_ZONES]; #ifdef CONFIG_VIRTUAL_MEM_MAP unsigned long zholes_size[MAX_NR_ZONES]; - unsigned long max_gap; #endif /* initialize mem_map[] */ @@ -266,7 +272,6 @@ paging_init (void) } } - max_gap = 0; efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); if (max_gap < LARGE_GAP) { vmem_map = (struct page *) 0; @@ -277,7 +282,8 @@ paging_init (void) /* allocate virtual_mem_map */ - map_size = PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + map_size = PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * + sizeof(struct page)); vmalloc_end -= map_size; vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, NULL); diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 99bd9e30db9..d260bffa01a 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -534,68 +534,6 @@ void __cpuinit *per_cpu_init(void) } #endif /* CONFIG_SMP */ -#ifdef CONFIG_VIRTUAL_MEM_MAP -static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) -{ - unsigned long end_address, hole_next_pfn; - unsigned long stop_address; - - end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i]; - end_address = PAGE_ALIGN(end_address); - - stop_address = (unsigned long) &vmem_map[ - pgdat->node_start_pfn + pgdat->node_spanned_pages]; - - do { - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - - pgd = pgd_offset_k(end_address); - if (pgd_none(*pgd)) { - end_address += PGDIR_SIZE; - continue; - } - - pud = pud_offset(pgd, end_address); - if (pud_none(*pud)) { - end_address += PUD_SIZE; - continue; - } - - pmd = pmd_offset(pud, end_address); - if (pmd_none(*pmd)) { - end_address += PMD_SIZE; - continue; - } - - pte = pte_offset_kernel(pmd, end_address); -retry_pte: - if (pte_none(*pte)) { - end_address += PAGE_SIZE; - pte++; - if ((end_address < stop_address) && - (end_address != ALIGN(end_address, 1UL << PMD_SHIFT))) - goto retry_pte; - continue; - } - /* Found next valid vmem_map page */ - break; - } while (end_address < stop_address); - - end_address = min(end_address, stop_address); - end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1; - hole_next_pfn = end_address / sizeof(struct page); - return hole_next_pfn - pgdat->node_start_pfn; -} -#else -static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) -{ - return i + 1; -} -#endif - /** * show_mem - give short summary of memory stats * @@ -625,7 +563,8 @@ void show_mem(void) if (pfn_valid(pgdat->node_start_pfn + i)) page = pfn_to_page(pgdat->node_start_pfn + i); else { - i = find_next_valid_pfn_for_pgdat(pgdat, i) - 1; + i = vmemmap_find_next_valid_pfn(pgdat->node_id, + i) - 1; continue; } if (PageReserved(page)) @@ -751,7 +690,8 @@ void __init paging_init(void) efi_memmap_walk(filter_rsvd_memory, count_node_pages); #ifdef CONFIG_VIRTUAL_MEM_MAP - vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + vmalloc_end -= PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * + sizeof(struct page)); vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, NULL); printk("Virtual mem_map starts at 0x%p\n", vmem_map); diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 2f50c064513..30617ccb4f7 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -415,6 +415,61 @@ ia64_mmu_init (void *my_cpu_data) } #ifdef CONFIG_VIRTUAL_MEM_MAP +int vmemmap_find_next_valid_pfn(int node, int i) +{ + unsigned long end_address, hole_next_pfn; + unsigned long stop_address; + pg_data_t *pgdat = NODE_DATA(node); + + end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i]; + end_address = PAGE_ALIGN(end_address); + + stop_address = (unsigned long) &vmem_map[ + pgdat->node_start_pfn + pgdat->node_spanned_pages]; + + do { + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + pgd = pgd_offset_k(end_address); + if (pgd_none(*pgd)) { + end_address += PGDIR_SIZE; + continue; + } + + pud = pud_offset(pgd, end_address); + if (pud_none(*pud)) { + end_address += PUD_SIZE; + continue; + } + + pmd = pmd_offset(pud, end_address); + if (pmd_none(*pmd)) { + end_address += PMD_SIZE; + continue; + } + + pte = pte_offset_kernel(pmd, end_address); +retry_pte: + if (pte_none(*pte)) { + end_address += PAGE_SIZE; + pte++; + if ((end_address < stop_address) && + (end_address != ALIGN(end_address, 1UL << PMD_SHIFT))) + goto retry_pte; + continue; + } + /* Found next valid vmem_map page */ + break; + } while (end_address < stop_address); + + end_address = min(end_address, stop_address); + end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1; + hole_next_pfn = end_address / sizeof(struct page); + return hole_next_pfn - pgdat->node_start_pfn; +} int __init create_mem_map_page_table (u64 start, u64 end, void *arg) diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 07bd02b6c37..4280c074d64 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c @@ -32,7 +32,7 @@ ioremap (unsigned long offset, unsigned long size) */ attr = kern_mem_attribute(offset, size); if (attr & EFI_MEMORY_WB) - return phys_to_virt(offset); + return (void __iomem *) phys_to_virt(offset); else if (attr & EFI_MEMORY_UC) return __ioremap(offset, size); @@ -43,7 +43,7 @@ ioremap (unsigned long offset, unsigned long size) gran_base = GRANULEROUNDDOWN(offset); gran_size = GRANULEROUNDUP(offset + size) - gran_base; if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB) - return phys_to_virt(offset); + return (void __iomem *) phys_to_virt(offset); return __ioremap(offset, size); } @@ -53,7 +53,7 @@ void __iomem * ioremap_nocache (unsigned long offset, unsigned long size) { if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB) - return 0; + return NULL; return __ioremap(offset, size); } |