aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSteve Capper <steve.capper@linaro.org>2014-10-09 18:29:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 22:26:01 -0400
commitb8cd51afe05a98ef907e61c603d5c5b7ad6242d8 (patch)
treeb0da97d39da9ddd9dabf5f033e9c0555ec374e6e /arch
parenta0ad5496b2b3accf09ab9485ad0170e3b4b1cb27 (diff)
arm: mm: enable RCU fast_gup
Activate the RCU fast_gup for ARM. We also need to force THP splits to broadcast an IPI s.t. we block in the fast_gup page walker. As THP splits are comparatively rare, this should not lead to a noticeable performance degradation. Some pre-requisite functions pud_write and pud_page are also added. Signed-off-by: Steve Capper <steve.capper@linaro.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Dann Frazier <dann.frazier@canonical.com> Cc: Hugh Dickins <hughd@google.com> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Will Deacon <will.deacon@arm.com> Cc: Christoffer Dall <christoffer.dall@linaro.org> Cc: Andrea Arcangeli <aarcange@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/include/asm/pgtable-3level.h8
-rw-r--r--arch/arm/mm/flush.c15
3 files changed, 27 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index eafe6aea64ff..18f392f8b744 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1661,6 +1661,10 @@ config ARCH_SELECT_MEMORY_MODEL
1661config HAVE_ARCH_PFN_VALID 1661config HAVE_ARCH_PFN_VALID
1662 def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM 1662 def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
1663 1663
1664config HAVE_GENERIC_RCU_GUP
1665 def_bool y
1666 depends on ARM_LPAE
1667
1664config HIGHMEM 1668config HIGHMEM
1665 bool "High Memory Support" 1669 bool "High Memory Support"
1666 depends on MMU 1670 depends on MMU
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 16122d4d7081..a31ecdad4b59 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -224,6 +224,8 @@ static inline pte_t pte_mkspecial(pte_t pte)
224#define __HAVE_ARCH_PMD_WRITE 224#define __HAVE_ARCH_PMD_WRITE
225#define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY)) 225#define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY))
226#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)))
227 229
228#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd)) 230#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd))
229#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))
@@ -231,6 +233,12 @@ static inline pte_t pte_mkspecial(pte_t pte)
231#ifdef CONFIG_TRANSPARENT_HUGEPAGE 233#ifdef CONFIG_TRANSPARENT_HUGEPAGE
232#define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd)) 234#define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd))
233#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
239void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
240 pmd_t *pmdp);
241#endif
234#endif 242#endif
235 243
236#define PMD_BIT_FUNC(fn,op) \ 244#define PMD_BIT_FUNC(fn,op) \
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 43d54f5b26b9..265b836b3bd1 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -400,3 +400,18 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l
400 */ 400 */
401 __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); 401 __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
402} 402}
403
404#ifdef CONFIG_TRANSPARENT_HUGEPAGE
405#ifdef CONFIG_HAVE_RCU_TABLE_FREE
406void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
407 pmd_t *pmdp)
408{
409 pmd_t pmd = pmd_mksplitting(*pmdp);
410 VM_BUG_ON(address & ~PMD_MASK);
411 set_pmd_at(vma->vm_mm, address, pmdp, pmd);
412
413 /* dummy IPI to serialise against fast_gup */
414 kick_all_cpus_sync();
415}
416#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
417#endif /* CONFIG_TRANSPARENT_HUGEPAGE */