Skip to contentSkip to conversation

split contig and discontig paging_init functions

PATCH In review Jesse Barnes 2 participants 3 messages Oct 6, 2003 – Oct 8, 2003

lore
Share & tools
lore
#0 lore raw

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
diff -Nru a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
@@ -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
diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
@@ -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
diff -Nru a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
@@ -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 */
#1 lore raw

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)

#2 lore raw
In reply to Jesse Barnes
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;
+#endif

Shouldn'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_map is 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
diff -Nru a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
@@ -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
diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
@@ -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
diff -Nru a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
@@ -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 */