Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6391af17 authored by Mel Gorman's avatar Mel Gorman Committed by Linus Torvalds
Browse files

[PATCH] mm: use symbolic names instead of indices for zone initialisation



Arch-independent zone-sizing is using indices instead of symbolic names to
offset within an array related to zones (max_zone_pfns).  The unintended
impact is that ZONE_DMA and ZONE_NORMAL is initialised on powerpc instead
of ZONE_DMA and ZONE_HIGHMEM when CONFIG_HIGHMEM is set.  As a result, the
the machine fails to boot but will boot with CONFIG_HIGHMEM turned off.

The following patch properly initialises the max_zone_pfns[] array and uses
symbolic names instead of indices in each architecture using
arch-independent zone-sizing.  Two users have successfully booted their
powerpcs with it (one an ibook G4).  It has also been boot tested on x86,
x86_64, ppc64 and ia64.  Please merge for 2.6.19-rc2.

Credit to Benjamin Herrenschmidt for identifying the bug and rolling the
first fix.  Additional credit to Johannes Berg and Andreas Schwab for
reporting the problem and testing on powerpc.

Signed-off-by: default avatarMel Gorman <mel@csn.ul.ie>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4e0fadfc
Loading
Loading
Loading
Loading
+6 −7
Original line number Original line Diff line number Diff line
@@ -1083,16 +1083,15 @@ static unsigned long __init setup_memory(void)


void __init zone_sizes_init(void)
void __init zone_sizes_init(void)
{
{
	unsigned long max_zone_pfns[MAX_NR_ZONES];
	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
	max_zone_pfns[ZONE_DMA] =
		virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
#ifdef CONFIG_HIGHMEM
#ifdef CONFIG_HIGHMEM
	unsigned long max_zone_pfns[MAX_NR_ZONES] = {
	max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
			virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
			max_low_pfn,
			highend_pfn};
	add_active_range(0, 0, highend_pfn);
	add_active_range(0, 0, highend_pfn);
#else
#else
	unsigned long max_zone_pfns[MAX_NR_ZONES] = {
			virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
			max_low_pfn};
	add_active_range(0, 0, max_low_pfn);
	add_active_range(0, 0, max_low_pfn);
#endif
#endif


+6 −5
Original line number Original line Diff line number Diff line
@@ -356,11 +356,12 @@ void __init numa_kva_reserve(void)
void __init zone_sizes_init(void)
void __init zone_sizes_init(void)
{
{
	int nid;
	int nid;
	unsigned long max_zone_pfns[MAX_NR_ZONES] = {
	unsigned long max_zone_pfns[MAX_NR_ZONES];
		virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
		max_low_pfn,
	max_zone_pfns[ZONE_DMA] =
		highend_pfn
		virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
	};
	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
	max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;


	/* If SRAT has not registered memory, register it now */
	/* If SRAT has not registered memory, register it now */
	if (find_max_pfn_with_active_regions() == 0) {
	if (find_max_pfn_with_active_regions() == 0) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -233,6 +233,7 @@ paging_init (void)
	efi_memmap_walk(count_pages, &num_physpages);
	efi_memmap_walk(count_pages, &num_physpages);


	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
	max_zone_pfns[ZONE_DMA] = max_dma;
	max_zone_pfns[ZONE_DMA] = max_dma;
	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;


+1 −0
Original line number Original line Diff line number Diff line
@@ -709,6 +709,7 @@ void __init paging_init(void)
			max_pfn = mem_data[node].max_pfn;
			max_pfn = mem_data[node].max_pfn;
	}
	}


	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
	max_zone_pfns[ZONE_DMA] = max_dma;
	max_zone_pfns[ZONE_DMA] = max_dma;
	max_zone_pfns[ZONE_NORMAL] = max_pfn;
	max_zone_pfns[ZONE_NORMAL] = max_pfn;
	free_area_init_nodes(max_zone_pfns);
	free_area_init_nodes(max_zone_pfns);
+4 −3
Original line number Original line Diff line number Diff line
@@ -307,11 +307,12 @@ void __init paging_init(void)
	       top_of_ram, total_ram);
	       top_of_ram, total_ram);
	printk(KERN_DEBUG "Memory hole size: %ldMB\n",
	printk(KERN_DEBUG "Memory hole size: %ldMB\n",
	       (top_of_ram - total_ram) >> 20);
	       (top_of_ram - total_ram) >> 20);
	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
#ifdef CONFIG_HIGHMEM
#ifdef CONFIG_HIGHMEM
	max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT;
	max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
	max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT;
	max_zone_pfns[ZONE_HIGHMEM] = top_of_ram >> PAGE_SHIFT;
#else
#else
	max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT;
	max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
#endif
#endif
	free_area_init_nodes(max_zone_pfns);
	free_area_init_nodes(max_zone_pfns);
}
}
Loading