[PATCH 19/31] powerpc/mm: Convert 4k hash insert to C
Benjamin Herrenschmidt
benh at kernel.crashing.org
Mon Sep 21 18:16:36 AEST 2015
On Mon, 2015-09-21 at 12:10 +0530, Aneesh Kumar K.V wrote:
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
> ---
> 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 000000000000..cbbef40c549a
> --- /dev/null
> +++ b/arch/powerpc/mm/hash64_64k.c
> @@ -0,0 +1,204 @@
> +/*
> + * Copyright IBM Corporation, 2015
> + * Author Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
> + *
> + * 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 <linux/mm.h>
> +#include <asm/machdep.h>
> +#include <asm/mmu.h>
> +
> +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 table
> + * as a 64k HW page, and invalidate the 64k HPTE if so.
> + */
> + if (!(old_pte & _PAGE_COMBO)) {
> + flush_hash_page(vpn, rpte, MMU_PAGE_64K, ssize,
> flags);
> + old_pte &= ~_PAGE_HPTE_SUB;
> + goto htab_insert_hpte;
> + }
> + /*
> + * Check for sub page valid and update
> + */
> + if (__rpte_sub_valid(rpte, subpg_index)) {
> + int ret;
> +
> + hash = hpt_hash(vpn, shift, ssize);
> + hidx = __rpte_to_hidx(rpte, subpg_index);
> + if (hidx & _PTEIDX_SECONDARY)
> + hash = ~hash;
> + slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
> + slot += hidx & _PTEIDX_GROUP_IX;
> +
> + ret = ppc_md.hpte_updatepp(slot, rflags, vpn,
> + MMU_PAGE_4K, MMU_PAGE_4K,
> + ssize, flags);
> + /*
> + *if we failed because typically the HPTE wasn't
> really here
> + * we try an insertion.
> + */
> + if (ret == -1)
> + goto htab_insert_hpte;
> +
> + *ptep = __pte(new_pte & ~_PAGE_BUSY);
> + return 0;
> + }
> +
> +htab_insert_hpte:
> + /*
> + * handle _PAGE_4K_PFN case
> + */
> + if (old_pte & _PAGE_4K_PFN) {
> + /*
> + * All the sub 4k page have the same
> + * physical address.
> + */
> + pa = pte_pfn(__pte(old_pte)) << HW_PAGE_SHIFT;
> + } else {
> + pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
> + pa += (subpg_index << shift);
> + }
> + hash = hpt_hash(vpn, shift, ssize);
> +repeat:
> + hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) &
> ~0x7UL;
> +
> + /* Insert into the hash table, primary slot */
> + slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
> + MMU_PAGE_4K, MMU_PAGE_4K, ssize);
> + /*
> + * Primary is full, try the secondary
> + */
> + if (unlikely(slot == -1)) {
> + hpte_group = ((~hash & htab_hash_mask) *
> HPTES_PER_GROUP) & ~0x7UL;
> + slot = ppc_md.hpte_insert(hpte_group, vpn, pa,
> + rflags, HPTE_V_SECONDARY,
> + MMU_PAGE_4K, MMU_PAGE_4K,
> ssize);
> + if (slot == -1) {
> + if (mftb() & 0x1)
> + hpte_group = ((hash &
> htab_hash_mask) *
> + HPTES_PER_GROUP) &
> ~0x7UL;
> + ppc_md.hpte_remove(hpte_group);
> + /*
> + * FIXME!! Should be try the group from
> which we removed ?
> + */
> + goto repeat;
> + }
> + }
> + /*
> + * Hypervisor failure. Restore old pmd and return -1
> + * similar to __hash_page_*
> + */
> + if (unlikely(slot == -2)) {
> + *ptep = __pte(old_pte);
> + hash_failure_debug(ea, access, vsid, trap, ssize,
> + MMU_PAGE_4K, MMU_PAGE_4K,
> old_pte);
> + return -1;
> + }
> + /*
> + * Insert slot number & secondary bit in PTE second half,
> + * clear _PAGE_BUSY and set appropriate HPTE slot bit
> + * Since we have _PAGE_BUSY set on ptep, we can be sure
> + * nobody is undating hidx.
> + */
> + hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
> + /* __real_pte use pte_val() any idea why ? FIXME!! */
> + rpte.hidx &= ~(0xfUL << (subpg_index << 2));
> + *hidxp = rpte.hidx | (slot << (subpg_index << 2));
> + new_pte |= (_PAGE_HPTE_SUB0 >> subpg_index);
> + /*
> + * check __real_pte for details on matching smp_rmb()
> + */
> + smp_wmb();
> + *ptep = __pte(new_pte & ~_PAGE_BUSY);
> + return 0;
> +}
> diff --git a/arch/powerpc/mm/hash_low_64.S
> b/arch/powerpc/mm/hash_low_64.S
> index 3b49e3295901..6b4d4c1d0628 100644
> --- a/arch/powerpc/mm/hash_low_64.S
> +++ b/arch/powerpc/mm/hash_low_64.S
> @@ -328,381 +328,8 @@ htab_pte_insert_failure:
> li r3,-1
> b htab_bail
>
> -
> #else /* CONFIG_PPC_64K_PAGES */
>
> -
> -/*******************************************************************
> **********
> - *
> *
> - * 64K SW & 4K or 64K HW in a 4K segment pages
> implementation *
> - *
> *
> -
> *********************************************************************
> ********/
> -
> -/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned
> long vsid,
> - * pte_t *ptep, unsigned long trap, unsigned local
> flags,
> - * int ssize, int subpg_prot)
> - */
> -
> -/*
> - * For now, we do NOT implement Admixed pages
> - */
> -_GLOBAL(__hash_page_4K)
> - mflr r0
> - std r0,16(r1)
> - stdu r1,-STACKFRAMESIZE(r1)
> - /* Save all params that we need after a function call */
> - std r6,STK_PARAM(R6)(r1)
> - std r8,STK_PARAM(R8)(r1)
> - std r9,STK_PARAM(R9)(r1)
> -
> - /* Save non-volatile registers.
> - * r31 will hold "old PTE"
> - * r30 is "new PTE"
> - * r29 is vpn
> - * r28 is a hash value
> - * r27 is hashtab mask (maybe dynamic patched instead ?)
> - * r26 is the hidx mask
> - * r25 is the index in combo page
> - */
> - std r25,STK_REG(R25)(r1)
> - std r26,STK_REG(R26)(r1)
> - std r27,STK_REG(R27)(r1)
> - std r28,STK_REG(R28)(r1)
> - std r29,STK_REG(R29)(r1)
> - std r30,STK_REG(R30)(r1)
> - std r31,STK_REG(R31)(r1)
> -
> - /* Step 1:
> - *
> - * Check permissions, atomically mark the linux PTE busy
> - * and hashed.
> - */
> -1:
> - ldarx r31,0,r6
> - /* Check access rights (access & ~(pte_val(*ptep))) */
> - andc. r0,r4,r31
> - bne- htab_wrong_access
> - /* Check if PTE is busy */
> - andi. r0,r31,_PAGE_BUSY
> - /* If so, just bail out and refault if needed. Someone else
> - * is changing this PTE anyway and might hash it.
> - */
> - bne- htab_bail_ok
> - /* Prepare new PTE value (turn access RW into DIRTY, then
> - * add BUSY and ACCESSED)
> - */
> - rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW ->
> _PAGE_DIRTY */
> - or r30,r30,r31
> - ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED
> - oris r30,r30,_PAGE_COMBO at h
> - /* Write the linux PTE atomically (setting busy) */
> - stdcx. r30,0,r6
> - bne- 1b
> - isync
> -
> - /* Step 2:
> - *
> - * Insert/Update the HPTE in the hash table. At this point,
> - * r4 (access) is re-useable, we use it for the new HPTE
> flags
> - */
> -
> - /* Load the hidx index */
> - rldicl r25,r3,64-12,60
> -
> -BEGIN_FTR_SECTION
> - cmpdi r9,0 /* check segment
> size */
> - bne 3f
> -END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
> - /* Calc vpn and put it in r29 */
> - sldi r29,r5,SID_SHIFT - VPN_SHIFT
> - /*
> - * clrldi r3,r3,64 - SID_SHIFT --> ea & 0xfffffff
> - * srdi r28,r3,VPN_SHIFT
> - */
> - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
> - or r29,r28,r29
> - /*
> - * Calculate hash value for primary slot and store it in r28
> - * r3 = va, r5 = vsid
> - * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
> - */
> - rldicl r0,r3,64-12,48
> - xor r28,r5,r0 /* hash */
> - b 4f
> -
> -3: /* Calc vpn and put it in r29 */
> - sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
> - /*
> - * clrldi r3,r3,64 - SID_SHIFT_1T --> ea & 0xffffffffff
> - * srdi r28,r3,VPN_SHIFT
> - */
> - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T -
> VPN_SHIFT)
> - or r29,r28,r29
> -
> - /*
> - * Calculate hash value for primary slot and
> - * store it in r28 for 1T segment
> - * r3 = va, r5 = vsid
> - */
> - sldi r28,r5,25 /* vsid << 25 */
> - /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
> - rldicl r0,r3,64-12,36
> - xor r28,r28,r5 /* vsid ^ ( vsid << 25)
> */
> - xor r28,r28,r0 /* hash */
> -
> - /* Convert linux PTE bits into HW equivalents */
> -4:
> -#ifdef CONFIG_PPC_SUBPAGE_PROT
> - andc r10,r30,r10
> - andi. r3,r10,0x1fe /* Get basic set of
> flags */
> - rlwinm r0,r10,32-9+1,30,30 /* _PAGE_RW ->
> _PAGE_USER (r0) */
> -#else
> - andi. r3,r30,0x1fe /* Get basic set of
> flags */
> - rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW ->
> _PAGE_USER (r0) */
> -#endif
> - xori r3,r3,HPTE_R_N /* _PAGE_EXEC ->
> NOEXEC */
> - rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY ->
> _PAGE_USER (r4) */
> - and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY
> ->r0 bit 30*/
> - andc r0,r3,r0 /* r0 = pte & ~r0 */
> - rlwimi r3,r0,32-1,31,31 /* Insert result into
> PP lsb */
> - /*
> - * Always add "C" bit for perf. Memory coherence is always
> enabled
> - */
> - ori r3,r3,HPTE_R_C | HPTE_R_M
> -
> - /* We eventually do the icache sync here (maybe inline that
> - * code rather than call a C function...)
> - */
> -BEGIN_FTR_SECTION
> - mr r4,r30
> - mr r5,r7
> - bl hash_page_do_lazy_icache
> -END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE,
> CPU_FTR_NOEXECUTE)
> -
> - /* At this point, r3 contains new PP bits, save them in
> - * place of "access" in the param area (sic)
> - */
> - std r3,STK_PARAM(R4)(r1)
> -
> - /* Get htab_hash_mask */
> - ld r4,htab_hash_mask at got(2)
> - ld r27,0(r4) /* htab_hash_mask -> r27 */
> -
> - /* Check if we may already be in the hashtable, in this
> case, we
> - * go to out-of-line code to try to modify the HPTE. We look
> for
> - * the bit at (1 >> (index + 32))
> - */
> - rldicl. r0,r31,64-12,48
> - li r26,0 /* Default hidx */
> - beq htab_insert_pte
> -
> - /*
> - * Check if the pte was already inserted into the hash table
> - * as a 64k HW page, and invalidate the 64k HPTE if so.
> - */
> - andis. r0,r31,_PAGE_COMBO at h
> - beq htab_inval_old_hpte
> -
> - ld r6,STK_PARAM(R6)(r1)
> - ori r26,r6,PTE_PAGE_HIDX_OFFSET /* Load the hidx
> mask. */
> - ld r26,0(r26)
> - addi r5,r25,36 /* Check actual
> HPTE_SUB bit, this */
> - rldcr. r0,r31,r5,0 /* must match
> pgtable.h definition */
> - bne htab_modify_pte
> -
> -htab_insert_pte:
> - /* real page number in r5, PTE RPN value + index */
> - andis. r0,r31,_PAGE_4K_PFN at h
> - srdi r5,r31,PTE_RPN_SHIFT
> - bne- htab_special_pfn
> - sldi r5,r5,PAGE_FACTOR
> - add r5,r5,r25
> -htab_special_pfn:
> - sldi r5,r5,HW_PAGE_SHIFT
> -
> - /* Calculate primary group hash */
> - and r0,r28,r27
> - rldicr r3,r0,3,63-3 /* r0 = (hash &
> mask) << 3 */
> -
> - /* Call ppc_md.hpte_insert */
> - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp
> bits */
> - mr r4,r29 /* Retrieve vpn */
> - li r7,0 /* !bolted, !secondary
> */
> - li r8,MMU_PAGE_4K /* page size */
> - li r9,MMU_PAGE_4K /* actual page size
> */
> - ld r10,STK_PARAM(R9)(r1) /* segment size */
> -.globl htab_call_hpte_insert1
> -htab_call_hpte_insert1:
> - bl . /* patched by
> htab_finish_init() */
> - cmpdi 0,r3,0
> - bge htab_pte_insert_ok /* Insertion successful
> */
> - cmpdi 0,r3,-2 /* Critical
> failure */
> - beq- htab_pte_insert_failure
> -
> - /* Now try secondary slot */
> -
> - /* real page number in r5, PTE RPN value + index */
> - andis. r0,r31,_PAGE_4K_PFN at h
> - srdi r5,r31,PTE_RPN_SHIFT
> - bne- 3f
> - sldi r5,r5,PAGE_FACTOR
> - add r5,r5,r25
> -3: sldi r5,r5,HW_PAGE_SHIFT
> -
> - /* Calculate secondary group hash */
> - andc r0,r27,r28
> - rldicr r3,r0,3,63-3 /* r0 = (~hash &
> mask) << 3 */
> -
> - /* Call ppc_md.hpte_insert */
> - ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp
> bits */
> - mr r4,r29 /* Retrieve vpn */
> - li r7,HPTE_V_SECONDARY /* !bolted, secondary
> */
> - li r8,MMU_PAGE_4K /* page size */
> - li r9,MMU_PAGE_4K /* actual page size
> */
> - ld r10,STK_PARAM(R9)(r1) /* segment size */
> -.globl htab_call_hpte_insert2
> -htab_call_hpte_insert2:
> - bl . /* patched by
> htab_finish_init() */
> - cmpdi 0,r3,0
> - bge+ htab_pte_insert_ok /* Insertion
> successful */
> - cmpdi 0,r3,-2 /* Critical
> failure */
> - beq- htab_pte_insert_failure
> -
> - /* Both are full, we need to evict something */
> - mftb r0
> - /* Pick a random group based on TB */
> - andi. r0,r0,1
> - mr r5,r28
> - bne 2f
> - not r5,r5
> -2: and r0,r5,r27
> - rldicr r3,r0,3,63-3 /* r0 = (hash &
> mask) << 3 */
> - /* Call ppc_md.hpte_remove */
> -.globl htab_call_hpte_remove
> -htab_call_hpte_remove:
> - bl . /* patched by
> htab_finish_init() */
> -
> - /* Try all again */
> - b htab_insert_pte
> -
> - /*
> - * Call out to C code to invalidate an 64k HW HPTE that is
> - * useless now that the segment has been switched to 4k
> pages.
> - */
> -htab_inval_old_hpte:
> - mr r3,r29 /* vpn */
> - mr r4,r31 /* PTE.pte */
> - li r5,0 /* PTE.hidx */
> - li r6,MMU_PAGE_64K /* psize */
> - ld r7,STK_PARAM(R9)(r1) /* ssize */
> - ld r8,STK_PARAM(R8)(r1) /* flags */
> - bl flush_hash_page
> - /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */
> - lis r0,_PAGE_HPTE_SUB at h
> - ori r0,r0,_PAGE_HPTE_SUB at l
> - andc r30,r30,r0
> - b htab_insert_pte
> -
> -htab_bail_ok:
> - li r3,0
> - b htab_bail
> -
> -htab_pte_insert_ok:
> - /* Insert slot number & secondary bit in PTE second half,
> - * clear _PAGE_BUSY and set approriate HPTE slot bit
> - */
> - ld r6,STK_PARAM(R6)(r1)
> - li r0,_PAGE_BUSY
> - andc r30,r30,r0
> - /* HPTE SUB bit */
> - li r0,1
> - subfic r5,r25,27 /* Must match bit
> position in */
> - sld r0,r0,r5 /* pgtable.h */
> - or r30,r30,r0
> - /* hindx */
> - sldi r5,r25,2
> - sld r3,r3,r5
> - li r4,0xf
> - sld r4,r4,r5
> - andc r26,r26,r4
> - or r26,r26,r3
> - ori r5,r6,PTE_PAGE_HIDX_OFFSET
> - std r26,0(r5)
> - lwsync
> - std r30,0(r6)
> - li r3, 0
> -htab_bail:
> - ld r25,STK_REG(R25)(r1)
> - ld r26,STK_REG(R26)(r1)
> - ld r27,STK_REG(R27)(r1)
> - ld r28,STK_REG(R28)(r1)
> - ld r29,STK_REG(R29)(r1)
> - ld r30,STK_REG(R30)(r1)
> - ld r31,STK_REG(R31)(r1)
> - addi r1,r1,STACKFRAMESIZE
> - ld r0,16(r1)
> - mtlr r0
> - blr
> -
> -htab_modify_pte:
> - /* Keep PP bits in r4 and slot idx from the PTE around in r3
> */
> - mr r4,r3
> - sldi r5,r25,2
> - srd r3,r26,r5
> -
> - /* Secondary group ? if yes, get a inverted hash value */
> - mr r5,r28
> - andi. r0,r3,0x8 /* page secondary ? */
> - beq 1f
> - not r5,r5
> -1: andi. r3,r3,0x7 /* extract idx alone */
> -
> - /* Calculate proper slot value for ppc_md.hpte_updatepp */
> - and r0,r5,r27
> - rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3
> */
> - add r3,r0,r3 /* add slot idx */
> -
> - /* Call ppc_md.hpte_updatepp */
> - mr r5,r29 /* vpn */
> - li r6,MMU_PAGE_4K /* base page size */
> - li r7,MMU_PAGE_4K /* actual page size
> */
> - ld r8,STK_PARAM(R9)(r1) /* segment size */
> - ld r9,STK_PARAM(R8)(r1) /* get "flags" param
> */
> -.globl htab_call_hpte_updatepp
> -htab_call_hpte_updatepp:
> - bl . /* patched by
> htab_finish_init() */
> -
> - /* if we failed because typically the HPTE wasn't really
> here
> - * we try an insertion.
> - */
> - cmpdi 0,r3,-1
> - beq- htab_insert_pte
> -
> - /* Clear the BUSY bit and Write out the PTE */
> - li r0,_PAGE_BUSY
> - andc r30,r30,r0
> - ld r6,STK_PARAM(R6)(r1)
> - std r30,0(r6)
> - li r3,0
> - b htab_bail
> -
> -htab_wrong_access:
> - /* Bail out clearing reservation */
> - stdcx. r31,0,r6
> - li r3,1
> - b htab_bail
> -
> -htab_pte_insert_failure:
> - /* Bail out restoring old PTE */
> - ld r6,STK_PARAM(R6)(r1)
> - std r31,0(r6)
> - li r3,-1
> - b htab_bail
> -
> -#endif /* CONFIG_PPC_64K_PAGES */
> -
> -#ifdef CONFIG_PPC_64K_PAGES
> -
> /*******************************************************************
> **********
> *
> *
> * 64K SW & 64K HW in a 64K segment pages implementation
> *
> @@ -994,10 +621,3 @@ ht64_pte_insert_failure:
>
>
> #endif /* CONFIG_PPC_64K_PAGES */
> -
> -
> -/*******************************************************************
> **********
> - *
> *
> - * Huge pages implementation is in hugetlbpage.c
> *
> - *
> *
> -
> *********************************************************************
> ********/
> diff --git a/arch/powerpc/mm/hash_utils_64.c
> b/arch/powerpc/mm/hash_utils_64.c
> index aee70171355b..67e1fe696ae5 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -653,7 +653,7 @@ static void __init htab_finish_init(void)
> patch_branch(ht64_call_hpte_updatepp,
> ppc_function_entry(ppc_md.hpte_updatepp),
> BRANCH_SET_LINK);
> -#endif /* CONFIG_PPC_64K_PAGES */
> +#else /* !CONFIG_PPC_64K_PAGES */
>
> patch_branch(htab_call_hpte_insert1,
> ppc_function_entry(ppc_md.hpte_insert),
> @@ -667,6 +667,8 @@ static void __init htab_finish_init(void)
> patch_branch(htab_call_hpte_updatepp,
> ppc_function_entry(ppc_md.hpte_updatepp),
> BRANCH_SET_LINK);
> +#endif
> +
> }
>
> static void __init htab_initialize(void)
More information about the Linuxppc-dev
mailing list