All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, hpa@zytor.com, mingo@redhat.com,
	yinghai@kernel.org, akpm@linux-foundation.org,
	tglx@linutronix.de, mingo@elte.hu
Subject: [tip:x86/mm] x86: make 32-bit init_memory_mapping range change more like 64-bit
Date: Wed, 4 Mar 2009 20:00:39 GMT	[thread overview]
Message-ID: <tip-b68adb16f29c8ea02f21f5ebf65bcabffe217e9f@git.kernel.org> (raw)
In-Reply-To: <49AE48B4.8010907@kernel.org>

Commit-ID:  b68adb16f29c8ea02f21f5ebf65bcabffe217e9f
Gitweb:     http://git.kernel.org/tip/b68adb16f29c8ea02f21f5ebf65bcabffe217e9f
Author:     "Yinghai Lu" <yinghai@kernel.org>
AuthorDate: Wed, 4 Mar 2009 01:24:04 -0800
Commit:     Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 4 Mar 2009 20:55:03 +0100

x86: make 32-bit init_memory_mapping range change more like 64-bit

Impact: cleanup

make code more readable and more like 64-bit

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
LKML-Reference: <49AE48B4.8010907@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 arch/x86/mm/init_32.c |  126 ++++++++++++++++++++++++++++++++++++------------
 1 files changed, 94 insertions(+), 32 deletions(-)

diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 67bdb59..37aeaf3 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -885,29 +885,55 @@ static void __init find_early_table_space(unsigned long end, int use_pse)
 		(table_start << PAGE_SHIFT) + tables);
 }
 
+struct map_range {
+	unsigned long start;
+	unsigned long end;
+	unsigned page_size_mask;
+};
+
+#define NR_RANGE_MR 3
+
+static int save_mr(struct map_range *mr, int nr_range,
+		   unsigned long start_pfn, unsigned long end_pfn,
+		   unsigned long page_size_mask)
+{
+	if (start_pfn < end_pfn) {
+		if (nr_range >= NR_RANGE_MR)
+			panic("run out of range for init_memory_mapping\n");
+		mr[nr_range].start = start_pfn<<PAGE_SHIFT;
+		mr[nr_range].end   = end_pfn<<PAGE_SHIFT;
+		mr[nr_range].page_size_mask = page_size_mask;
+		nr_range++;
+	}
+
+	return nr_range;
+}
+
 unsigned long __init_refok init_memory_mapping(unsigned long start,
 						unsigned long end)
 {
 	pgd_t *pgd_base = swapper_pg_dir;
+	unsigned long page_size_mask = 0;
 	unsigned long start_pfn, end_pfn;
-	unsigned long big_page_start;
+	unsigned long pos;
+
+	struct map_range mr[NR_RANGE_MR];
+	int nr_range, i;
+	int use_pse;
+
+	printk(KERN_INFO "init_memory_mapping: %08lx-%08lx\n", start, end);
+
 #ifdef CONFIG_DEBUG_PAGEALLOC
 	/*
 	 * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages.
 	 * This will simplify cpa(), which otherwise needs to support splitting
 	 * large pages into small in interrupt context, etc.
 	 */
-	int use_pse = 0;
+	use_pse = 0;
 #else
-	int use_pse = cpu_has_pse;
+	use_pse = cpu_has_pse;
 #endif
 
-	/*
-	 * Find space for the kernel direct mapping tables.
-	 */
-	if (!after_init_bootmem)
-		find_early_table_space(end, use_pse);
-
 #ifdef CONFIG_X86_PAE
 	set_nx();
 	if (nx_enabled)
@@ -924,45 +950,81 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
 		__supported_pte_mask |= _PAGE_GLOBAL;
 	}
 
+	memset(mr, 0, sizeof(mr));
+	nr_range = 0;
+
+	if (use_pse)
+		page_size_mask |= 1 << PG_LEVEL_2M;
+
 	/*
 	 * Don't use a large page for the first 2/4MB of memory
 	 * because there are often fixed size MTRRs in there
 	 * and overlapping MTRRs into large pages can cause
 	 * slowdowns.
 	 */
-	big_page_start = PMD_SIZE;
-
-	if (start < big_page_start) {
-		start_pfn = start >> PAGE_SHIFT;
-		end_pfn = min(big_page_start>>PAGE_SHIFT, end>>PAGE_SHIFT);
-	} else {
-		/* head is not big page alignment ? */
-		start_pfn = start >> PAGE_SHIFT;
-		end_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT)
+	/* head could not be big page alignment ? */
+	start_pfn = start >> PAGE_SHIFT;
+	pos = start_pfn << PAGE_SHIFT;
+	if (pos == 0)
+		end_pfn = 1<<(PMD_SHIFT - PAGE_SHIFT);
+	else
+		end_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
 				 << (PMD_SHIFT - PAGE_SHIFT);
+	if (end_pfn > (end>>PAGE_SHIFT))
+		end_pfn = end>>PAGE_SHIFT;
+	if (start_pfn < end_pfn) {
+		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
+		pos = end_pfn << PAGE_SHIFT;
 	}
-	if (start_pfn < end_pfn)
-		kernel_physical_mapping_init(pgd_base, start_pfn, end_pfn, 0);
 
 	/* big page range */
-	start_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT)
+	start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
 			 << (PMD_SHIFT - PAGE_SHIFT);
-	if (start_pfn < (big_page_start >> PAGE_SHIFT))
-		start_pfn =  big_page_start >> PAGE_SHIFT;
 	end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT);
-	if (start_pfn < end_pfn)
-		kernel_physical_mapping_init(pgd_base, start_pfn, end_pfn,
-					     use_pse);
+	if (start_pfn < end_pfn) {
+		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
+				page_size_mask & (1<<PG_LEVEL_2M));
+		pos = end_pfn << PAGE_SHIFT;
+	}
 
 	/* tail is not big page alignment ? */
-	start_pfn = end_pfn;
-	if (start_pfn > (big_page_start>>PAGE_SHIFT)) {
-		end_pfn = end >> PAGE_SHIFT;
-		if (start_pfn < end_pfn)
-			kernel_physical_mapping_init(pgd_base, start_pfn,
-							 end_pfn, 0);
+	start_pfn = pos>>PAGE_SHIFT;
+	end_pfn = end>>PAGE_SHIFT;
+	if (start_pfn < end_pfn)
+		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
+
+	/* try to merge same page size and continuous */
+	for (i = 0; nr_range > 1 && i < nr_range - 1; i++) {
+		unsigned long old_start;
+		if (mr[i].end != mr[i+1].start ||
+		    mr[i].page_size_mask != mr[i+1].page_size_mask)
+			continue;
+		/* move it */
+		old_start = mr[i].start;
+		memmove(&mr[i], &mr[i+1],
+			(nr_range - 1 - i) * sizeof(struct map_range));
+		mr[i--].start = old_start;
+		nr_range--;
 	}
 
+	for (i = 0; i < nr_range; i++)
+		printk(KERN_DEBUG " %08lx - %08lx page %s\n",
+			mr[i].start, mr[i].end,
+			(mr[i].page_size_mask & (1<<PG_LEVEL_2M)) ?
+				  "big page" : "4k");
+
+	/*
+	 * Find space for the kernel direct mapping tables.
+	 */
+	if (!after_init_bootmem)
+		find_early_table_space(end, use_pse);
+
+	for (i = 0; i < nr_range; i++)
+		kernel_physical_mapping_init(pgd_base,
+				mr[i].start >> PAGE_SHIFT,
+				mr[i].end >> PAGE_SHIFT,
+				mr[i].page_size_mask == (1<<PG_LEVEL_2M));
+
 	early_ioremap_page_table_range_init(pgd_base);
 
 	load_cr3(swapper_pg_dir);

  parent reply	other threads:[~2009-03-04 20:02 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-04  9:22 [PATCH] x86: fix bootmem cross node for 32bit numa Yinghai Lu
2009-03-04  9:24 ` [PATCH] x86: make 32bit init_memory_mapping range change more like 64bit Yinghai Lu
2009-03-04  9:51   ` Pekka Enberg
2009-03-04 20:00   ` Yinghai Lu [this message]
2009-03-04  9:25 ` [PATCH] x86: ioremap mptable Yinghai Lu
2009-03-04  9:25   ` [PATCH] x86: reserve exact size of mptable Yinghai Lu
2009-03-04 19:51     ` Ingo Molnar
2009-03-04 20:01     ` [tip:x86/mm] " Yinghai Lu
2009-03-04 19:50   ` [PATCH] x86: ioremap mptable Ingo Molnar
2009-03-04 20:29     ` Yinghai Lu
2009-03-04 21:06       ` Ingo Molnar
2009-03-04 20:00   ` [tip:x86/mm] " Yinghai Lu
2009-03-04 18:08 ` [PATCH] x86: fix bootmem cross node for 32bit numa -v2 Yinghai Lu
2009-03-04 19:58   ` Ingo Molnar
2009-03-04 20:21     ` Yinghai Lu
2009-03-04 21:12       ` [tip:x86/mm] x86: fix bootmem cross node for 32bit numa, cleanup Yinghai Lu
2009-03-04 20:00 ` [tip:x86/mm] x86: fix bootmem cross node for 32bit numa Yinghai Lu
2009-03-08 23:16   ` Yinghai Lu
2009-03-09  6:58     ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-b68adb16f29c8ea02f21f5ebf65bcabffe217e9f@git.kernel.org \
    --to=yinghai@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.