split contig and discontig paging_init functions
PATCH 1/1 split contig and discontig paging_init functions
Split up the contig and discontig versions of paging_init() into the appropriate files.
arch/ia64/mm/contig.c | 95 +++++++++++++++++++++++++++++++++++++++ arch/ia64/mm/discontig.c | 6 +- arch/ia64/mm/init.c | 108 +-------------------------------------------- include/asm-ia64/meminit.h | 11 ++++
Thanks,
Jesse
arch/ia64/mm/contig.c +94 -0
@@ -25,6 +25,10 @@#include <asm/pgtable.h> #include <asm/sections.h> +#ifdef CONFIG_VIRTUAL_MEM_MAP +static unsigned long num_dma_physpages; +#endif +/** * show_mem - display a memory statistics summary *
@@ -160,4 +164,95 @@reserve_bootmem (bootmap_start, bootmap_size);find_initrd (); +} + +#ifdef CONFIG_VIRTUAL_MEM_MAP +static int +count_dma_pages (u64 start,u64 end,void *arg) +{ +unsigned long *count = arg; + +if (end <=MAX_DMA_ADDRESS ) + *count += (end - start) >>PAGE_SHIFT ; +return 0 ; +} +#endif + +/* +* Set up the page tables. +*/ + +void +paging_init (void ) +{ +unsigned long max_dma; +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[] */ + +memset (zones_size,0 ,sizeof (zones_size)); + + num_physpages =0 ; +efi_memmap_walk (count_pages, &num_physpages); + + max_dma =virt_to_phys ((void *)MAX_DMA_ADDRESS ) >>PAGE_SHIFT ; + +#ifdef CONFIG_VIRTUAL_MEM_MAP +memset (zholes_size,0 ,sizeof (zholes_size)); + + num_dma_physpages =0 ; +efi_memmap_walk (count_dma_pages, &num_dma_physpages); + +if (max_low_pfn < max_dma) { + zones_size[ZONE_DMA ] = max_low_pfn; + zholes_size[ZONE_DMA ] = max_low_pfn - num_dma_physpages; + }else { + zones_size[ZONE_DMA ] = max_dma; + zholes_size[ZONE_DMA ] = max_dma - num_dma_physpages; +if (num_physpages > num_dma_physpages) { + zones_size[ZONE_NORMAL ] = max_low_pfn - max_dma; + zholes_size[ZONE_NORMAL ] + ((max_low_pfn - max_dma) - + (num_physpages - num_dma_physpages)); + } + } + + max_gap =0 ; +efi_memmap_walk (find_largest_hole, (u64 *)&max_gap); +if (max_gap <LARGE_GAP ) { + vmem_map = (struct page *)0 ; +free_area_init_node (0 , &contig_page_data,NULL , zones_size,0 , + zholes_size); + mem_map = contig_page_data.node_mem_map; + } +else { +unsigned long map_size; + +/* allocate virtual_mem_map */ + + map_size =PAGE_ALIGN (max_low_pfn *sizeof (struct page )); + vmalloc_end -= map_size; + vmem_map = (struct page *) vmalloc_end; +efi_memmap_walk (create_mem_map_page_table,0 ); + +free_area_init_node (0 , &contig_page_data, vmem_map, zones_size, +0 , zholes_size); + + mem_map = contig_page_data.node_mem_map; +printk ("Virtual mem_map starts at 0x%p\n" , mem_map); + } +#else /* !CONFIG_VIRTUAL_MEM_MAP */ +if (max_low_pfn < max_dma) + zones_size[ZONE_DMA ] = max_low_pfn; +else { + zones_size[ZONE_DMA ] = max_dma; + zones_size[ZONE_NORMAL ] = max_low_pfn - max_dma; + } +free_area_init (zones_size); +#endif /* !CONFIG_VIRTUAL_MEM_MAP */ + zero_page_memmap_ptr =virt_to_page (ia64_imva (empty_zero_page)); }
arch/ia64/mm/discontig.c +4 -2
@@ -248,8 +248,7 @@* - replicate the nodedir structure to other nodes */ -void __init -discontig_paging_init (void ) +void __init paging_init (void ) {int node, mynode;unsigned long max_dma, zones_size[MAX_NR_ZONES ];
@@ -306,6 +305,9 @@memcpy (node_data[node], node_data[mynode],sizeof (struct ia64_node_data )); node_data[node]->node = node; } + +efi_memmap_walk (count_pages, &num_physpages); + zero_page_memmap_ptr =virt_to_page (ia64_imva (empty_zero_page)); }void show_mem (void )
arch/ia64/mm/init.c +4 -104
139 lines not on this page · raw message
include/asm-ia64/meminit.h +11 -0
@@ -7,6 +7,9 @@* for more details. */ +#include <linux/config.h> +#include <linux/mm.h> +/* * Entries defined so far: * - boot param structure itself
@@ -31,11 +34,19 @@extern void reserve_memory (void );extern void find_initrd (void );extern int filter_rsvd_memory (unsigned long start,unsigned long end,void *arg); +extern int count_pages (u64 start,u64 end,void *arg);#ifdef CONFIG_DISCONTIGMEM extern void call_pernode_memory (unsigned long start,unsigned long end,void *arg);#endif #define IGNORE_PFN0 1/* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */ + +#ifdef CONFIG_VIRTUAL_MEM_MAP +#define LARGE_GAP 0x40000000/* Use virtual mem map if hole is > than this */ +extern struct page *vmem_map; +extern int find_largest_hole (u64 start,u64 end,void *arg); +extern int create_mem_map_page_table (u64 start,u64 end,void *arg); +#endif #endif /* meminit_h */
arch/ia64/mm/contig.c line 30
Quoted 6 lines · Jesse Barnes
#include <
asm/pgtable.h>
#include <asm/sections.h>arch/ia64/mm/contig.c +3
-0+#ifdef CONFIG_VIRTUAL_MEM_MAP +static unsigned long num_dma_physpages; +#endif
Shouldn't this move down to the ifdef block where it's actually used?
Quoted 12 lines
arch/ia64/mm/contig.c +12
-0+if (max_gap <LARGE_GAP ) { + vmem_map = (struct page *)0 ; +free_area_init_node (0 , &contig_page_data,NULL , zones_size,0 , + zholes_size); + mem_map = contig_page_data.node_mem_map; + } +else { +unsigned long map_size; + +/* allocate virtual_mem_map */ + + map_size =PAGE_ALIGN (max_low_pfn *sizeof (struct page ));
arch/ia64/mm/contig.c line 246
Quoted 10 lines
arch/ia64/mm/contig.c +10
-0+ vmalloc_end -= map_size; + vmem_map = (struct page *) vmalloc_end; +efi_memmap_walk (create_mem_map_page_table,0 ); + +free_area_init_node (0 , &contig_page_data, vmem_map, zones_size, +0 , zholes_size); + + mem_map = contig_page_data.node_mem_map; +printk ("Virtual mem_map starts at 0x%p\n" , mem_map); + }
what about:
if (max_gap >= LARGE_GAP) {
vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page));
vmem_map = (struct page *)vmalloc_end;
efi_memmap_walk(create_mem_map_page_table, 0);
}
free_area_init_node(0, &contig_page_data, vmem_map, zones_size, 0,
zholes_size);
mem_map = contig_page_data.node_mem_map;(vmem_map is in .bss and thus implicitly NULL)
Quoted 9 lines · Christoph Hellwig
Review
Quoted 6 lines · Jesse Barnes
#include <
asm/pgtable.h>
#include <asm/sections.h>(quoted diff) +3
-0+#ifdef CONFIG_VIRTUAL_MEM_MAP +static unsigned long num_dma_physpages; +#endifShouldn't this move down to the ifdef block where it's actually used?
Yep, in fact, it's only used in paging_init() so I just put it on the stack there.
Quoted 35 lines
Quoted 12 lines
(quoted diff) +12
-0+ if (max_gap < LARGE_GAP) { + vmem_map = (struct page *) 0; + free_area_init_node(0, &contig_page_data, NULL, zones_size, 0, + zholes_size); + mem_map = contig_page_data.node_mem_map; + } + else { + unsigned long map_size; + + /* allocate virtual_mem_map */ + + map_size = PAGE_ALIGN(max_low_pfn * sizeof(struct page));Review
Quoted 10 lines
(quoted diff) +10
-0+ vmalloc_end -= map_size; + vmem_map = (struct page *) vmalloc_end; + efi_memmap_walk(create_mem_map_page_table, 0); + + free_area_init_node(0, &contig_page_data, vmem_map, zones_size, + 0, zholes_size); + + mem_map = contig_page_data.node_mem_map; + printk("Virtual mem_map starts at 0x%p\n", mem_map); + }what about:
if (max_gap >= LARGE_GAP) { vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page)); vmem_map = (struct page *)vmalloc_end; efi_memmap_walk(create_mem_map_page_table, 0); } free_area_init_node(0, &contig_page_data, vmem_map, zones_size, 0, zholes_size); mem_map = contig_page_data.node_mem_map;
Quoted 1 line
(
vmem_mapis in .bss and thus implicitly NULL)
Sure, I was trying to keep the code the same as it was in init.c, but this seems like a reasonable clarification. Here's a new one. Tested on a 6GB zx1. Booted normally and with 'mem 0M'.
arch/ia64/mm/contig.c | 80 +++++++++++++++++++++++++++++++++ arch/ia64/mm/discontig.c | 6 +- arch/ia64/mm/init.c | 108 +-------------------------------------------- include/asm-ia64/meminit.h | 11 ++++
Thanks,
Jesse
arch/ia64/mm/contig.c +79 -0
@@ -161,3 +161,83 @@find_initrd (); } + +#ifdef CONFIG_VIRTUAL_MEM_MAP +static int +count_dma_pages (u64 start,u64 end,void *arg) +{ +unsigned long *count = arg; + +if (end <=MAX_DMA_ADDRESS ) + *count += (end - start) >>PAGE_SHIFT ; +return 0 ; +} +#endif + +/* +* Set up the page tables. +*/ + +void +paging_init (void ) +{ +unsigned long max_dma; +unsigned long zones_size[MAX_NR_ZONES ]; +#ifdef CONFIG_VIRTUAL_MEM_MAP +unsigned long zholes_size[MAX_NR_ZONES ]; +unsigned long max_gap; +unsigned long num_dma_physpages; +#endif + +/* initialize mem_map[] */ + +memset (zones_size,0 ,sizeof (zones_size)); + + num_physpages =0 ; +efi_memmap_walk (count_pages, &num_physpages); + + max_dma =virt_to_phys ((void *)MAX_DMA_ADDRESS ) >>PAGE_SHIFT ; + +#ifdef CONFIG_VIRTUAL_MEM_MAP +memset (zholes_size,0 ,sizeof (zholes_size)); + + num_dma_physpages =0 ; +efi_memmap_walk (count_dma_pages, &num_dma_physpages); + +if (max_low_pfn < max_dma) { + zones_size[ZONE_DMA ] = max_low_pfn; + zholes_size[ZONE_DMA ] = max_low_pfn - num_dma_physpages; + }else { + zones_size[ZONE_DMA ] = max_dma; + zholes_size[ZONE_DMA ] = max_dma - num_dma_physpages; +if (num_physpages > num_dma_physpages) { + zones_size[ZONE_NORMAL ] = max_low_pfn - max_dma; + zholes_size[ZONE_NORMAL ] + ((max_low_pfn - max_dma) - + (num_physpages - num_dma_physpages)); + } + } + + max_gap =0 ; +efi_memmap_walk (find_largest_hole, (u64 *)&max_gap); +if (max_gap >=LARGE_GAP ) { + vmalloc_end -=PAGE_ALIGN (max_low_pfn *sizeof (struct page )); + vmem_map = (struct page *)vmalloc_end; +efi_memmap_walk (create_mem_map_page_table,0 ); +printk ("Virtual mem_map starts at 0x%p\n" , vmem_map); + } + +free_area_init_node (0 , &contig_page_data, vmem_map, zones_size,0 , + zholes_size); + mem_map = contig_page_data.node_mem_map; +#else /* !CONFIG_VIRTUAL_MEM_MAP */ +if (max_low_pfn < max_dma) + zones_size[ZONE_DMA ] = max_low_pfn; +else { + zones_size[ZONE_DMA ] = max_dma; + zones_size[ZONE_NORMAL ] = max_low_pfn - max_dma; + } +free_area_init (zones_size); +#endif /* !CONFIG_VIRTUAL_MEM_MAP */ + zero_page_memmap_ptr =virt_to_page (ia64_imva (empty_zero_page)); +}
arch/ia64/mm/discontig.c +4 -2
@@ -248,8 +248,7 @@* - replicate the nodedir structure to other nodes */ -void __init -discontig_paging_init (void ) +void __init paging_init (void ) {int node, mynode;unsigned long max_dma, zones_size[MAX_NR_ZONES ];
@@ -306,6 +305,9 @@memcpy (node_data[node], node_data[mynode],sizeof (struct ia64_node_data )); node_data[node]->node = node; } + +efi_memmap_walk (count_pages, &num_physpages); + zero_page_memmap_ptr =virt_to_page (ia64_imva (empty_zero_page)); }void show_mem (void )
arch/ia64/mm/init.c +4 -104
139 lines not on this page · raw message
include/asm-ia64/meminit.h +11 -0
@@ -7,6 +7,9 @@* for more details. */ +#include <linux/config.h> +#include <linux/mm.h> +/* * Entries defined so far: * - boot param structure itself
@@ -31,11 +34,19 @@extern void reserve_memory (void );extern void find_initrd (void );extern int filter_rsvd_memory (unsigned long start,unsigned long end,void *arg); +extern int count_pages (u64 start,u64 end,void *arg);#ifdef CONFIG_DISCONTIGMEM extern void call_pernode_memory (unsigned long start,unsigned long end,void *arg);#endif #define IGNORE_PFN0 1/* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */ + +#ifdef CONFIG_VIRTUAL_MEM_MAP +#define LARGE_GAP 0x40000000/* Use virtual mem map if hole is > than this */ +extern struct page *vmem_map; +extern int find_largest_hole (u64 start,u64 end,void *arg); +extern int create_mem_map_page_table (u64 start,u64 end,void *arg); +#endif #endif /* meminit_h */