diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 22:26:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-09 22:26:14 -0400 |
commit | 0cf744bc7ae8e0072159a901f6e1a159bbc30ffa (patch) | |
tree | fc8222a3a5af4f42226070c3f76462cfcf0b4e50 /arch/arm/include | |
parent | b528392669415dc1e53a047215e5ad6c2de879fc (diff) | |
parent | 7f8998c7aef3ac9c5f3f2943e083dfa6302e90d0 (diff) |
Merge branch 'akpm' (fixes from Andrew Morton)
Merge patch-bomb from Andrew Morton:
- part of OCFS2 (review is laggy again)
- procfs
- slab
- all of MM
- zram, zbud
- various other random things: arch, filesystems.
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (164 commits)
nosave: consolidate __nosave_{begin,end} in <asm/sections.h>
include/linux/screen_info.h: remove unused ORIG_* macros
kernel/sys.c: compat sysinfo syscall: fix undefined behavior
kernel/sys.c: whitespace fixes
acct: eliminate compile warning
kernel/async.c: switch to pr_foo()
include/linux/blkdev.h: use NULL instead of zero
include/linux/kernel.h: deduplicate code implementing clamp* macros
include/linux/kernel.h: rewrite min3, max3 and clamp using min and max
alpha: use Kbuild logic to include <asm-generic/sections.h>
frv: remove deprecated IRQF_DISABLED
frv: remove unused cpuinfo_frv and friends to fix future build error
zbud: avoid accessing last unused freelist
zsmalloc: simplify init_zspage free obj linking
mm/zsmalloc.c: correct comment for fullness group computation
zram: use notify_free to account all free notifications
zram: report maximum used memory
zram: zram memory size limitation
zsmalloc: change return value unit of zs_get_total_size_bytes
zsmalloc: move pages_allocated to zs_pool
...
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/pgtable-2level.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/pgtable-3level.h | 15 | ||||
-rw-r--r-- | arch/arm/include/asm/pgtable.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/tlb.h | 38 |
4 files changed, 55 insertions, 6 deletions
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index 219ac88a9542..f0279411847d 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h | |||
@@ -182,6 +182,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | |||
182 | #define pmd_addr_end(addr,end) (end) | 182 | #define pmd_addr_end(addr,end) (end) |
183 | 183 | ||
184 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) | 184 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) |
185 | #define pte_special(pte) (0) | ||
186 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
185 | 187 | ||
186 | /* | 188 | /* |
187 | * We don't have huge page support for short descriptors, for the moment | 189 | * We don't have huge page support for short descriptors, for the moment |
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 06e0bc0f8b00..a31ecdad4b59 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h | |||
@@ -213,10 +213,19 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | |||
213 | #define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val))) | 213 | #define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val))) |
214 | 214 | ||
215 | #define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF)) | 215 | #define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF)) |
216 | #define pte_special(pte) (pte_isset((pte), L_PTE_SPECIAL)) | ||
217 | static inline pte_t pte_mkspecial(pte_t pte) | ||
218 | { | ||
219 | pte_val(pte) |= L_PTE_SPECIAL; | ||
220 | return pte; | ||
221 | } | ||
222 | #define __HAVE_ARCH_PTE_SPECIAL | ||
216 | 223 | ||
217 | #define __HAVE_ARCH_PMD_WRITE | 224 | #define __HAVE_ARCH_PMD_WRITE |
218 | #define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY)) | 225 | #define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY)) |
219 | #define pmd_dirty(pmd) (pmd_isset((pmd), L_PMD_SECT_DIRTY)) | 226 | #define pmd_dirty(pmd) (pmd_isset((pmd), L_PMD_SECT_DIRTY)) |
227 | #define pud_page(pud) pmd_page(__pmd(pud_val(pud))) | ||
228 | #define pud_write(pud) pmd_write(__pmd(pud_val(pud))) | ||
220 | 229 | ||
221 | #define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd)) | 230 | #define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd)) |
222 | #define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd)) | 231 | #define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd)) |
@@ -224,6 +233,12 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | |||
224 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 233 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
225 | #define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd)) | 234 | #define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd)) |
226 | #define pmd_trans_splitting(pmd) (pmd_isset((pmd), L_PMD_SECT_SPLITTING)) | 235 | #define pmd_trans_splitting(pmd) (pmd_isset((pmd), L_PMD_SECT_SPLITTING)) |
236 | |||
237 | #ifdef CONFIG_HAVE_RCU_TABLE_FREE | ||
238 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH | ||
239 | void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address, | ||
240 | pmd_t *pmdp); | ||
241 | #endif | ||
227 | #endif | 242 | #endif |
228 | 243 | ||
229 | #define PMD_BIT_FUNC(fn,op) \ | 244 | #define PMD_BIT_FUNC(fn,op) \ |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 01baef07cd0c..90aa4583b308 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -226,7 +226,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
226 | #define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY)) | 226 | #define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY)) |
227 | #define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG)) | 227 | #define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG)) |
228 | #define pte_exec(pte) (pte_isclear((pte), L_PTE_XN)) | 228 | #define pte_exec(pte) (pte_isclear((pte), L_PTE_XN)) |
229 | #define pte_special(pte) (0) | ||
230 | 229 | ||
231 | #define pte_valid_user(pte) \ | 230 | #define pte_valid_user(pte) \ |
232 | (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte)) | 231 | (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte)) |
@@ -245,7 +244,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
245 | unsigned long ext = 0; | 244 | unsigned long ext = 0; |
246 | 245 | ||
247 | if (addr < TASK_SIZE && pte_valid_user(pteval)) { | 246 | if (addr < TASK_SIZE && pte_valid_user(pteval)) { |
248 | __sync_icache_dcache(pteval); | 247 | if (!pte_special(pteval)) |
248 | __sync_icache_dcache(pteval); | ||
249 | ext |= PTE_EXT_NG; | 249 | ext |= PTE_EXT_NG; |
250 | } | 250 | } |
251 | 251 | ||
@@ -264,8 +264,6 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); | |||
264 | PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); | 264 | PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); |
265 | PTE_BIT_FUNC(mknexec, |= L_PTE_XN); | 265 | PTE_BIT_FUNC(mknexec, |= L_PTE_XN); |
266 | 266 | ||
267 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
268 | |||
269 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 267 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
270 | { | 268 | { |
271 | const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | | 269 | const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | |
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index f1a0dace3efe..3cadb726ec88 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h | |||
@@ -35,12 +35,39 @@ | |||
35 | 35 | ||
36 | #define MMU_GATHER_BUNDLE 8 | 36 | #define MMU_GATHER_BUNDLE 8 |
37 | 37 | ||
38 | #ifdef CONFIG_HAVE_RCU_TABLE_FREE | ||
39 | static inline void __tlb_remove_table(void *_table) | ||
40 | { | ||
41 | free_page_and_swap_cache((struct page *)_table); | ||
42 | } | ||
43 | |||
44 | struct mmu_table_batch { | ||
45 | struct rcu_head rcu; | ||
46 | unsigned int nr; | ||
47 | void *tables[0]; | ||
48 | }; | ||
49 | |||
50 | #define MAX_TABLE_BATCH \ | ||
51 | ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *)) | ||
52 | |||
53 | extern void tlb_table_flush(struct mmu_gather *tlb); | ||
54 | extern void tlb_remove_table(struct mmu_gather *tlb, void *table); | ||
55 | |||
56 | #define tlb_remove_entry(tlb, entry) tlb_remove_table(tlb, entry) | ||
57 | #else | ||
58 | #define tlb_remove_entry(tlb, entry) tlb_remove_page(tlb, entry) | ||
59 | #endif /* CONFIG_HAVE_RCU_TABLE_FREE */ | ||
60 | |||
38 | /* | 61 | /* |
39 | * TLB handling. This allows us to remove pages from the page | 62 | * TLB handling. This allows us to remove pages from the page |
40 | * tables, and efficiently handle the TLB issues. | 63 | * tables, and efficiently handle the TLB issues. |
41 | */ | 64 | */ |
42 | struct mmu_gather { | 65 | struct mmu_gather { |
43 | struct mm_struct *mm; | 66 | struct mm_struct *mm; |
67 | #ifdef CONFIG_HAVE_RCU_TABLE_FREE | ||
68 | struct mmu_table_batch *batch; | ||
69 | unsigned int need_flush; | ||
70 | #endif | ||
44 | unsigned int fullmm; | 71 | unsigned int fullmm; |
45 | struct vm_area_struct *vma; | 72 | struct vm_area_struct *vma; |
46 | unsigned long start, end; | 73 | unsigned long start, end; |
@@ -101,6 +128,9 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb) | |||
101 | static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) | 128 | static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) |
102 | { | 129 | { |
103 | tlb_flush(tlb); | 130 | tlb_flush(tlb); |
131 | #ifdef CONFIG_HAVE_RCU_TABLE_FREE | ||
132 | tlb_table_flush(tlb); | ||
133 | #endif | ||
104 | } | 134 | } |
105 | 135 | ||
106 | static inline void tlb_flush_mmu_free(struct mmu_gather *tlb) | 136 | static inline void tlb_flush_mmu_free(struct mmu_gather *tlb) |
@@ -129,6 +159,10 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start | |||
129 | tlb->pages = tlb->local; | 159 | tlb->pages = tlb->local; |
130 | tlb->nr = 0; | 160 | tlb->nr = 0; |
131 | __tlb_alloc_page(tlb); | 161 | __tlb_alloc_page(tlb); |
162 | |||
163 | #ifdef CONFIG_HAVE_RCU_TABLE_FREE | ||
164 | tlb->batch = NULL; | ||
165 | #endif | ||
132 | } | 166 | } |
133 | 167 | ||
134 | static inline void | 168 | static inline void |
@@ -205,7 +239,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
205 | tlb_add_flush(tlb, addr + SZ_1M); | 239 | tlb_add_flush(tlb, addr + SZ_1M); |
206 | #endif | 240 | #endif |
207 | 241 | ||
208 | tlb_remove_page(tlb, pte); | 242 | tlb_remove_entry(tlb, pte); |
209 | } | 243 | } |
210 | 244 | ||
211 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | 245 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, |
@@ -213,7 +247,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | |||
213 | { | 247 | { |
214 | #ifdef CONFIG_ARM_LPAE | 248 | #ifdef CONFIG_ARM_LPAE |
215 | tlb_add_flush(tlb, addr); | 249 | tlb_add_flush(tlb, addr); |
216 | tlb_remove_page(tlb, virt_to_page(pmdp)); | 250 | tlb_remove_entry(tlb, virt_to_page(pmdp)); |
217 | #endif | 251 | #endif |
218 | } | 252 | } |
219 | 253 | ||