Christophe Leroy <christophe.le...@c-s.fr> writes: > Today there are two implementations of hugetlbpages which are managed > by exclusive #ifdefs: > * FSL_BOOKE: several directory entries points to the same single hugepage > * BOOK3S: one upper level directory entry points to a table of hugepages > > In preparation of implementation of hugepage support on the 8xx, we > need a mix of the two above solutions, because the 8xx needs both cases > depending on the size of pages: > * In 4k page size mode, each PGD entry covers a 4M bytes area. It means > that 2 PGD entries will be necessary to cover an 8M hugepage while a > single PGD entry will cover 8x 512k hugepages. > * In 16 page size mode, each PGD entry covers a 64M bytes area. It means > that 8x 8M hugepages will be covered by one PGD entry and 64x 512k > hugepages will be covers by one PGD entry. > > This patch: > * removes #ifdefs in favor of if/else based on the range sizes > * merges the two huge_pte_alloc() functions as they are pretty similar > * merges the two hugetlbpage_init() functions as they are pretty similar > > Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr> > --- > v2: This part is new and results from a split of last patch of v1 serie in > two parts > > arch/powerpc/mm/hugetlbpage.c | 189 > +++++++++++++++++------------------------- > 1 file changed, 77 insertions(+), 112 deletions(-) > > diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c > index 8a512b1..2119f00 100644 > --- a/arch/powerpc/mm/hugetlbpage.c > +++ b/arch/powerpc/mm/hugetlbpage.c > @@ -64,14 +64,16 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t > *hpdp, > { > struct kmem_cache *cachep; > pte_t *new; > - > -#ifdef CONFIG_PPC_FSL_BOOK3E > int i; > - int num_hugepd = 1 << (pshift - pdshift); > - cachep = hugepte_cache; > -#else > - cachep = PGT_CACHE(pdshift - pshift); > -#endif > + int num_hugepd; > + > + if (pshift >= pdshift) { > + cachep = hugepte_cache; > + num_hugepd = 1 << (pshift - pdshift); > + } else { > + cachep = PGT_CACHE(pdshift - pshift); > + num_hugepd = 1; > + }
Is there a way to hint likely/unlikely branch based on the page size selected at build time ? > > new = kmem_cache_zalloc(cachep, GFP_KERNEL); > > @@ -89,7 +91,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t > *hpdp, > smp_wmb(); > > spin_lock(&mm->page_table_lock); > -#ifdef CONFIG_PPC_FSL_BOOK3E > + > /* > * We have multiple higher-level entries that point to the same > * actual pte location. Fill in each as we go and backtrack on error. > @@ -100,8 +102,13 @@ static int __hugepte_alloc(struct mm_struct *mm, > hugepd_t *hpdp, > if (unlikely(!hugepd_none(*hpdp))) > break; > else .... > -#ifdef CONFIG_PPC_FSL_BOOK3E > struct kmem_cache *hugepte_cache; > static int __init hugetlbpage_init(void) > { > int psize; > > - for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { > - unsigned shift; > - > - if (!mmu_psize_defs[psize].shift) > - continue; > - > - shift = mmu_psize_to_shift(psize); > - > - /* Don't treat normal page sizes as huge... */ > - if (shift != PAGE_SHIFT) > - if (add_huge_page_size(1ULL << shift) < 0) > - continue; > - } > - > - /* > - * Create a kmem cache for hugeptes. The bottom bits in the pte have > - * size information encoded in them, so align them to allow this > - */ > - hugepte_cache = kmem_cache_create("hugepte-cache", sizeof(pte_t), > - HUGEPD_SHIFT_MASK + 1, 0, NULL); > - if (hugepte_cache == NULL) > - panic("%s: Unable to create kmem cache for hugeptes\n", > - __func__); > - > - /* Default hpage size = 4M */ > - if (mmu_psize_defs[MMU_PAGE_4M].shift) > - HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_4M].shift; > - else > - panic("%s: Unable to set default huge page size\n", __func__); > - > - > - return 0; > -} > -#else > -static int __init hugetlbpage_init(void) > -{ > - int psize; > - > +#if !defined(CONFIG_PPC_FSL_BOOK3E) > if (!radix_enabled() && !mmu_has_feature(MMU_FTR_16M_PAGE)) > return -ENODEV; > - > +#endif Do we need that #if ? radix_enabled() should become 0 and that if condition should be removed at compile time isn't it ? or are you finding errors with that ? > for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { > unsigned shift; > unsigned pdshift; > @@ -860,16 +807,31 @@ static int __init hugetlbpage_init(void) > * if we have pdshift and shift value same, we don't > * use pgt cache for hugepd. > */ > - if (pdshift != shift) { > + if (pdshift > shift) { > pgtable_cache_add(pdshift - shift, NULL); > if (!PGT_CACHE(pdshift - shift)) > panic("hugetlbpage_init(): could not create " > "pgtable cache for %d bit pagesize\n", > shift); > + } else if (!hugepte_cache) { > + /* > + * Create a kmem cache for hugeptes. The bottom bits in > + * the pte have size information encoded in them, so > + * align them to allow this > + */ > + hugepte_cache = kmem_cache_create("hugepte-cache", > + sizeof(pte_t), > + HUGEPD_SHIFT_MASK + 1, > + 0, NULL); > + if (hugepte_cache == NULL) > + panic("%s: Unable to create kmem cache " > + "for hugeptes\n", __func__); > + We don't need hugepte_cache for book3s 64K. I guess we will endup creating one here ? > } > } > > /* Set default large page size. Currently, we pick 16M or 1M > * depending on what is available > + * We select 4M on other ones. > */ > if (mmu_psize_defs[MMU_PAGE_16M].shift) > HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_16M].shift; > @@ -877,11 +839,14 @@ static int __init hugetlbpage_init(void) > HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_1M].shift; > else if (mmu_psize_defs[MMU_PAGE_2M].shift) > HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_2M].shift; > - > + else if (mmu_psize_defs[MMU_PAGE_4M].shift) > + HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_4M].shift; > + else > + panic("%s: Unable to set default huge page size\n", __func__); > > return 0; > } > -#endif > + > arch_initcall(hugetlbpage_init); > > void flush_dcache_icache_hugepage(struct page *page) > -- > 2.1.0