Skip to contentSkip to conversation

powerpc: add hugepagesz boot-time parameter

PATCH Superseded Jon Tollefson 2 participants 2 messages Dec 19, 2007 – Dec 20, 2007

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 powerpc: add hugepagesz boot-time parameter

Paul, please include this in 2.6.25 if there are no objections.

This patch adds the hugepagesz boot-time parameter for ppc64. It lets one pick the size for huge pages. The choices available are 64K and 16M when the base page size is 4k. It defaults to 16M (previously the only only choice) if nothing or an invalid choice is specified.

Tested 64K huge pages successfully with the libhugetlbfs 1.2.

Changes from v1:
disallow 64K huge pages when base page size is 64K since we can't
distinguish between
base and huge pages when doing a hash_page()
collapsed pmd_offset and pmd_alloc to inline calls to simplify the
main code
removed printing of the huge page size in mm/hugetlb.c since this
information is already
available in /proc/meminfo and leaves the remaining changes all
powerpc specific

---

Documentation/kernel-parameters.txt +1 -0
index 33121d6..2fc1fb8 100644
@@ -685,6 +685,7 @@ and is between 256 and 4096 characters. It is defined in the file
 			See Documentation/isdn/README.HiSax.
 
 	hugepages=	[HW,X86-32,IA-64] Maximal number of HugeTLB pages.
+	hugepagesz=	[HW,IA-64,PPC] The size of the HugeTLB pages.
 
 	i8042.direct	[HW] Put keyboard port into non-translated mode
 	i8042.dumbkbd	[HW] Pretend that controller can only read data from
arch/powerpc/mm/hash_utils_64.c +2 -9
index cbbd8b0..9326a69 100644
@@ -369,18 +369,11 @@ static void __init htab_init_page_sizes(void)
 	 * on what is available
 	 */
 	if (mmu_psize_defs[MMU_PAGE_16M].shift)
-		mmu_huge_psize = MMU_PAGE_16M;
+		set_huge_psize(MMU_PAGE_16M);
 	/* With 4k/4level pagetables, we can't (for now) cope with a
 	 * huge page size < PMD_SIZE */
 	else if (mmu_psize_defs[MMU_PAGE_1M].shift)
-		mmu_huge_psize = MMU_PAGE_1M;
-
-	/* Calculate HPAGE_SHIFT and sanity check it */
-	if (mmu_psize_defs[mmu_huge_psize].shift > MIN_HUGEPTE_SHIFT &&
-	    mmu_psize_defs[mmu_huge_psize].shift < SID_SHIFT)
-		HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift;
-	else
-		HPAGE_SHIFT = 0; /* No huge pages dude ! */
+		set_huge_psize(MMU_PAGE_1M);
 #endif /* CONFIG_HUGETLB_PAGE */
 }
 
arch/powerpc/mm/hugetlbpage.c +90 -25

182 lines not on this page · raw message

include/asm-powerpc/mmu-hash64.h +1 -0
index 12e5e77..2fda33c 100644
@@ -278,6 +278,7 @@ extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
 extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
 			     unsigned long pstart, unsigned long mode,
 			     int psize, int ssize);
+extern void set_huge_psize(int psize);
 
 extern void htab_initialize(void);
 extern void htab_initialize_secondary(void);
include/asm-powerpc/pgtable.h +6 -0
index d18ffe7..66ff7e5 100644
@@ -37,6 +37,12 @@ extern void paging_init(void);
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
+/* Base page size affects how we walk hugetlb page tables */
+#ifdef CONFIG_PPC_64K_PAGES
+#define hpmd_offset(pud, addr)		pmd_offset(pud, addr)
+#define hpmd_alloc(mm, pud, addr)	pmd_alloc(mm, pud, addr)
+#endif
+
 #include <asm-generic/pgtable.h>
 #endif /* __ASSEMBLY__ */
 
#1 lore raw
Quoted 19 lines · Jon Tollefson

Paul, please include this in 2.6.25 if there are no objections.

This patch adds the hugepagesz boot-time parameter for ppc64. It lets one pick the size for huge pages. The choices available are 64K and 16M when the base page size is 4k. It defaults to 16M (previously the only only choice) if nothing or an invalid choice is specified.

Tested 64K huge pages successfully with the libhugetlbfs 1.2.

Changes from v1:
disallow 64K huge pages when base page size is 64K since we can't
distinguish between
base and huge pages when doing a hash_page()
collapsed pmd_offset and pmd_alloc to inline calls to simplify the
main code
removed printing of the huge page size in mm/hugetlb.c since this
information is already
available in /proc/meminfo and leaves the remaining changes all
powerpc specific

[snip]

Quoted 13 lines
arch/powerpc/mm/hugetlbpage.c +9 -0
@@ -82,11 +81,31 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
 	return 0;
 }
 
+#ifndef CONFIG_PPC_64K_PAGES
+static inline
+pmd_t *hpmd_offset(pud_t *pud, unsigned long addr)
+{
+	if (HPAGE_SHIFT == HPAGE_SHIFT_64K)
+		return pmd_offset(pud, addr);
+	else
+		return (pmd_t *) pud;
+}

arch/powerpc/mm/hugetlbpage.c static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, · line 102

Quoted 10 lines
arch/powerpc/mm/hugetlbpage.c +10 -0
+static inline
+pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr)
+{
+	if (HPAGE_SHIFT == HPAGE_SHIFT_64K)
+		return pmd_alloc(mm, pud, addr);
+	else
+		return (pmd_t *) pud;
+}
+#endif
+

I'm baffled by this section of code; I can't see how it can work properly with 64k base page size. hpmd_offset() and hpmd_alloc() are only defined if the base page size is 4k, but they appear to be used unconditionally in huge_pte_offset() and huge_pte_alloc() (since you remove the #ifdef that was there).

Quoted 49 lines
arch/powerpc/mm/hugetlbpage.c +4 -12
 /* Modelled after find_linux_pte() */
 pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pg;
 	pud_t *pu;
+	pmd_t *pm;
 
 	BUG_ON(get_slice_psize(mm, addr) != mmu_huge_psize);
 
@@ -96,14 +115,9 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 	if (!pgd_none(*pg)) {
 		pu = pud_offset(pg, addr);
 		if (!pud_none(*pu)) {
-#ifdef CONFIG_PPC_64K_PAGES
-			pmd_t *pm;
-			pm = pmd_offset(pu, addr);
+			pm = hpmd_offset(pu, addr);
 			if (!pmd_none(*pm))
 				return hugepte_offset((hugepd_t *)pm, addr);
-#else
-			return hugepte_offset((hugepd_t *)pu, addr);
-#endif
 		}
 	}
 
@@ -114,6 +128,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pg;
 	pud_t *pu;
+	pmd_t *pm;
 	hugepd_t *hpdp = NULL;
 
 	BUG_ON(get_slice_psize(mm, addr) != mmu_huge_psize);
@@ -124,14 +139,9 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 	pu = pud_alloc(mm, pg, addr);
 
 	if (pu) {
-#ifdef CONFIG_PPC_64K_PAGES
-		pmd_t *pm;
-		pm = pmd_alloc(mm, pu, addr);
+		pm = hpmd_alloc(mm, pu, addr);
 		if (pm)
 			hpdp = (hugepd_t *)pm;
-#else
-		hpdp = (hugepd_t *)pu;
-#endif
 	}
 
 	if (! hpdp)

[snip]

include/asm-powerpc/pgtable.h extern void paging_init(void); · line 44

Quoted 13 lines
include/asm-powerpc/pgtable.h +5 -0
index d18ffe7..66ff7e5 100644
@@ -37,6 +37,12 @@ extern void paging_init(void);
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
+/* Base page size affects how we walk hugetlb page tables */
+#ifdef CONFIG_PPC_64K_PAGES
+#define hpmd_offset(pud, addr)		pmd_offset(pud, addr)
+#define hpmd_alloc(mm, pud, addr)	pmd_alloc(mm, pud, addr)
+#endif

These functions are only used in hugetlbpage.c, I don't see any reason they should go in the header file.

Signature · 4 lines
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson