aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/tlb_nohash.c
diff options
context:
space:
mode:
authorBecky Bruce <beckyb@kernel.crashing.org>2011-06-28 05:54:48 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-19 19:19:40 -0400
commit41151e77a4d96ea138cede6d84c955aa4769ce74 (patch)
tree2d997b77b9adf406a2fd30326bff688577d2e64f /arch/powerpc/mm/tlb_nohash.c
parent7df5659eefad9b6d457ccdee016bd78bd064cfc0 (diff)
powerpc: Hugetlb for BookE
Enable hugepages on Freescale BookE processors. This allows the kernel to use huge TLB entries to map pages, which can greatly reduce the number of TLB misses and the amount of TLB thrashing experienced by applications with large memory footprints. Care should be taken when using this on FSL processors, as the number of large TLB entries supported by the core is low (16-64) on current processors. The supported set of hugepage sizes include 4m, 16m, 64m, 256m, and 1g. Page sizes larger than the max zone size are called "gigantic" pages and must be allocated on the command line (and cannot be deallocated). This is currently only fully implemented for Freescale 32-bit BookE processors, but there is some infrastructure in the code for 64-bit BooKE. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash.c')
-rw-r--r--arch/powerpc/mm/tlb_nohash.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index d32ec643c231..afc95c7304ae 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -36,14 +36,49 @@
36#include <linux/spinlock.h> 36#include <linux/spinlock.h>
37#include <linux/memblock.h> 37#include <linux/memblock.h>
38#include <linux/of_fdt.h> 38#include <linux/of_fdt.h>
39#include <linux/hugetlb.h>
39 40
40#include <asm/tlbflush.h> 41#include <asm/tlbflush.h>
41#include <asm/tlb.h> 42#include <asm/tlb.h>
42#include <asm/code-patching.h> 43#include <asm/code-patching.h>
44#include <asm/hugetlb.h>
43 45
44#include "mmu_decl.h" 46#include "mmu_decl.h"
45 47
46#ifdef CONFIG_PPC_BOOK3E 48/*
49 * This struct lists the sw-supported page sizes. The hardawre MMU may support
50 * other sizes not listed here. The .ind field is only used on MMUs that have
51 * indirect page table entries.
52 */
53#ifdef CONFIG_PPC_BOOK3E_MMU
54#ifdef CONFIG_FSL_BOOKE
55struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
56 [MMU_PAGE_4K] = {
57 .shift = 12,
58 .enc = BOOK3E_PAGESZ_4K,
59 },
60 [MMU_PAGE_4M] = {
61 .shift = 22,
62 .enc = BOOK3E_PAGESZ_4M,
63 },
64 [MMU_PAGE_16M] = {
65 .shift = 24,
66 .enc = BOOK3E_PAGESZ_16M,
67 },
68 [MMU_PAGE_64M] = {
69 .shift = 26,
70 .enc = BOOK3E_PAGESZ_64M,
71 },
72 [MMU_PAGE_256M] = {
73 .shift = 28,
74 .enc = BOOK3E_PAGESZ_256M,
75 },
76 [MMU_PAGE_1G] = {
77 .shift = 30,
78 .enc = BOOK3E_PAGESZ_1GB,
79 },
80};
81#else
47struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { 82struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
48 [MMU_PAGE_4K] = { 83 [MMU_PAGE_4K] = {
49 .shift = 12, 84 .shift = 12,
@@ -77,6 +112,8 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
77 .enc = BOOK3E_PAGESZ_1GB, 112 .enc = BOOK3E_PAGESZ_1GB,
78 }, 113 },
79}; 114};
115#endif /* CONFIG_FSL_BOOKE */
116
80static inline int mmu_get_tsize(int psize) 117static inline int mmu_get_tsize(int psize)
81{ 118{
82 return mmu_psize_defs[psize].enc; 119 return mmu_psize_defs[psize].enc;
@@ -87,7 +124,7 @@ static inline int mmu_get_tsize(int psize)
87 /* This isn't used on !Book3E for now */ 124 /* This isn't used on !Book3E for now */
88 return 0; 125 return 0;
89} 126}
90#endif 127#endif /* CONFIG_PPC_BOOK3E_MMU */
91 128
92/* The variables below are currently only used on 64-bit Book3E 129/* The variables below are currently only used on 64-bit Book3E
93 * though this will probably be made common with other nohash 130 * though this will probably be made common with other nohash
@@ -266,6 +303,11 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
266 303
267void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) 304void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
268{ 305{
306#ifdef CONFIG_HUGETLB_PAGE
307 if (is_vm_hugetlb_page(vma))
308 flush_hugetlb_page(vma, vmaddr);
309#endif
310
269 __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, 311 __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr,
270 mmu_get_tsize(mmu_virtual_psize), 0); 312 mmu_get_tsize(mmu_virtual_psize), 0);
271} 313}