From 5b9593f3bccb9904f260f9ad7f184e1d2921bd1e Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Thu, 26 Feb 2015 14:16:02 +0100 Subject: [PATCH] Revert "MIPS: Remove race window in page fault handling" Revert commit 2a4a8b1e5d9d ("MIPS: Remove race window in page fault handling") because it increased the number of flushed dcache pages and became a performance problem for some workloads. Signed-off-by: Lars Persson Cc: linux-mips@linux-mips.org Cc: paul.burton@imgtec.com Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/9345/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/pgtable.h | 9 +++++---- arch/mips/mm/cache.c | 27 ++++++++------------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index bffd46c..819af9d 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -127,10 +127,6 @@ do { \ } \ } while(0) - -extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, - pte_t pteval); - #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) #define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL)) @@ -152,6 +148,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte) buddy->pte_high |= _PAGE_GLOBAL; } } +#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { @@ -190,6 +187,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) } #endif } +#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { @@ -399,12 +397,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte); +extern void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte); static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) { pte_t pte = *ptep; __update_tlb(vma, address, pte); + __update_cache(vma, address, pte); } static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 7e3ea77..f7b91d3 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -119,36 +119,25 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr) EXPORT_SYMBOL(__flush_anon_page); -static void mips_flush_dcache_from_pte(pte_t pteval, unsigned long address) +void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) { struct page *page; - unsigned long pfn = pte_pfn(pteval); + unsigned long pfn, addr; + int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc; + pfn = pte_pfn(pte); if (unlikely(!pfn_valid(pfn))) return; - page = pfn_to_page(pfn); if (page_mapping(page) && Page_dcache_dirty(page)) { - unsigned long page_addr = (unsigned long) page_address(page); - - if (!cpu_has_ic_fills_f_dc || - pages_do_alias(page_addr, address & PAGE_MASK)) - flush_data_cache_page(page_addr); + addr = (unsigned long) page_address(page); + if (exec || pages_do_alias(addr, address & PAGE_MASK)) + flush_data_cache_page(addr); ClearPageDcacheDirty(page); } } -void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pteval) -{ - if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) { - if (pte_present(pteval)) - mips_flush_dcache_from_pte(pteval, addr); - } - - set_pte(ptep, pteval); -} - unsigned long _page_cachable_default; EXPORT_SYMBOL(_page_cachable_default); -- 2.7.4