Re: [PATCH 19/31] powerpc/mm: Convert 4k hash insert to C
Benjamin Herrenschmidtwrites: > On Mon, 2015-09-21 at 12:10 +0530, Aneesh Kumar K.V wrote: >> Signed-off-by: Aneesh Kumar K.V >> --- >> arch/powerpc/mm/Makefile| 3 + >> arch/powerpc/mm/hash64_64k.c| 204 + >> arch/powerpc/mm/hash_low_64.S | 380 -- >> -- >> arch/powerpc/mm/hash_utils_64.c | 4 +- >> 4 files changed, 210 insertions(+), 381 deletions(-) >> create mode 100644 arch/powerpc/mm/hash64_64k.c > > Did you check if there was any measurable performance difference ? > I looked at the performance number with and without patch. I don't see much impact in the numbers. We do have a path lengh increase ( I measured this using systemsim) Path length __hash_page_4k with patch: 196 without patch: 142 Path length __hash_page_64k with patch: 219 without patch: 154 But even if we have a path lengh increase of around 50 instructions. We don't see the impact when running workload. I tried the kernelbuild test. With THP enabled (which is default) we see an improvement. I haven't fully looked at the reason. This could be due to reduced contention of ptl lock. __hash_thp_page is already a C code. make -j64 vmlinux modules With fix: - real1m35.509s user56m8.565s sys 4m34.973s real1m32.174s user57m2.336s sys 4m39.142s Without fix: --- real1m37.703s user58m50.783s sys 7m52.440s real1m37.890s user57m55.445s sys 7m50.501s THP disabled: make -j64 vmlinux modules With fix: - real1m37.197s user58m28.672s sys 7m58.188s real1m44.638s user58m37.551s sys 7m53.960s Without fix: real1m41.224s user58m46.944s sys 7m49.714s real1m42.585s user59m14.019s sys 7m52.714s -aneesh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 19/31] powerpc/mm: Convert 4k hash insert to C
Signed-off-by: Aneesh Kumar K.V--- arch/powerpc/mm/Makefile| 3 + arch/powerpc/mm/hash64_64k.c| 204 + arch/powerpc/mm/hash_low_64.S | 380 arch/powerpc/mm/hash_utils_64.c | 4 +- 4 files changed, 210 insertions(+), 381 deletions(-) create mode 100644 arch/powerpc/mm/hash64_64k.c diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 3eb73a38220d..f80ad1a76cc8 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -18,6 +18,9 @@ obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \ tlb_hash$(CONFIG_WORD_SIZE).o \ mmu_context_hash$(CONFIG_WORD_SIZE).o +ifeq ($(CONFIG_PPC_STD_MMU_64),y) +obj-$(CONFIG_PPC_64K_PAGES)+= hash64_64k.o +endif obj-$(CONFIG_PPC_ICSWX)+= icswx.o obj-$(CONFIG_PPC_ICSWX_PID)+= icswx_pid.o obj-$(CONFIG_40x) += 40x_mmu.o diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c new file mode 100644 index ..cbbef40c549a --- /dev/null +++ b/arch/powerpc/mm/hash64_64k.c @@ -0,0 +1,204 @@ +/* + * Copyright IBM Corporation, 2015 + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include +#include +#include + +int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, + pte_t *ptep, unsigned long trap, unsigned long flags, + int ssize, int subpg_prot) +{ + real_pte_t rpte; + unsigned long *hidxp; + unsigned long hpte_group; + unsigned int subpg_index; + unsigned long shift = 12; /* 4K */ + unsigned long rflags, pa, hidx; + unsigned long old_pte, new_pte, subpg_pte; + unsigned long vpn, hash, slot; + + /* +* atomically mark the linux large page PTE busy and dirty +*/ + do { + pte_t pte = READ_ONCE(*ptep); + + old_pte = pte_val(pte); + /* If PTE busy, retry the access */ + if (unlikely(old_pte & _PAGE_BUSY)) + return 0; + /* If PTE permissions don't match, take page fault */ + if (unlikely(access & ~old_pte)) + return 1; + /* +* Try to lock the PTE, add ACCESSED and DIRTY if it was +* a write access. Since this is 4K insert of 64K page size +* also add _PAGE_COMBO +*/ + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | _PAGE_COMBO; + if (access & _PAGE_RW) + new_pte |= _PAGE_DIRTY; + } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, + old_pte, new_pte)); + /* +* Handle the subpage protection bits +*/ + subpg_pte = new_pte & ~subpg_prot; + /* +* PP bits. _PAGE_USER is already PP bit 0x2, so we only +* need to add in 0x1 if it's a read-only user page +*/ + rflags = subpg_pte & _PAGE_USER; + if ((subpg_pte & _PAGE_USER) && !((subpg_pte & _PAGE_RW) && + (subpg_pte & _PAGE_DIRTY))) + rflags |= 0x1; + /* +* _PAGE_EXEC -> HW_NO_EXEC since it's inverted +*/ + rflags |= ((subpg_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); + /* +* Always add C and Memory coherence bit +*/ + rflags |= HPTE_R_C | HPTE_R_M; + /* +* Add in WIMG bits +*/ + rflags |= (subpg_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | + _PAGE_COHERENT | _PAGE_GUARDED)); + /* +* FIXME!! check this +*/ + if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && + !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { + + /* +* No CPU has hugepages but lacks no execute, so we +* don't need to worry about that case +*/ + rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap); + } + + subpg_index = (ea & (PAGE_SIZE - 1)) >> shift; + vpn = hpt_vpn(ea, vsid, ssize); + rpte = __real_pte(old_pte, ptep); + /* +*None of the sub 4k page is hashed +*/ + if (!(old_pte & _PAGE_HASHPTE)) + goto htab_insert_hpte; + /* +* Check if the pte was already inserted into the hash
Re: [PATCH 19/31] powerpc/mm: Convert 4k hash insert to C
On Mon, 2015-09-21 at 12:10 +0530, Aneesh Kumar K.V wrote: > Signed-off-by: Aneesh Kumar K.V> --- > arch/powerpc/mm/Makefile| 3 + > arch/powerpc/mm/hash64_64k.c| 204 + > arch/powerpc/mm/hash_low_64.S | 380 -- > -- > arch/powerpc/mm/hash_utils_64.c | 4 +- > 4 files changed, 210 insertions(+), 381 deletions(-) > create mode 100644 arch/powerpc/mm/hash64_64k.c Did you check if there was any measurable performance difference ? Cheers, Ben. > diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile > index 3eb73a38220d..f80ad1a76cc8 100644 > --- a/arch/powerpc/mm/Makefile > +++ b/arch/powerpc/mm/Makefile > @@ -18,6 +18,9 @@ obj-$(CONFIG_PPC_STD_MMU_32)+= ppc_mmu_32.o > obj-$(CONFIG_PPC_STD_MMU)+= hash_low_$(CONFIG_WORD_SIZE).o \ > tlb_hash$(CONFIG_WORD_SIZE).o \ > > mmu_context_hash$(CONFIG_WORD_SIZE).o > +ifeq ($(CONFIG_PPC_STD_MMU_64),y) > +obj-$(CONFIG_PPC_64K_PAGES) += hash64_64k.o > +endif > obj-$(CONFIG_PPC_ICSWX) += icswx.o > obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o > obj-$(CONFIG_40x)+= 40x_mmu.o > diff --git a/arch/powerpc/mm/hash64_64k.c > b/arch/powerpc/mm/hash64_64k.c > new file mode 100644 > index ..cbbef40c549a > --- /dev/null > +++ b/arch/powerpc/mm/hash64_64k.c > @@ -0,0 +1,204 @@ > +/* > + * Copyright IBM Corporation, 2015 > + * Author Aneesh Kumar K.V > + * > + * This program is free software; you can redistribute it and/or > modify it > + * under the terms of version 2.1 of the GNU Lesser General Public > License > + * as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it would be useful, > but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > + * > + */ > + > +#include > +#include > +#include > + > +int __hash_page_4K(unsigned long ea, unsigned long access, unsigned > long vsid, > +pte_t *ptep, unsigned long trap, unsigned long > flags, > +int ssize, int subpg_prot) > +{ > + real_pte_t rpte; > + unsigned long *hidxp; > + unsigned long hpte_group; > + unsigned int subpg_index; > + unsigned long shift = 12; /* 4K */ > + unsigned long rflags, pa, hidx; > + unsigned long old_pte, new_pte, subpg_pte; > + unsigned long vpn, hash, slot; > + > + /* > + * atomically mark the linux large page PTE busy and dirty > + */ > + do { > + pte_t pte = READ_ONCE(*ptep); > + > + old_pte = pte_val(pte); > + /* If PTE busy, retry the access */ > + if (unlikely(old_pte & _PAGE_BUSY)) > + return 0; > + /* If PTE permissions don't match, take page fault > */ > + if (unlikely(access & ~old_pte)) > + return 1; > + /* > + * Try to lock the PTE, add ACCESSED and DIRTY if it > was > + * a write access. Since this is 4K insert of 64K > page size > + * also add _PAGE_COMBO > + */ > + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | > _PAGE_COMBO; > + if (access & _PAGE_RW) > + new_pte |= _PAGE_DIRTY; > + } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, > + old_pte, new_pte)); > + /* > + * Handle the subpage protection bits > + */ > + subpg_pte = new_pte & ~subpg_prot; > + /* > + * PP bits. _PAGE_USER is already PP bit 0x2, so we only > + * need to add in 0x1 if it's a read-only user page > + */ > + rflags = subpg_pte & _PAGE_USER; > + if ((subpg_pte & _PAGE_USER) && !((subpg_pte & _PAGE_RW) && > + (subpg_pte & _PAGE_DIRTY))) > + rflags |= 0x1; > + /* > + * _PAGE_EXEC -> HW_NO_EXEC since it's inverted > + */ > + rflags |= ((subpg_pte & _PAGE_EXEC) ? 0 : HPTE_R_N); > + /* > + * Always add C and Memory coherence bit > + */ > + rflags |= HPTE_R_C | HPTE_R_M; > + /* > + * Add in WIMG bits > + */ > + rflags |= (subpg_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | > + _PAGE_COHERENT | _PAGE_GUARDED)); > + /* > + * FIXME!! check this > + */ > + if (!cpu_has_feature(CPU_FTR_NOEXECUTE) && > + !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { > + > + /* > + * No CPU has hugepages but lacks no execute, so we > + * don't need to worry about that case > + */ > + rflags = hash_page_do_lazy_icache(rflags, > __pte(old_pte), trap); > + } > + > + subpg_index = (ea & (PAGE_SIZE - 1)) >> shift; > + vpn = hpt_vpn(ea, vsid,
Re: [PATCH 19/31] powerpc/mm: Convert 4k hash insert to C
Benjamin Herrenschmidtwrites: > On Mon, 2015-09-21 at 12:10 +0530, Aneesh Kumar K.V wrote: >> Signed-off-by: Aneesh Kumar K.V >> --- >> arch/powerpc/mm/Makefile| 3 + >> arch/powerpc/mm/hash64_64k.c| 204 + >> arch/powerpc/mm/hash_low_64.S | 380 -- >> -- >> arch/powerpc/mm/hash_utils_64.c | 4 +- >> 4 files changed, 210 insertions(+), 381 deletions(-) >> create mode 100644 arch/powerpc/mm/hash64_64k.c > > Did you check if there was any measurable performance difference ? > Not with this patch series. I did look at the .s file generated between __hash_page_4k and hash64_4k.c and found them similar. I will also try some micro benchmarks w.r.t hash insert/update and will update later with numbers. -aneesh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev