From 18f7e2b45eab25b7b83c340146a1c9a8828a27ce Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 16 Feb 2019 04:16:10 +0000 Subject: [PATCH] powerpc/booke: Use DMAP where possible for page copy and zeroing This avoids several locks and pmap_kenter()'s, improving performance marginally. MFC after: 2 weeks --- sys/powerpc/booke/pmap.c | 103 +++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 36 deletions(-) diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 19b9b36b491c..e5d20834adc9 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -2973,14 +2973,19 @@ mmu_booke_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size) /* XXX KASSERT off and size are within a single page? */ - mtx_lock(&zero_page_mutex); - va = zero_page_va; + if (hw_direct_map) { + va = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)); + bzero((caddr_t)va + off, size); + } else { + mtx_lock(&zero_page_mutex); + va = zero_page_va; - mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m)); - bzero((caddr_t)va + off, size); - mmu_booke_kremove(mmu, va); + mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m)); + bzero((caddr_t)va + off, size); + mmu_booke_kremove(mmu, va); - mtx_unlock(&zero_page_mutex); + mtx_unlock(&zero_page_mutex); + } } /* @@ -2991,15 +2996,23 @@ mmu_booke_zero_page(mmu_t mmu, vm_page_t m) { vm_offset_t off, va; - mtx_lock(&zero_page_mutex); - va = zero_page_va; + if (hw_direct_map) { + va = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)); + } else { + va = zero_page_va; + mtx_lock(&zero_page_mutex); + + mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m)); + } - mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m)); for (off = 0; off < PAGE_SIZE; off += cacheline_size) __asm __volatile("dcbz 0,%0" :: "r"(va + off)); - mmu_booke_kremove(mmu, va); - mtx_unlock(&zero_page_mutex); + if (!hw_direct_map) { + mmu_booke_kremove(mmu, va); + + mtx_unlock(&zero_page_mutex); + } } /* @@ -3015,13 +3028,20 @@ mmu_booke_copy_page(mmu_t mmu, vm_page_t sm, vm_page_t dm) sva = copy_page_src_va; dva = copy_page_dst_va; - mtx_lock(©_page_mutex); - mmu_booke_kenter(mmu, sva, VM_PAGE_TO_PHYS(sm)); - mmu_booke_kenter(mmu, dva, VM_PAGE_TO_PHYS(dm)); + if (hw_direct_map) { + sva = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(sm)); + dva = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dm)); + } else { + mtx_lock(©_page_mutex); + mmu_booke_kenter(mmu, sva, VM_PAGE_TO_PHYS(sm)); + mmu_booke_kenter(mmu, dva, VM_PAGE_TO_PHYS(dm)); + } memcpy((caddr_t)dva, (caddr_t)sva, PAGE_SIZE); - mmu_booke_kremove(mmu, dva); - mmu_booke_kremove(mmu, sva); - mtx_unlock(©_page_mutex); + if (!hw_direct_map) { + mmu_booke_kremove(mmu, dva); + mmu_booke_kremove(mmu, sva); + mtx_unlock(©_page_mutex); + } } static inline void @@ -3032,26 +3052,31 @@ mmu_booke_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset, vm_offset_t a_pg_offset, b_pg_offset; int cnt; - mtx_lock(©_page_mutex); - while (xfersize > 0) { - a_pg_offset = a_offset & PAGE_MASK; - cnt = min(xfersize, PAGE_SIZE - a_pg_offset); - mmu_booke_kenter(mmu, copy_page_src_va, - VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT])); - a_cp = (char *)copy_page_src_va + a_pg_offset; - b_pg_offset = b_offset & PAGE_MASK; - cnt = min(cnt, PAGE_SIZE - b_pg_offset); - mmu_booke_kenter(mmu, copy_page_dst_va, - VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT])); - b_cp = (char *)copy_page_dst_va + b_pg_offset; - bcopy(a_cp, b_cp, cnt); - mmu_booke_kremove(mmu, copy_page_dst_va); - mmu_booke_kremove(mmu, copy_page_src_va); - a_offset += cnt; - b_offset += cnt; - xfersize -= cnt; + if (hw_direct_map) { + bcopy((caddr_t)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(*ma)) + a_offset, + (caddr_t)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(*mb)), xfersize); + } else { + mtx_lock(©_page_mutex); + while (xfersize > 0) { + a_pg_offset = a_offset & PAGE_MASK; + cnt = min(xfersize, PAGE_SIZE - a_pg_offset); + mmu_booke_kenter(mmu, copy_page_src_va, + VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT])); + a_cp = (char *)copy_page_src_va + a_pg_offset; + b_pg_offset = b_offset & PAGE_MASK; + cnt = min(cnt, PAGE_SIZE - b_pg_offset); + mmu_booke_kenter(mmu, copy_page_dst_va, + VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT])); + b_cp = (char *)copy_page_dst_va + b_pg_offset; + bcopy(a_cp, b_cp, cnt); + mmu_booke_kremove(mmu, copy_page_dst_va); + mmu_booke_kremove(mmu, copy_page_src_va); + a_offset += cnt; + b_offset += cnt; + xfersize -= cnt; + } + mtx_unlock(©_page_mutex); } - mtx_unlock(©_page_mutex); } static vm_offset_t @@ -3064,6 +3089,9 @@ mmu_booke_quick_enter_page(mmu_t mmu, vm_page_t m) paddr = VM_PAGE_TO_PHYS(m); + if (hw_direct_map) + return (PHYS_TO_DMAP(paddr)); + flags = PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | PTE_VALID; flags |= tlb_calc_wimg(paddr, pmap_page_get_memattr(m)) << PTE_MAS2_SHIFT; flags |= PTE_PS_4KB; @@ -3097,6 +3125,9 @@ mmu_booke_quick_remove_page(mmu_t mmu, vm_offset_t addr) { pte_t *pte; + if (hw_direct_map) + return; + pte = pte_find(mmu, kernel_pmap, addr); KASSERT(PCPU_GET(qmap_addr) == addr,