powerpc/mm: Add missing pmd accessors
Subsystems (5)
PATCH v5 1/3 powerpc/mm: Add missing pmd accessors
This patch add documentation and missing accessors.
--- arch/powerpc/include/asm/pgtable-ppc64-4k.h | 16 ++++++++- arch/powerpc/include/asm/pgtable-ppc64-64k.h | 3 ++ arch/powerpc/include/asm/pgtable-ppc64.h | 51 +++++++++++++++++++++------- arch/powerpc/mm/hugetlbpage.c | 3 ++ arch/powerpc/mm/pgtable_64.c | 22 ++++++++++-- 5 files changed, 78 insertions(+), 17 deletions(-)
arch/powerpc/include/asm/pgtable-ppc64-4k.h +15 -1
@@ -57,7 +57,21 @@#define pgd_present (pgd) (pgd_val(pgd) != 0)#define pgd_clear (pgdp) (pgd_val(*(pgdp)) = 0)#define pgd_page_vaddr (pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) -#define pgd_page (pgd) virt_to_page(pgd_page_vaddr(pgd)) + +#ifndef __ASSEMBLY__ + +static inline pte_t pgd_pte (pgd_t pgd) +{ +return __pte (pgd_val (pgd)); +} + +static inline pgd_t pte_pgd (pte_t pte) +{ +return __pgd (pte_val (pte)); +} +extern struct page *pgd_page (pgd_t pgd); + +#endif /* !__ASSEMBLY__ */ #define pud_offset (pgdp, addr) \ (((pud_t *) pgd_page_vaddr(*(pgdp))) + \
arch/powerpc/include/asm/pgtable-ppc64-64k.h +3 -0
@@ -38,4 +38,7 @@/* Bits to mask out from a PGD/PUD to get to the PMD page */ #define PUD_MASKED_BITS 0x1ff +#define pgd_pte (pgd) (pud_pte(((pud_t){ pgd }))) +#define pte_pgd (pte) ((pgd_t)pte_pud(pte)) +#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */
arch/powerpc/include/asm/pgtable-ppc64.h +38 -13
83 lines not on this page · raw message
arch/powerpc/mm/hugetlbpage.c +3 -0
@@ -62,6 +62,9 @@ static unsigned nr_gpages;/* * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD; +* +* Defined in such a way that we can optimize away code block at build time +* if CONFIG_HUGETLB_PAGE=n. */ int pmd_huge (pmd_t pmd) {
arch/powerpc/mm/pgtable_64.c +19 -3
@@ -36,6 +36,7 @@#include <linux/bootmem.h> #include <linux/memblock.h> #include <linux/slab.h> +#include <linux/hugetlb.h> #include <asm/pgalloc.h> #include <asm/page.h>
@@ -352,16 +353,31 @@ EXPORT_SYMBOL(iounmap);EXPORT_SYMBOL (__iounmap);EXPORT_SYMBOL (__iounmap_at); +#ifndef __PAGETABLE_PUD_FOLDED +/* 4 level page table */ +struct page *pgd_page (pgd_t pgd) +{ +if (pgd_huge (pgd)) +return pte_page (pgd_pte (pgd)); +return virt_to_page (pgd_page_vaddr (pgd)); +} +#endif + +struct page *pud_page (pud_t pud) +{ +if (pud_huge (pud)) +return pte_page (pud_pte (pud)); +return virt_to_page (pud_page_vaddr (pud)); +} +/* * For hugepage we have pfn in the pmd, we use PTE_RPN_SHIFT bits for flags * For PTE page, we have a PTE_FRAG_SIZE (4K) aligned virtual address. */ struct page *pmd_page (pmd_t pmd) { -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -if (pmd_trans_huge (pmd)) +if (pmd_trans_huge (pmd) ||pmd_huge (pmd))return pfn_to_page (pmd_pfn (pmd)); -#endif return virt_to_page (pmd_page_vaddr (pmd)); }
Signature · 1 line
2.1.0
PATCH v5 2/3 mm: Update generic gup implementation to handle hugepage directory
Update generic gup implementation with powerpc specific details. On powerpc at pmd level we can have hugepte, normal pmd pointer or a pointer to the hugepage directory.
---
Changes from V4:
* Add pmd accessor needed for the change to ppc64
* Drop the assumption that we can access pmd using pte_* functions.
arch/powerpc/include/asm/page.h | 1 + include/linux/hugetlb.h | 46 +++++++++++++++++++++++ mm/gup.c | 81 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 120 insertions(+), 8 deletions(-)
arch/powerpc/include/asm/page.h +1 -0
@@ -380,6 +380,7 @@ static inline int hugepd_ok(hugepd_t hpd)#endif #define is_hugepd (pdep) (hugepd_ok(*((hugepd_t *)(pdep)))) +#define pgd_huge pgd_hugeint pgd_huge (pgd_t pgd);#else /* CONFIG_HUGETLB_PAGE */ #define is_hugepd (pdep) 0
include/linux/hugetlb.h +46 -0
52 lines not on this page · raw message
mm/gup.c +73 -8
130 lines not on this page · raw message
Signature · 7 lines
2.1.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v5 3/3 powerpc/mm: Switch to generic RCU get_user_pages_fast
In reply to Aneesh Kumar K.VThis patch switch the ppc arch to use the generic RCU based gup implementation.
--- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/hugetlb.h | 8 +- arch/powerpc/include/asm/page.h | 3 +- arch/powerpc/include/asm/pgtable-ppc64.h | 1 - arch/powerpc/include/asm/pgtable.h | 6 +- arch/powerpc/mm/Makefile | 2 +- arch/powerpc/mm/gup.c | 235 ------------------------------- arch/powerpc/mm/hugetlbpage.c | 33 ++--- 8 files changed, 22 insertions(+), 267 deletions(-) delete mode 100644 arch/powerpc/mm/gup.c
arch/powerpc/Kconfig +1 -0
@@ -148,6 +148,7 @@ config PPC select HAVE_ARCH_AUDITSYSCALL select ARCH_SUPPORTS_ATOMIC_RMW select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN + select HAVE_GENERIC_RCU_GUP config GENERIC_CSUM def_bool CPU_LITTLE_ENDIAN
arch/powerpc/include/asm/hugetlb.h +4 -4
@@ -48,7 +48,7 @@ static inline unsigned int hugepd_shift(hugepd_t hpd)#endif /* CONFIG_PPC_BOOK3S_64 */ -static inline pte_t *hugepte_offset (hugepd_t *hpdp,unsigned long addr, +static inline pte_t *hugepte_offset (hugepd_t hpd,unsigned long addr,unsigned pdshift) {/*
@@ -58,9 +58,9 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,*/ unsigned long idx =0 ; -pte_t *dir =hugepd_page (*hpdp); +pte_t *dir =hugepd_page (hpd);#ifndef CONFIG_PPC_FSL_BOOK3E - idx = (addr & ((1UL << pdshift) -1 )) >>hugepd_shift (*hpdp); + idx = (addr & ((1UL << pdshift) -1 )) >>hugepd_shift (hpd);#endif return dir + idx;
@@ -193,7 +193,7 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma, }#define hugepd_shift (x) 0 -static inline pte_t *hugepte_offset (hugepd_t *hpdp,unsigned long addr, +static inline pte_t *hugepte_offset (hugepd_t hpd,unsigned long addr,unsigned pdshift) {return 0 ;
arch/powerpc/include/asm/page.h +2 -1
@@ -379,13 +379,14 @@ static inline int hugepd_ok(hugepd_t hpd) }#endif -#define is_hugepd (pdep) (hugepd_ok(*((hugepd_t *)(pdep)))) +#define is_hugepd (hpd) (hugepd_ok(hpd))#define pgd_huge pgd_hugeint pgd_huge (pgd_t pgd);#else /* CONFIG_HUGETLB_PAGE */ #define is_hugepd (pdep) 0#define pgd_huge (pgd) 0#endif /* CONFIG_HUGETLB_PAGE */ +#define __hugepd (x) ((hugepd_t) { (x) })struct page ;extern void clear_user_page (void *page,unsigned long vaddr,struct page *pg);
arch/powerpc/include/asm/pgtable-ppc64.h +0 -1
@@ -600,6 +600,5 @@ static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,*/ return true; } -#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */
arch/powerpc/include/asm/pgtable.h +2 -4
@@ -274,11 +274,9 @@ extern void paging_init(void);*/ extern void update_mmu_cache (struct vm_area_struct *,unsigned long ,pte_t *); -extern int gup_hugepd (hugepd_t *hugepd,unsigned pdshift,unsigned long addr, -unsigned long end,int write,struct page **pages,int *nr); -extern int gup_hugepte (pte_t *ptep,unsigned long sz,unsigned long addr, -unsigned long end,int write,struct page **pages,int *nr); +unsigned long end,int write, +struct page **pages,int *nr);#ifndef CONFIG_TRANSPARENT_HUGEPAGE #define pmd_large (pmd) 0#define has_transparent_hugepage () 0
arch/powerpc/mm/Makefile +1 -1
@@ -6,7 +6,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) -obj-y := fault.o mem.o pgtable.o gup.o mmap.o \ +obj-y := fault.o mem.o pgtable.o mmap.o \ init_$(CONFIG_WORD_SIZE).o \ pgtable_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \
arch/powerpc/mm/gup.c deleted +0 -235
235 lines not on this page · raw message
arch/powerpc/mm/hugetlbpage.c +12 -21
@@ -233,7 +233,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long szif (hugepd_none (*hpdp) &&__hugepte_alloc (mm, hpdp, addr, pdshift, pshift))return NULL ; - return hugepte_offset(hpdp, addr, pdshift); + return hugepte_offset(*hpdp, addr, pdshift); }#else
@@ -273,7 +273,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long szif (hugepd_none (*hpdp) &&__hugepte_alloc (mm, hpdp, addr, pdshift, pshift))return NULL ; - return hugepte_offset(hpdp, addr, pdshift); + return hugepte_offset(*hpdp, addr, pdshift); }#endif
@@ -541,7 +541,7 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, do { pmd = pmd_offset(pud, addr); next = pmd_addr_end(addr, end); - if (!is_hugepd(pmd)) { + if (!is_hugepd(__hugepd(pmd_val(*pmd)))) { /* * if it is not hugepd pointer, we should already find * it cleared.
@@ -590,7 +590,7 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, do { pud = pud_offset(pgd, addr); next = pud_addr_end(addr, end); - if (!is_hugepd(pud)) { + if (!is_hugepd(__hugepd(pud_val(*pud)))) { if (pud_none_or_clear_bad(pud)) continue; hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
@@ -656,7 +656,7 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, do { next = pgd_addr_end(addr, end); pgd = pgd_offset(tlb->mm, addr); - if (!is_hugepd(pgd)) { + if (!is_hugepd(__hugepd(pgd_val(*pgd)))) { if (pgd_none_or_clear_bad(pgd)) continue; hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
@@ -716,12 +716,11 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,return (__boundary -1 < end -1 ) ? __boundary : end; } -int gup_hugepd (hugepd_t *hugepd,unsigned pdshift, -unsigned long addr,unsigned long end, -int write,struct page **pages,int *nr) +int gup_huge_pd (hugepd_t hugepd,unsigned long addr,unsigned pdshift, +unsigned long end,int write,struct page **pages,int *nr) {pte_t *ptep; -unsigned long sz =1UL <<hugepd_shift (*hugepd); +unsigned long sz =1UL <<hugepd_shift (hugepd);unsigned long next; ptep =hugepte_offset (hugepd, addr, pdshift);
@@ -964,7 +963,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shiftelse if (pgd_huge (pgd)) { ret_pte = (pte_t *) pgdp; goto out; - }else if (is_hugepd (&pgd)) + }else if (is_hugepd (__hugepd (pgd_val (pgd)))) hpdp = (hugepd_t *)&pgd;else {/*
@@ -981,7 +980,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shiftelse if (pud_huge (pud)) { ret_pte = (pte_t *) pudp; goto out; - }else if (is_hugepd (&pud)) + }else if (is_hugepd (__hugepd (pud_val (pud)))) hpdp = (hugepd_t *)&pud;else { pdshift =PMD_SHIFT ;
@@ -1002,7 +1001,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shiftif (pmd_huge (pmd) ||pmd_large (pmd)) { ret_pte = (pte_t *) pmdp; goto out; - }else if (is_hugepd (&pmd)) + }else if (is_hugepd (__hugepd (pmd_val (pmd)))) hpdp = (hugepd_t *)&pmd;else return pte_offset_kernel (&pmd, ea);
@@ -1011,7 +1010,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shiftif (!hpdp)return NULL ; - ret_pte =hugepte_offset (hpdp, ea, pdshift); + ret_pte =hugepte_offset (*hpdp, ea, pdshift); pdshift =hugepd_shift (*hpdp); out:if (shift)
@@ -1041,14 +1040,6 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,if ((pte_val (pte) & mask) != mask)return 0 ; -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -/* -* check for splitting here -*/ -if (pmd_trans_splitting (pte_pmd (pte))) -return 0 ; -#endif -/* hugepages are never "special" */ VM_BUG_ON (!pfn_valid (pte_pfn (pte)));
Signature · 7 lines
2.1.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>