Inter-revision diff: patch 17

Comparing v5 (message) to v1 (message)

--- v5
+++ v1
@@ -1,107 +1,205 @@
-This patch move pgtable_t into platform headers.
-
-It gets rid of the CONFIG_PPC_64K_PAGES case for PPC64
-as nohash/64 doesn't support CONFIG_PPC_64K_PAGES.
+DO NOT APPLY THAT ONE, IT BUGS. But comments are welcome.
+
+
+In 16k pages mode, the 8xx still need only 4k for the page table.
+
+This patch makes use of the pte_fragment functions in order
+to avoid wasting memory space
 
 Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
 ---
- arch/powerpc/include/asm/book3s/32/mmu-hash.h |  2 ++
- arch/powerpc/include/asm/book3s/64/mmu.h      |  9 +++++++++
- arch/powerpc/include/asm/nohash/32/mmu.h      |  4 ++++
- arch/powerpc/include/asm/nohash/64/mmu.h      |  4 ++++
- arch/powerpc/include/asm/page.h               | 14 --------------
- 5 files changed, 19 insertions(+), 14 deletions(-)
-
-diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
-index e38c91388c40..5bd26c218b94 100644
---- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h
-+++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
-@@ -42,6 +42,8 @@ struct ppc_bat {
- 	u32 batu;
- 	u32 batl;
- };
-+
-+typedef struct page *pgtable_t;
- #endif /* !__ASSEMBLY__ */
- 
- /*
-diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
-index 9c8c669a6b6a..488e7ed07e96 100644
---- a/arch/powerpc/include/asm/book3s/64/mmu.h
-+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
-@@ -2,6 +2,8 @@
- #ifndef _ASM_POWERPC_BOOK3S_64_MMU_H_
- #define _ASM_POWERPC_BOOK3S_64_MMU_H_
- 
-+#include <asm/page.h>
-+
- #ifndef __ASSEMBLY__
- /*
-  * Page size definition
-@@ -24,6 +26,13 @@ struct mmu_psize_def {
- };
- extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
- 
-+/*
-+ * For BOOK3s 64 with 4k and 64K linux page size
-+ * we want to use pointers, because the page table
-+ * actually store pfn
-+ */
-+typedef pte_t *pgtable_t;
-+
- #endif /* __ASSEMBLY__ */
- 
- /* 64-bit classic hash table MMU */
-diff --git a/arch/powerpc/include/asm/nohash/32/mmu.h b/arch/powerpc/include/asm/nohash/32/mmu.h
-index af0e8b54876a..f61f933a4cd8 100644
---- a/arch/powerpc/include/asm/nohash/32/mmu.h
-+++ b/arch/powerpc/include/asm/nohash/32/mmu.h
-@@ -16,4 +16,8 @@
- #include <asm/nohash/32/mmu-8xx.h>
+ arch/powerpc/include/asm/mmu-8xx.h           |  4 ++++
+ arch/powerpc/include/asm/nohash/32/pgalloc.h | 29 +++++++++++++++++++++++++++-
+ arch/powerpc/include/asm/nohash/32/pgtable.h |  5 ++++-
+ arch/powerpc/mm/mmu_context_nohash.c         |  4 ++++
+ arch/powerpc/mm/pgtable.c                    | 10 +++++++++-
+ arch/powerpc/mm/pgtable_32.c                 | 12 ++++++++++++
+ arch/powerpc/platforms/Kconfig.cputype       |  1 +
+ 7 files changed, 62 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
+index 193f53116c7a..4f4cb754afd8 100644
+--- a/arch/powerpc/include/asm/mmu-8xx.h
++++ b/arch/powerpc/include/asm/mmu-8xx.h
+@@ -190,6 +190,10 @@ typedef struct {
+ 	struct slice_mask mask_8m;
+ # endif
  #endif
- 
-+#ifndef __ASSEMBLY__
-+typedef struct page *pgtable_t;
-+#endif
-+
- #endif /* _ASM_POWERPC_NOHASH_32_MMU_H_ */
-diff --git a/arch/powerpc/include/asm/nohash/64/mmu.h b/arch/powerpc/include/asm/nohash/64/mmu.h
-index 87871d027b75..e6585480dfc4 100644
---- a/arch/powerpc/include/asm/nohash/64/mmu.h
-+++ b/arch/powerpc/include/asm/nohash/64/mmu.h
-@@ -5,4 +5,8 @@
- /* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */
- #include <asm/nohash/mmu-book3e.h>
- 
-+#ifndef __ASSEMBLY__
-+typedef struct page *pgtable_t;
-+#endif
-+
- #endif /* _ASM_POWERPC_NOHASH_64_MMU_H_ */
-diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
-index f6a1265face2..ddfb4b965e5b 100644
---- a/arch/powerpc/include/asm/page.h
-+++ b/arch/powerpc/include/asm/page.h
-@@ -335,20 +335,6 @@ void arch_free_page(struct page *page, int order);
++#ifdef CONFIG_NEED_PTE_FRAG
++	/* for 4K PTE fragment support */
++	void *pte_frag;
++#endif
+ } mm_context_t;
+ 
+ #define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000)
+diff --git a/arch/powerpc/include/asm/nohash/32/pgalloc.h b/arch/powerpc/include/asm/nohash/32/pgalloc.h
+index 1c6461e7c6aa..1e3b8f580499 100644
+--- a/arch/powerpc/include/asm/nohash/32/pgalloc.h
++++ b/arch/powerpc/include/asm/nohash/32/pgalloc.h
+@@ -93,6 +93,32 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
+ 	((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel_g(pmd, address))? \
+ 		NULL: pte_offset_kernel(pmd, address))
+ 
++#ifdef CONFIG_NEED_PTE_FRAG
++extern pte_t *pte_fragment_alloc(struct mm_struct *, unsigned long, int);
++extern void pte_fragment_free(unsigned long *, int);
++
++static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
++					  unsigned long address)
++{
++	return (pte_t *)pte_fragment_alloc(mm, address, 1);
++}
++
++static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
++				      unsigned long address)
++{
++	return (pgtable_t)pte_fragment_alloc(mm, address, 0);
++}
++
++static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
++{
++	pte_fragment_free((unsigned long *)pte, 1);
++}
++
++static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
++{
++	pte_fragment_free((unsigned long *)ptepage, 0);
++}
++#else
+ extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
+ extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
+ 
+@@ -106,11 +132,12 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
+ 	pgtable_page_dtor(ptepage);
+ 	__free_page(ptepage);
+ }
++#endif
+ 
+ static inline void pgtable_free(void *table, unsigned index_size)
+ {
+ 	if (!index_size) {
+-		free_page((unsigned long)table);
++		pte_free_kernel(NULL, table);
+ 	} else {
+ 		BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
+ 		kmem_cache_free(PGT_CACHE(index_size), table);
+diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
+index 3efd616bbc80..e2a22c8dc7f6 100644
+--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
++++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
+@@ -20,6 +20,9 @@ extern int icache_44x_need_flush;
+ 
+ #if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
+ #define PTE_INDEX_SIZE  (PTE_SHIFT - 2)
++#define PTE_FRAG_NR		4
++#define PTE_FRAG_SIZE_SHIFT	12
++#define PTE_FRAG_SIZE		(1UL << PTE_FRAG_SIZE_SHIFT)
+ #else
+ #define PTE_INDEX_SIZE	PTE_SHIFT
  #endif
- 
- struct vm_area_struct;
--#ifdef CONFIG_PPC_BOOK3S_64
--/*
-- * For BOOK3s 64 with 4k and 64K linux page size
-- * we want to use pointers, because the page table
-- * actually store pfn
-- */
--typedef pte_t *pgtable_t;
--#else
--#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC64)
--typedef pte_t *pgtable_t;
--#else
--typedef struct page *pgtable_t;
--#endif
--#endif
- 
- #include <asm-generic/memory_model.h>
- #endif /* __ASSEMBLY__ */
+@@ -303,7 +306,7 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm,
+  */
+ #ifndef CONFIG_BOOKE
+ #define pmd_page_vaddr(pmd)	\
+-	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
++	((unsigned long) __va(pmd_val(pmd) & ~(PTE_TABLE_SIZE - 1)))
+ #define pmd_page(pmd)		\
+ 	pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+ #else
+diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
+index e09228a9ad00..8b0ab33673e5 100644
+--- a/arch/powerpc/mm/mmu_context_nohash.c
++++ b/arch/powerpc/mm/mmu_context_nohash.c
+@@ -390,6 +390,9 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm)
+ #endif
+ 	mm->context.id = MMU_NO_CONTEXT;
+ 	mm->context.active = 0;
++#ifdef CONFIG_NEED_PTE_FRAG
++	mm->context.pte_frag = NULL;
++#endif
+ 	return 0;
+ }
+ 
+@@ -418,6 +421,7 @@ void destroy_context(struct mm_struct *mm)
+ 		nr_free_contexts++;
+ 	}
+ 	raw_spin_unlock_irqrestore(&context_lock, flags);
++	destroy_pagetable_page(mm);
+ }
+ 
+ #ifdef CONFIG_SMP
+diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
+index 2d34755ed727..96cc5aa73331 100644
+--- a/arch/powerpc/mm/pgtable.c
++++ b/arch/powerpc/mm/pgtable.c
+@@ -23,6 +23,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/gfp.h>
++#include <linux/memblock.h>
+ #include <linux/mm.h>
+ #include <linux/percpu.h>
+ #include <linux/hardirq.h>
+@@ -320,10 +321,17 @@ static pte_t *__alloc_for_cache(struct mm_struct *mm, int kernel)
+ 	return (pte_t *)ret;
+ }
+ 
+-pte_t *pte_fragment_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel)
++__ref pte_t *pte_fragment_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel)
+ {
+ 	pte_t *pte;
+ 
++	if (kernel && !slab_is_available()) {
++		pte = __va(memblock_alloc(PTE_FRAG_SIZE, PTE_FRAG_SIZE));
++		if (pte)
++			memset(pte, 0, PTE_FRAG_SIZE);
++
++		return pte;
++	}
+ 	pte = get_from_cache(mm);
+ 	if (pte)
+ 		return pte;
+diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
+index 3aa0c78db95d..5c8737cf2945 100644
+--- a/arch/powerpc/mm/pgtable_32.c
++++ b/arch/powerpc/mm/pgtable_32.c
+@@ -40,6 +40,17 @@
+ 
+ extern char etext[], _stext[], _sinittext[], _einittext[];
+ 
++#ifdef CONFIG_NEED_PTE_FRAG
++void pte_fragment_free(unsigned long *table, int kernel)
++{
++	struct page *page = virt_to_page(table);
++	if (put_page_testzero(page)) {
++		if (!kernel)
++			pgtable_page_dtor(page);
++		free_unref_page(page);
++	}
++}
++#else
+ __ref pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+ {
+ 	pte_t *pte;
+@@ -69,6 +80,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
+ 	}
+ 	return ptepage;
+ }
++#endif
+ 
+ #ifdef CONFIG_PPC_GUARDED_PAGE_IN_PMD
+ int __pte_alloc_kernel_g(pmd_t *pmd, unsigned long address)
+diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
+index 7172b04c91b5..eff6210ad3c0 100644
+--- a/arch/powerpc/platforms/Kconfig.cputype
++++ b/arch/powerpc/platforms/Kconfig.cputype
+@@ -340,6 +340,7 @@ config PPC_MM_SLICES
+ config NEED_PTE_FRAG
+ 	bool
+ 	default y if PPC_BOOK3S_64 && PPC_64K_PAGES
++	default y if PPC_8xx && PPC_16K_PAGES
+ 	default n
+ 
+ config PPC_HAVE_PMU_SUPPORT
 -- 
 2.13.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help