Skip to contentSkip to conversation

x86/mm: Separate paging setup from memory mapping

PATCH Superseded Pekka Enberg 2 participants 3 messages Jul 14, 2012 – Jul 15, 2012

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 3/3 x86/mm: Separate paging setup from memory mapping

Move PSE and PGE bit twiddling from init_memory_mapping() to a new setup_paging() function to simplify the former function. The init_memory_mapping() function is called later in the boot process by gart_iommu_init(), efi_ioremap(), and arch_add_memory() which have no business whatsover updating the CR4 register.

---
 arch/x86/include/asm/page_types.h |    2 ++
 arch/x86/kernel/setup.c           |    2 ++
 arch/x86/mm/init.c                |   23 +++++++++++++----------
 3 files changed, 17 insertions(+), 10 deletions(-)
arch/x86/include/asm/page_types.h +2 -0
index e21fdd1..529905e 100644
@@ -51,6 +51,8 @@ static inline phys_addr_t get_max_mapped(void)
 	return (phys_addr_t)max_pfn_mapped << PAGE_SHIFT;
 }
 
+extern void setup_paging(void);
+
 extern unsigned long init_memory_mapping(unsigned long start,
 					 unsigned long end);
 
arch/x86/kernel/setup.c +2 -0
index 16be6dc..a883978 100644
@@ -913,6 +913,8 @@ void __init setup_arch(char **cmdline_p)
 
 	init_gbpages();
 
+	setup_paging();
+
 	/* max_pfn_mapped is updated here */
 	max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
 	max_pfn_mapped = max_low_pfn_mapped;
arch/x86/mm/init.c +13 -10
index e270f94..79b4b89 100644
@@ -127,6 +127,19 @@ static unsigned long addr_to_pud_pfn(unsigned long addr)
 	return (addr >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT);
 }
 
+void setup_paging(void)
+{
+	/* Enable PSE if available */
+	if (cpu_has_pse)
+		set_in_cr4(X86_CR4_PSE);
+
+	/* Enable PGE if available */
+	if (cpu_has_pge) {
+		set_in_cr4(X86_CR4_PGE);
+		__supported_pte_mask |= _PAGE_GLOBAL;
+	}
+}
+
 /*
  * Setup the direct mapping of the physical memory at PAGE_OFFSET.
  * This runs before bootmem is initialized and gets pages directly from
@@ -159,16 +172,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
 	use_gbpages = direct_gbpages;
 #endif
 
-	/* Enable PSE if available */
-	if (cpu_has_pse)
-		set_in_cr4(X86_CR4_PSE);
-
-	/* Enable PGE if available */
-	if (cpu_has_pge) {
-		set_in_cr4(X86_CR4_PGE);
-		__supported_pte_mask |= _PAGE_GLOBAL;
-	}
-
 	if (use_gbpages)
 		page_size_mask |= 1 << PG_LEVEL_1G;
 	if (use_pse)
Signature · 1 line
1.7.7.6
#1 lore raw
Quoted 5 lines · Pekka Enberg

Move PSE and PGE bit twiddling from init_memory_mapping() to a new setup_paging() function to simplify the former function. The init_memory_mapping() function is called later in the boot process by gart_iommu_init(), efi_ioremap(), and arch_add_memory() which have no business whatsover updating the CR4 register.

I have one local patch that will only set that one time too. also do other page size probe one time.

please check attached one.

Thanks

Yinghai

Subject: [PATCH 1/3] x86, mm: Introduce global page_size_mask

Add probe_page_size_mask() to detect if need to use 1G or 2M. and store them in page_size_mask.

Only probe them at first init_memory_mapping calling.
second and later init_memory_mapping() calling does not need probe again. also we don't need to pass use_gbpages around.

---
 arch/x86/include/asm/pgtable.h |    1 
 arch/x86/mm/init.c             |   70 +++++++++++++++++++++--------------------
 2 files changed, 37 insertions(+), 34 deletions(-)
arch/x86/include/asm/pgtable.h +1 -0
Index: linux-2.6/arch/x86/include/asm/pgtable.h
===================================================================
@@ -597,6 +597,7 @@ static inline int pgd_none(pgd_t pgd)
 #ifndef __ASSEMBLY__
 
 extern int direct_gbpages;
+extern int page_size_mask;
 
 /* local pte updates need not use xchg for locking */
 static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
arch/x86/mm/init.c +36 -34

115 lines not on this page · raw message

#2 lore raw
Quoted 5 lines · Pekka Enberg
Quoted 5 lines

Move PSE and PGE bit twiddling from init_memory_mapping() to a new setup_paging() function to simplify the former function. The init_memory_mapping() function is called later in the boot process by gart_iommu_init(), efi_ioremap(), and arch_add_memory() which have no business whatsover updating the CR4 register.

Quoted 4 lines · Yinghai Lu

I have one local patch that will only set that one time too. also do other page size probe one time.

please check attached one.

Your patch still keeps the same sort of code flow. That is, init_memory_mapping() does all sorts of things upon first call. I personally prefer the more explicit approach in this patch. In fact, you could do the page_size_mask setup in the setup_paging() function.

Pekka