[PATCH] powerpc: Free a PTE bit on ppc64 with 64K pages
This patch frees a PTE bit when using 64K pages on ppc64. This is done by getting rid of the separate _PAGE_HASHPTE bit. Instead, we just test if any of the 16 sub-page bits is set. For non-combo pages (ie. real 64K pages), we set SUB0 and the location encoding in that field. Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> --- Second version of the patch, fixes the problem with 64K hashing used with 4K base pages. arch/powerpc/mm/hash_low_64.S | 17 ++--- arch/powerpc/mm/hugetlbpage.c |8 +--- include/asm-powerpc/pgtable-4k.h|1 + include/asm-powerpc/pgtable-64k.h | 17 +++-- include/asm-powerpc/pgtable-ppc64.h |1 - 5 files changed, 31 insertions(+), 13 deletions(-) --- linux-work.orig/arch/powerpc/mm/hash_low_64.S 2008-03-19 13:52:26.0 +1100 +++ linux-work/arch/powerpc/mm/hash_low_64.S2008-06-11 14:34:03.0 +1000 @@ -388,7 +388,7 @@ _GLOBAL(__hash_page_4K) */ 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 | _PAGE_HASHPTE + ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED orisr30,r30,[EMAIL PROTECTED] /* Write the linux PTE atomically (setting busy) */ stdcx. r30,0,r6 @@ -468,7 +468,7 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FT * go to out-of-line code to try to modify the HPTE. We look for * the bit at (1 >> (index + 32)) */ - andi. r0,r31,_PAGE_HASHPTE + rldicl. r0,r31,64-12,48 li r26,0 /* Default hidx */ beq htab_insert_pte @@ -722,11 +722,11 @@ BEGIN_FTR_SECTION bne-ht64_bail_ok END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE) /* Prepare new PTE value (turn access RW into DIRTY, then -* add BUSY,HASHPTE and ACCESSED) +* 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 | _PAGE_HASHPTE + ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED /* Write the linux PTE atomically (setting busy) */ stdcx. r30,0,r6 bne-1b @@ -794,18 +794,21 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FT /* 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 */ - andi. r0,r31,_PAGE_HASHPTE + rldicl. r0,r31,64-12,48 bne ht64_modify_pte ht64_insert_pte: /* Clear hpte bits in new pte (we also clear BUSY btw) and -* add _PAGE_HASHPTE +* add _PAGE_HPTE_SUB0 */ lis r0,[EMAIL PROTECTED] ori r0,r0,[EMAIL PROTECTED] andcr30,r30,r0 +#ifdef CONFIG_PPC_64K_PAGES + orisr30,r30,[EMAIL PROTECTED] +#else ori r30,r30,_PAGE_HASHPTE - +#endif /* Phyical address in r5 */ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT sldir5,r5,PAGE_SHIFT Index: linux-work/arch/powerpc/mm/hugetlbpage.c === --- linux-work.orig/arch/powerpc/mm/hugetlbpage.c 2008-03-19 13:52:26.0 +1100 +++ linux-work/arch/powerpc/mm/hugetlbpage.c2008-06-11 14:34:03.0 +1000 @@ -458,8 +458,7 @@ int hash_huge_page(struct mm_struct *mm, old_pte = pte_val(*ptep); if (old_pte & _PAGE_BUSY) goto out; - new_pte = old_pte | _PAGE_BUSY | - _PAGE_ACCESSED | _PAGE_HASHPTE; + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; } while(old_pte != __cmpxchg_u64((unsigned long *)ptep, old_pte, new_pte)); @@ -499,8 +498,11 @@ repeat: HPTES_PER_GROUP) & ~0x7UL; /* clear HPTE slot informations in new PTE */ +#ifdef CONFIG_PPC_64K_PAGES + new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0; +#else new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE; - +#endif /* Add in WIMG bits */ /* XXX We should store these in the pte */ /* --BenH: I think they are ... */ Index: linux-work/include/asm-powerpc/pgtable-4k.h === --- linux-work.orig/include/asm-powerpc/pgtable-4k.h2008-03-03 11:58:57.0 +1100 +++ linux-work/include/asm-powerpc/pgtable-4k.h 2008-06-11 14:34:03.0 +1000 @@ -41,6 +41,7 @@ #define PGDIR_MASK (~(PGDIR_SIZE-1)) /* PTE bits */ +#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */ #define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */ #define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */ #define _PAGE_F_SECOND _PAGE_SECONDARY Index:
Re: [PATCH] [POWERPC] Free a PTE bit on ppc64 with 64K pages
On Tue, 2008-06-10 at 14:00 +1000, Michael Ellerman wrote: > > This doesn't build for CONFIG_PPC_64K_PAGES=n and > CONFIG_PPC_HAS_HASH_64K=y, because the asm is protected by the latter > but the header definitions are protected by the former. Crap ! This is going to be nasty... I have to think about it Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] [POWERPC] Free a PTE bit on ppc64 with 64K pages
On Thu, 2008-05-29 at 15:51 +1000, Benjamin Herrenschmidt wrote: > This patch frees a PTE bit when using 64K pages on ppc64. This is done > by getting rid of the separate _PAGE_HASHPTE bit. Instead, we just test > if any of the 16 sub-page bits is set. For non-combo pages (ie. real > 64K pages), we set SUB0 and the location encoding in that field. > > Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> > --- > > Please review and make sure I didn't miss something ... This doesn't build for CONFIG_PPC_64K_PAGES=n and CONFIG_PPC_HAS_HASH_64K=y, because the asm is protected by the latter but the header definitions are protected by the former. cheers -- Michael Ellerman OzLabs, IBM Australia Development Lab wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person signature.asc Description: This is a digitally signed message part ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH] [POWERPC] Free a PTE bit on ppc64 with 64K pages
This patch frees a PTE bit when using 64K pages on ppc64. This is done by getting rid of the separate _PAGE_HASHPTE bit. Instead, we just test if any of the 16 sub-page bits is set. For non-combo pages (ie. real 64K pages), we set SUB0 and the location encoding in that field. Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> --- Please review and make sure I didn't miss something ... The freed bit is intended to be used as _PAGE_SPECIAL in order to support fast get_user_pages(). Test booted with 64K pages on G5, power5 and power6 arch/powerpc/mm/hash_low_64.S | 12 ++-- arch/powerpc/mm/hugetlbpage.c |5 ++--- include/asm-powerpc/pgtable-4k.h|2 ++ include/asm-powerpc/pgtable-64k.h | 18 -- include/asm-powerpc/pgtable-ppc64.h |1 - 5 files changed, 26 insertions(+), 12 deletions(-) --- linux-work.orig/arch/powerpc/mm/hash_low_64.S 2008-05-29 12:10:47.0 +1000 +++ linux-work/arch/powerpc/mm/hash_low_64.S2008-05-29 12:56:16.0 +1000 @@ -388,7 +388,7 @@ _GLOBAL(__hash_page_4K) */ 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 | _PAGE_HASHPTE + ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED orisr30,r30,[EMAIL PROTECTED] /* Write the linux PTE atomically (setting busy) */ stdcx. r30,0,r6 @@ -468,7 +468,7 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FT * go to out-of-line code to try to modify the HPTE. We look for * the bit at (1 >> (index + 32)) */ - andi. r0,r31,_PAGE_HASHPTE + rldicl. r0,r31,64-12,48 li r26,0 /* Default hidx */ beq htab_insert_pte @@ -726,7 +726,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_P */ 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 | _PAGE_HASHPTE + ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED /* Write the linux PTE atomically (setting busy) */ stdcx. r30,0,r6 bne-1b @@ -794,17 +794,17 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FT /* 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 */ - andi. r0,r31,_PAGE_HASHPTE + rldicl. r0,r31,64-12,48 bne ht64_modify_pte ht64_insert_pte: /* Clear hpte bits in new pte (we also clear BUSY btw) and -* add _PAGE_HASHPTE +* add _PAGE_HPTE_SUB0 */ lis r0,[EMAIL PROTECTED] ori r0,r0,[EMAIL PROTECTED] andcr30,r30,r0 - ori r30,r30,_PAGE_HASHPTE + orisr30,r30,[EMAIL PROTECTED] /* Phyical address in r5 */ rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT Index: linux-work/arch/powerpc/mm/hugetlbpage.c === --- linux-work.orig/arch/powerpc/mm/hugetlbpage.c 2008-05-29 12:16:25.0 +1000 +++ linux-work/arch/powerpc/mm/hugetlbpage.c2008-05-29 12:18:51.0 +1000 @@ -458,8 +458,7 @@ int hash_huge_page(struct mm_struct *mm, old_pte = pte_val(*ptep); if (old_pte & _PAGE_BUSY) goto out; - new_pte = old_pte | _PAGE_BUSY | - _PAGE_ACCESSED | _PAGE_HASHPTE; + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; } while(old_pte != __cmpxchg_u64((unsigned long *)ptep, old_pte, new_pte)); @@ -499,7 +498,7 @@ repeat: HPTES_PER_GROUP) & ~0x7UL; /* clear HPTE slot informations in new PTE */ - new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE; + new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HUGE_HPTE; /* Add in WIMG bits */ /* XXX We should store these in the pte */ Index: linux-work/include/asm-powerpc/pgtable-4k.h === --- linux-work.orig/include/asm-powerpc/pgtable-4k.h2008-05-29 12:07:09.0 +1000 +++ linux-work/include/asm-powerpc/pgtable-4k.h 2008-05-29 12:17:36.0 +1000 @@ -41,6 +41,8 @@ #define PGDIR_MASK (~(PGDIR_SIZE-1)) /* PTE bits */ +#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */ +#define _PAGE_HUGE_HPTE_PAGE_HASHPTE #define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */ #define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */ #define _PAGE_F_SECOND _PAGE_SECONDARY Index: linux-work/include/asm-powerpc/pgtable-64k.h === --- linux-work.orig/include/asm-powerpc/pgtable-64k.h 2008-05-29 12:06:37.0 +1000 +++