powerpc: add 16K/64K pages support for the 44x PPC32 architectures.
PATCH 1/1 powerpc: add 16K/64K pages support for the 44x PPC32 architectures.
This patch adds support for page sizes bigger than 4K (16K/64K) on PPC 44x.
PGDIR table is much smaller than page in case of 16K/64K pages (512 and 32 bytes resp.) so we allocate PGDIR with kzalloc() instead of __get_free_pages().
PTE table covers rather big memory area in case of 16K/64K pages (32MB and 512MB resp.) so we can easily put FIXMAP and PKMAP in area covered by one PTE table.
--- arch/powerpc/Kconfig | 54 ++++++++++++++++++++++++------- arch/powerpc/include/asm/highmem.h | 15 ++++++++- arch/powerpc/include/asm/mmu-44x.h | 18 ++++++++++ arch/powerpc/include/asm/page.h | 13 +++++--- arch/powerpc/include/asm/page_32.h | 3 +- arch/powerpc/include/asm/pgtable.h | 2 + arch/powerpc/kernel/asm-offsets.c | 4 ++ arch/powerpc/kernel/head_44x.S | 22 ++++++++----- arch/powerpc/kernel/misc_32.S | 12 +++--- arch/powerpc/mm/pgtable_32.c | 13 ++----- arch/powerpc/platforms/Kconfig.cputype | 2 +- 11 files changed, 112 insertions(+), 46 deletions(-)
arch/powerpc/Kconfig +42 -12
@@ -401,23 +401,53 @@ config PPC_HAS_HASH_64K depends on PPC64 default n -config PPC_64K_PAGES - bool "64k page size" - depends on PPC64 - select PPC_HAS_HASH_64K +choice + prompt "Page size" + default PPC_4K_PAGES help - This option changes the kernel logical page size to 64k. On machines - without processor support for 64k pages, the kernel will simulate - them by loading each individual 4k page on demand transparently, - while on hardware with such support, it will be used to map - normal application pages. + Select the kernel logical page size. Increasing the page size + will reduce software overhead at each page boundary, allow + hardware prefetch mechanisms to be more effective, and allow + larger dma transfers increasing IO efficiency and reducing + overhead. However the utilization of memory will increase. + For example, each cached file will using a multiple of the + page size to hold its contents and the difference between the + end of file and the end of page is wasted. + + Some dedicated systems, such as software raid serving with + accelerated calculations, have shown significant increases. + + If you configure a 64 bit kernel for 64k pages but the + processor does not support them, then the kernel will simulate + them with 4k pages, loading them on demand, but with the + reduced software overhead and larger internal fragmentation. + For the 32 bit kernel, a large page option will not be offered + unless it is supported by the configured processor. + + If unsure, choose 4K_PAGES. + +config PPC_4K_PAGES + bool "4k page size" + +config PPC_16K_PAGES + bool "16k page size" if 44x + +config PPC_64K_PAGES + bool "64k page size" if 44x || PPC64 + select PPC_HAS_HASH_64K if PPC64 + +endchoice config FORCE_MAX_ZONEORDER int "Maximum zone order" - range 9 64 if PPC_64K_PAGES - default "9" if PPC_64K_PAGES + range 9 64 if PPC64 && PPC_64K_PAGES + default "9" if PPC64 && PPC_64K_PAGES range 13 64 if PPC64 && !PPC_64K_PAGES default "13" if PPC64 && !PPC_64K_PAGES + range 9 64 if PPC32 && PPC_16K_PAGES + default "9" if PPC32 && PPC_16K_PAGES + range 7 64 if PPC32 && PPC_64K_PAGES + default "7" if PPC32 && PPC_64K_PAGES range 11 64 default "11" help
@@ -437,7 +467,7 @@ config FORCE_MAX_ZONEORDER config PPC_SUBPAGE_PROT bool "Support setting protections for 4k subpages" - depends on PPC_64K_PAGES + depends on PPC64 && PPC_64K_PAGES help This option adds support for a system call to allow user programs to set access permissions (read/write, readonly, or no access)
arch/powerpc/include/asm/highmem.h +13 -2
@@ -38,9 +38,20 @@ extern pte_t *pkmap_page_table;* easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#define LAST_PKMAP (1 << PTE_SHIFT) -#define LAST_PKMAP_MASK (LAST_PKMAP-1) +/* +* We use one full pte table with 4K pages. And with 16K/64K pages pte +* table covers enough memory (32MB and 512MB resp.) that both FIXMAP +* and PKMAP can be placed in single pte table. We use 1024 pages for +* PKMAP in case of 16K/64K pages. +*/ +#define PKMAP_ORDER min(PTE_SHIFT, 10) +#define LAST_PKMAP (1 << PKMAP_ORDER) +#if !defined(CONFIG_PPC_4K_PAGES ) +#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) +#else #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) +#endif +#define LAST_PKMAP_MASK (LAST_PKMAP-1)#define PKMAP_NR (virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)#define PKMAP_ADDR (nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
arch/powerpc/include/asm/mmu-44x.h +18 -0
@@ -4,6 +4,8 @@* PPC440 support */ +#include <asm/page.h> +#define PPC44x_MMUCR_TID 0x000000ff#define PPC44x_MMUCR_STS 0x00010000
@@ -73,4 +75,20 @@ typedef struct {/* Size of the TLBs used for pinning in lowmem */ #define PPC_PIN_SIZE (1 << 28)/* 256M */ +#if (PAGE_SHIFT ==12 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_4K +#elif (PAGE_SHIFT ==14 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_16K +#elif (PAGE_SHIFT ==16 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_64K +#else +#error "Unsupported PAGE_SIZE" +#endif + +#define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2) +#define PPC44x_PGD_OFF_MASK (PGDIR_SHIFT - PGD_T_LOG2) +#define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2) +#define PPC44x_PTE_ADD_MASK (32 - PTE_T_LOG2 - PTE_SHIFT) +#define PPC44x_RPN_MASK (31 - PAGE_SHIFT) +#endif /* _ASM_POWERPC_MMU_44X_H_ */
arch/powerpc/include/asm/page.h +8 -5
@@ -19,12 +19,15 @@#include <asm/kdump.h> /* -* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software +* On regular PPC32 page size is 4K (but we support 4K/16K/64K pages +* on PPC44x). For PPC64 we support either 4K or 64K software * page size. When using 64K pages however, whether we are really supporting * 64K pages in HW or not is irrelevant to those definitions. */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES )#define PAGE_SHIFT 16 +#elif defined(CONFIG_PPC_16K_PAGES ) +#define PAGE_SHIFT 14#else #define PAGE_SHIFT 12#endif
@@ -151,7 +154,7 @@ typedef struct { pte_basic_t pte; } pte_t;/* 64k pages additionally define a bigger "real PTE" type that gathers * the "second half" part of the PTE for pseudo 64k pages */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else typedef struct {pte_t pte; }real_pte_t ;
@@ -191,10 +194,10 @@ typedef pte_basic_t pte_t;#define pte_val (x) (x)#define __pte (x) (x) -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else -typedef unsigned long real_pte_t ; +typedef pte_t real_pte_t ;#endif
arch/powerpc/include/asm/page_32.h +1 -2
@@ -19,6 +19,7 @@#define PTE_FLAGS_OFFSET 0#endif +#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2)/* full page */ #ifndef __ASSEMBLY__/* * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
@@ -26,10 +27,8 @@*/ #ifdef CONFIG_PTE_64BIT typedef unsigned long long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 3)/* 512 ptes per page */ #else typedef unsigned long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 2)/* 1024 ptes per page */ #endif struct page ;
arch/powerpc/include/asm/pgtable.h +2 -0
@@ -39,6 +39,8 @@ extern void paging_init(void);#include <asm-generic/pgtable.h> +#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) +#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1)/* * This gets called at the end of handling a page fault, when
arch/powerpc/kernel/asm-offsets.c +4 -0
@@ -378,6 +378,10 @@ int main(void) DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));#endif +#ifdef CONFIG_44x +DEFINE (PGD_T_LOG2 ,PGD_T_LOG2 ); +DEFINE (PTE_T_LOG2 ,PTE_T_LOG2 ); +#endif return 0 ; }
arch/powerpc/kernel/head_44x.S +13 -9
@@ -391,12 +391,14 @@ interrupt_base: rlwimi r13,r12,10,30,30 /* Load the PTE */ - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */
@@ -485,12 +487,14 @@ tlb_44x_patch_hwater_D: /* Make up the required permissions */ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */
@@ -554,15 +558,15 @@ tlb_44x_patch_hwater_I: */ finish_tlb_load: /* Combine RPN & ERPN an write WS 0 */ - rlwimi r11,r12,0,0,19 + rlwimi r11,r12,0,0,PPC44x_RPN_MASK tlbwe r11,r13,PPC44x_TLB_XLAT /* * Create WS1. This is the faulting address (EPN), * page size, and valid flag. */ - li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K - rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ + li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE + rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK,31/* Insert valid and page size*/ tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ /* And WS 2 */
@@ -634,12 +638,12 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data - .align 12 + .align PAGE_SHIFT .globl sdata sdata: .globl empty_zero_page empty_zero_page: - .space 4096 + .space PAGE_SIZE /* * To support >32-bit physical addresses, we use an 8KB pgdir.
arch/powerpc/kernel/misc_32.S +6 -6
@@ -647,8 +647,8 @@ _GLOBAL(__flush_dcache_icache) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,PPC44x_RPN_MASK /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */
@@ -688,8 +688,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 isync - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,PPC44x_RPN_MASK /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */
@@ -713,7 +713,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) * void clear_pages(void *page, int order) ; */ _GLOBAL(clear_pages) - li r0,4096/L1_CACHE_BYTES + li r0,PAGE_SIZE/L1_CACHE_BYTES slw r0,r0,r4 mtctr r0 #ifdef CONFIG_8xx
@@ -771,7 +771,7 @@ _GLOBAL(copy_page) dcbt r5,r4 li r11,L1_CACHE_BYTES+4 #endif /* MAX_COPY_PREFETCH */ - li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH + li r0,PAGE_SIZE/L1_CACHE_BYTES - MAX_COPY_PREFETCH crclr 4*cr0+eq 2: mtctr r0
arch/powerpc/mm/pgtable_32.c +4 -9
@@ -72,24 +72,19 @@ extern unsigned long p_mapped_by_tlbcam(unsigned long pa);#define p_mapped_by_tlbcam (x) (0UL)#endif /* HAVE_TLBCAM */ -#ifdef CONFIG_PTE_64BIT -/* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */ -#define PGDIR_ORDER 1 -#else -#define PGDIR_ORDER 0 -#endif +#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)pgd_t *pgd_alloc (struct mm_struct *mm) {pgd_t *ret; - ret = (pgd_t *)__get_free_pages (GFP_KERNEL |__GFP_ZERO,PGDIR_ORDER ); + ret = (pgd_t *)kzalloc (1 <<PGDIR_ORDER ,GFP_KERNEL );return ret; }void pgd_free (struct mm_struct *mm,pgd_t *pgd) { -free_pages ((unsigned long )pgd,PGDIR_ORDER ); +kfree ((void *)pgd); } __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
@@ -400,7 +395,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)#endif /* CONFIG_DEBUG_PAGEALLOC */ static int fixmaps; -unsigned long FIXADDR_TOP =0xfffff000 ; +unsigned long FIXADDR_TOP = (-PAGE_SIZE );EXPORT_SYMBOL (FIXADDR_TOP );void __set_fixmap (enum fixed_addresses idx,phys_addr_t phys,pgprot_t flags)
arch/powerpc/platforms/Kconfig.cputype +1 -1
@@ -204,7 +204,7 @@ config PPC_STD_MMU_32 config PPC_MM_SLICES bool - default y if HUGETLB_PAGE || PPC_64K_PAGES + default y if HUGETLB_PAGE || (PPC64 && PPC_64K_PAGES) default n config VIRT_CPU_ACCOUNTING
Signature · 1 line
1.5.6.1
Quoted 8 lines · Ilya Yanok
This patch adds support for page sizes bigger than 4K (16K/64K) on PPC 44x.
PGDIR table is much smaller than page in case of 16K/64K pages (512 and 32 bytes resp.) so we allocate PGDIR withkzalloc()instead of__get_free_pages().
PTE table covers rather big memory area in case of 16K/64K pages (32MB and 512MB resp.) so we can easily put FIXMAP and PKMAP in area covered by one PTE table.
Ben, you had some comments on the previous version of this patch. Have those been addressed to your satisfaction? If so, could you please queue this for 2.6.29?
-Hollis
Quoted 10 lines · Hollis Blanchard
Quoted 8 lines · Ilya Yanok
This patch adds support for page sizes bigger than 4K (16K/64K) on PPC 44x.
PGDIR table is much smaller than page in case of 16K/64K pages (512 and 32 bytes resp.) so we allocate PGDIR withkzalloc()instead of__get_free_pages().
PTE table covers rather big memory area in case of 16K/64K pages (32MB and 512MB resp.) so we can easily put FIXMAP and PKMAP in area covered by one PTE table.
Quoted 3 lines
Ben, you had some comments on the previous version of this patch. Have those been addressed to your satisfaction? If so, could you please queue this for 2.6.29?
Milton had some comments too. And I'd also like to review it and add and Acked-by since I'll be the one getting bug reports if it's broken :).
I've been sick for the past few days, but this is the first thing to review on my list tomorrow.
josh
Quoted 5 lines · Hollis Blanchard
Ben, you had some comments on the previous version of this patch. Have those been addressed to your satisfaction? If so, could you please queue this for 2.6.29?
From the description, they have, however I haven't had a chance to look
in details at the code yet. I would like to see these in 2.6.29 too though, I'll have a look asap.
Cheers,
Ben.
Hi Ilya !
Looks good overall. A few minor comments.
arch/powerpc/Kconfig config PPC_HAS_HASH_64K · line 437
Quoted 9 lines
arch/powerpc/Kconfig +9
-0+config PPC_4K_PAGES + bool "4k page size" + +config PPC_16K_PAGES + bool "16k page size" if 44x + +config PPC_64K_PAGES + bool "64k page size" if 44x || PPC64 + select PPC_HAS_HASH_64K if PPC64
I'd rather if the PPC64 references were instead PPC_STD_MMU_64 (which may or may not be defined in Kconfig depending on what you are based on, but is trivial to add.
I want to clearly differenciate what is MMU from what CPU architecture and there may (will ... ahem) at some point be 64-bit BookE.
In the same vein, we should probably rework some of the above so that the CPU/MMU type actually defines what page sizes are allowed (PPC_CAN_16K, PPC_CAN_64K, ...) but let's keep that for a later patch.
arch/powerpc/Kconfig config FORCE_MAX_ZONEORDER · line 473
Quoted 7 lines
config
PPC_SUBPAGE_PROTarch/powerpc/Kconfig +1
-1bool "Support setting protections for 4k subpages" - depends on PPC_64K_PAGES + depends on PPC64 && PPC_64K_PAGES help This option adds support for a system call to allow user programs to set access permissions (read/write, readonly, or no access)
Same comment here.
Quoted 13 lines
arch/powerpc/include/asm/highmem.h +3
-2@@ -38,9 +38,20 @@ extern pte_t *pkmap_page_table;* easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#define LAST_PKMAP (1 << PTE_SHIFT) -#define LAST_PKMAP_MASK (LAST_PKMAP-1) +/* +* We use one full pte table with 4K pages. And with 16K/64K pages pte +* table covers enough memory (32MB and 512MB resp.) that both FIXMAP
arch/powerpc/include/asm/highmem.h extern pte_t *pkmap_page_table; · line 53
Quoted 10 lines
arch/powerpc/include/asm/highmem.h +9
-0+* and PKMAP can be placed in single pte table. We use 1024 pages for +* PKMAP in case of 16K/64K pages. +*/ +#define PKMAP_ORDER min(PTE_SHIFT, 10) +#define LAST_PKMAP (1 << PKMAP_ORDER) +#if !defined(CONFIG_PPC_4K_PAGES ) +#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) +#else #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) +#endif
I'm not sure about the above & PMD_MASK. Shouldn't we instead make it not build if (PKMAP_BASE & PMD_MASK) != 0 ? IE, somebody set FIXADDR_START to something wrong... and avoid the ifdef alltogether ? Or am I missing something ? (it's early morning and I may not have all my wits with me right now !)
arch/powerpc/include/asm/highmem.h extern pte_t *pkmap_page_table; · line 56
Quoted 4 lines
arch/powerpc/include/asm/highmem.h +1
-1-#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else
Same comment about using PPC_STD_MMU_64, it's going to make my life easier later on :-) And in various other places, I won't quote them all.
arch/powerpc/include/asm/page_32.h line 23
Quoted 10 lines
arch/powerpc/include/asm/page_32.h +1
-0@@ -19,6 +19,7 @@#define PTE_FLAGS_OFFSET 0#endif +#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2)/* full page */ #ifndef __ASSEMBLY__
Stick a blank line between the two above statements.
Quoted 18 lines
arch/powerpc/include/asm/page_32.h +0
-2/* * The basic type of a PTE - 64 bits for those CPUs with > 32 bit @@ -26,10 +27,8 @@*/ #ifdef CONFIG_PTE_64BIT typedef unsigned long long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 3)/* 512 ptes per page */ #else typedef unsigned long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 2)/* 1024 ptes per page */ #endif struct page ;arch/powerpc/include/asm/pgtable.h +0
-0
arch/powerpc/include/asm/pgtable.h extern void paging_init(void); · line 43
Quoted 5 lines
arch/powerpc/include/asm/pgtable.h +2
-0@@ -39,6 +39,8 @@ extern void paging_init(void);#include <asm-generic/pgtable.h> +#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) +#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1)
I'm surprised the above actually work :-) Why not having these next to the definition of pte_t in page_32.h ?
Also, you end up having to do an asm-offset trick to get those to asm, I wonder if it's worth it or if we aren't better off just #defining the sizes with actual numbers next to the type definitions. No big deal either way.
Quoted 7 lines
arch/powerpc/include/asm/pgtable.h +0
-0/* * To support >32-bit physical addresses, we use an 8KB pgdir. arch/powerpc/kernel/misc_32.S +0
-0
arch/powerpc/kernel/misc_32.S _GLOBAL(__flush_dcache_icache) · line 651
Quoted 7 lines
arch/powerpc/kernel/misc_32.S +2
-2@@ -647,8 +647,8 @@ _GLOBAL(__flush_dcache_icache) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,PPC44x_RPN_MASK /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */
Now, the problem here is the name of the constant. IE. This is more or less generic ppc code and you are using something called "PPC4xx_RPN_MASK", doesn't look right.
I'r rather you do the right arithmetic using PAGE_SHIFT straight in here. In general, those _MASK constants you use aren't really masks, they are bit numbers in PPC notation which is very confusing. Maybe you should call those constants something like
PPC_xxxx_MASK_BIT
Dunno ... it's a bit verbose. But I'm not too happy with that naming at this stage. In any case, the above is definitely wrong in misc_32.S
arch/powerpc/kernel/misc_32.S END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) · line 692
Quoted 11 lines
arch/powerpc/kernel/misc_32.S +2
-2mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */@@ -688,8 +688,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 isync - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,PPC44x_RPN_MASK /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */
Same comment.
arch/powerpc/kernel/misc_32.S END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
Quoted 8 lines
arch/powerpc/kernel/misc_32.S +1
-1pgd_t *pgd_alloc(struct mm_struct *mm) { pgd_t *ret; - ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER); + ret = (pgd_t *)kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); return ret; }
We may want to consider using a slab cache. Maybe an area where we want to merge 32 and 64 bit code, though it doesn't have to be right now.
Do we know the impact of using kzalloc instead of gfp for when it's really just a single page though ? Does it have overhead or will kzalloc just fallback to gfp ? If it has overhead, then we probably want to ifdef and keep using gfp for the 1-page case.
Quoted 15 lines
__init_refokpte_t*pte_alloc_one_kernel(structmm_struct*mm, unsigned long address)arch/powerpc/kernel/misc_32.S +1
-1@@ -400,7 +395,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable) #endif /* CONFIG_DEBUG_PAGEALLOC */ static int fixmaps; -unsigned long FIXADDR_TOP = 0xfffff000; +unsigned long FIXADDR_TOP = (-PAGE_SIZE); EXPORT_SYMBOL(FIXADDR_TOP); void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)arch/powerpc/platforms/Kconfig.cputype +0
-0
arch/powerpc/platforms/Kconfig.cputype config PPC_STD_MMU_32 · line 208
Quoted 6 lines
arch/powerpc/platforms/Kconfig.cputype +1
-1@@ -204,7 +204,7 @@ config PPC_STD_MMU_32 config PPC_MM_SLICES bool - default y if HUGETLB_PAGE || PPC_64K_PAGES + default y if HUGETLB_PAGE || (PPC64 && PPC_64K_PAGES) default n
I would make it PPC_64 && (HUGETLB_PAGE || PPC_64K_PAGES) for now, I don't think we want to use the existing slice code on anything else.
Make it even PPC_STD_MMU_64
Cheers,
Ben.
Hello Ben,
Quoted 18 lines · On Wednesday, December 10, 2008 you wrote:
Hi Ilya !
Looks good overall. A few minor comments.
arch/powerpc/Kconfig config PPC_HAS_HASH_64K · line 437
Quoted 9 lines
arch/powerpc/Kconfig +9
-0+config PPC_4K_PAGES + bool "4k page size" + +config PPC_16K_PAGES + bool "16k page size" if 44x + +config PPC_64K_PAGES + bool "64k page size" if 44x || PPC64 + select PPC_HAS_HASH_64K if PPC64I'd rather if the PPC64 references were instead
PPC_STD_MMU_64(which may or may not be defined inKconfigdepending on what you are based on, but is trivial to add.
Quoted 2 lines
I want to clearly differenciate what is MMU from what CPU architecture and there may (will ... ahem) at some point be 64-bit BookE.
Understood. We'll fix this, and re-post the patch then.
[snip]
Quoted 1 line
arch/powerpc/include/a=
Quoted 1 line
arch/powerpc/include/a= renamed from arch/powerpc/include/asm/highmem.h +0
-0
sm/highmem.h
Quoted 13 lines
Quoted 13 lines
index 91c5895..9875540 100644
arch/powerpc/include/asm/highmem.h +4
-2@@ -38,9 +38,20 @@ extern pte_t *pkmap_page_table;* easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#define LAST_PKMAP (1 << PTE_SHIFT) -#define LAST_PKMAP_MASK (LAST_PKMAP-1) +/* +* We use one full pte table with 4K pages. And with 16K/64K pages pte +* table covers enough memory (32MB and 512MB resp.) that both FIXMAP +* and PKMAP can be placed in single pte table. We use 1024 pages for
Quoted 8 lines
arch/powerpc/include/asm/highmem.h extern pte_t *pkmap_page_table;
Quoted 8 lines
arch/powerpc/include/asm/highmem.h +7
-0+* PKMAP in case of 16K/64K pages. +*/ +#define PKMAP_ORDER min(PTE_SHIFT, 10) +#define LAST_PKMAP (1 << PKMAP_ORDER) +#if !defined(CONFIG_PPC_4K_PAGES ) +#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) +#else #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PM=
D_MASK)
Quoted 4 lines
arch/powerpc/include/asm/highmem.h extern pte_t *pkmap_page_table; · line 53
Quoted 1 line
arch/powerpc/include/asm/highmem.h +1
-0+#endif I'm not sure about the above &
PMD_MASK. Shouldn't we instead make it not build if (PKMAP_BASE&PMD_MASK) !=3D 0 ?=20
We separated the !4K_PAGES case here exactly because (PKMAP_BASE &=20PMD_MASK) !=3D 0 [see the comment to this chunk - why]. So, this'll turn=20 out to be broken if we follow your suggestion. Are there any reasons=20 why we should have PKMAP_BASE aligned on the PMD_SIZE boundary ?
Quoted 4 lines
IE, somebody set
FIXADDR_STARTto something wrong... and avoid the ifdef alltogether ? Or am I missing something ? (it's early morning and I may not have all my wits with me right now !)
[snip]
Quoted 1 line
arch/powerpc/include/a=
Quoted 1 line
arch/powerpc/include/a= renamed from arch/powerpc/include/asm/pgtable.h +0
-0
sm/pgtable.h
Quoted 4 lines
Quoted 4 lines
index dbb8ca1..a202043 100644
arch/powerpc/include/asm/pgtable.h +0
-0@@ -39,6 +39,8 @@ extern void paging_init(void);
Quoted 8 lines
arch/powerpc/include/asm/pgtable.h extern void paging_init(void); · line 43
Quoted 5 lines
=20
#include <asm-generic/pgtable.h>
=20arch/powerpc/include/asm/pgtable.h +2
-0+#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) +#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1)I'm surprised the above actually work :-) Why not having these next to the definition of
pte_tinpage_32.h?
These definitions seem to be related to the page table, so, as for me,=20
then pgtable.h is the better place for them. Though, as you want;=20 we'll move this to page_32.h.
Quoted 2 lines
Also, you end up having to do an asm-offset trick to get those to asm, I wonder if it's worth it or if we aren't better off just #defining the siz=
es
Quoted 4 lines
with actual numbers next to the type definitions. No big deal either way.
arch/powerpc/kernel/misc_32=
Quoted 3 lines
/*
* To support >32-bit physical addresses, we use an 8KB pgdir.arch/powerpc/kernel/misc_32= renamed from arch/powerpc/kernel/misc_32.S +0
-0
.S
Quoted 11 lines
arch/powerpc/kernel/misc_32.S _GLOBAL(__flush_dcache_icache) · line 651
Quoted 11 lines
index bdc8b0e..42f99d2 100644
arch/powerpc/kernel/misc_32.S +2
-2@@ -647,8 +647,8 @@ _GLOBAL(__flush_dcache_icache) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,PPC44x_RPN_MASK /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a pa=
ge */
Quoted 10 lines
Now, the problem here is the name of the constant. IE. This is more or less generic ppc code and you are using something called "
PPC4xx_RPN_MASK", doesn't look right.I'r rather you do the right arithmetic using
PAGE_SHIFTstraight in here. In general, those_MASKconstants you use aren't really masks, they are bit numbers in PPC notation which is very confusing. Maybe you should call those constants something like
PPC_xxxx_MASK_BIT
OK.
Quoted 14 lines
Dunno ... it's a bit verbose. But I'm not too happy with that naming at this stage. In any case, the above is definitely wrong in misc_32.S=20
arch/powerpc/kernel/misc_32.S END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) · line 692
Quoted 11 lines
arch/powerpc/kernel/misc_32.S +2
-2mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */@@ -688,8 +688,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 isync - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,PPC44x_RPN_MASK /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a pa=
ge */
Quoted 7 lines
Same comment.
Quoted 5 lines
arch/powerpc/kernel/misc_32.S +0
-0pgd_t *pgd_alloc(struct mm_struct *mm) { pgd_t *ret;=20
- ret =3D (pgd_t*)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORD=
ER);
Quoted 11 lines
Quoted 3 lines
+ ret =3D (pgd_t *)kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); return ret;}
We may want to consider using a slab cache. Maybe an area where we want to merge 32 and 64 bit code, though it doesn't have to be right now.
Do we know the impact of using kzalloc instead of gfp for when it's really just a single page though ? Does it have overhead or will kzalloc just fallback to gfp ? If it has overhead, then we probably want to ifdef and keep using gfp for the 1-page case.
This depends on allocator: SLUB looks calling __get_free_pages() if=20
size > PAGE_SIZE [note, not >=3D !], but SLAB doesn't. So, we'll add=20 ifdef here.
Quoted 1 line
Quoted 1 line
__init_refokpte_t*pte_alloc_one_kernel(structmm_struct*mm, unsigned=
long address)
Quoted 1 line
arch/powerpc/kernel/misc_32.S void kernel_map_pages(struct page *page, int numpage=
Quoted 1 line
arch/powerpc/kernel/misc_32.S +0
-0@@ -400,7 +395,7 @@ void kernel_map_pages(struct page *page, int numpage=
s, int enable)
Quoted 8 lines
Quoted 8 lines
arch/powerpc/kernel/misc_32.S +0
-0#endif /* CONFIG_DEBUG_PAGEALLOC */=20
static int fixmaps;arch/powerpc/kernel/misc_32.S +1
-1-unsigned long FIXADDR_TOP =3D 0xfffff000; +unsigned long FIXADDR_TOP =3D (-PAGE_SIZE); EXPORT_SYMBOL(FIXADDR_TOP);=20
void__set_fixmap(enumfixed_addressesidx,phys_addr_tphys, pgprot_t=
flags)
Quoted 1 line
arch/powerpc/platf=
Quoted 1 line
arch/powerpc/platf= renamed from arch/powerpc/platforms/Kconfig.cputype +0
-0
orms/Kconfig.cputype
Quoted 14 lines
arch/powerpc/platforms/Kconfig.cputype config PPC_STD_MMU_32 · line 208
Quoted 10 lines
index 548efa5..73a5aa9 100644
arch/powerpc/platforms/Kconfig.cputype +0
-0@@ -204,7 +204,7 @@ config PPC_STD_MMU_32=20
configPPC_MM_SLICES
boolarch/powerpc/platforms/Kconfig.cputype +1
-1- default y if HUGETLB_PAGE || PPC_64K_PAGES + default y if HUGETLB_PAGE || (PPC64 && PPC_64K_PAGES) default nI would make it
PPC_64&& (HUGETLB_PAGE||PPC_64K_PAGES) for now, I don't think we want to use the existing slice code on anything else.
Quoted 4 lines
Make it even
PPC_STD_MMU_64Cheers,
Ben.
Regards, Yuri
--
Yuri Tikhonov, Senior Software Engineer
Emcraft Systems, www.emcraft.com
Quoted 8 lines · Yuri Tikhonov
Quoted 3 lines
I'm not sure about the above &
PMD_MASK. Shouldn't we instead make it not build if (PKMAP_BASE&PMD_MASK) != 0 ?We separated the !4K_PAGES case here exactly because (
PKMAP_BASE&PMD_MASK) != 0 [see the comment to this chunk - why]. So, this'll turn out to be broken if we follow your suggestion. Are there any reasons why we should havePKMAP_BASEaligned on thePMD_SIZEboundary ?
No, you are right, so why do we need the & PMD_MASK in the 4k case ?
What I don't get is why do we need a different formula for 4k and 64k but I might just be stupid :-)
Quoted 3 lines
These definitions seem to be related to the page table, so, as for me,
thenpgtable.his the better place for them. Though, as you want; we'll move this topage_32.h.
Well, I like having them next to the pte_t/pgd_t definitions since they relate directly to the size of those structures.
Cheers,
Ben.
Hi Benjamin,
Quoted 9 lines · Benjamin Herrenschmidt
Quoted 8 lines
Quoted 3 lines
I'm not sure about the above &
PMD_MASK. Shouldn't we instead make it not build if (PKMAP_BASE&PMD_MASK) != 0 ?We separated the !4K_PAGES case here exactly because (
PKMAP_BASE&PMD_MASK) != 0 [see the comment to this chunk - why]. So, this'll turn out to be broken if we follow your suggestion. Are there any reasons why we should havePKMAP_BASEaligned on thePMD_SIZEboundary ?
Quoted 5 lines
No, you are right, so why do we need the &
PMD_MASKin the 4k case ?What I don't get is why do we need a different formula for 4k and 64k but I might just be stupid :-)
Because we want full PTE table for PKMAP with 4K pages (it's pretty small - only 512 pages so we really want to use all). And as current code doesn't support PKMAP being in different PTE tables we want to align to full PTE table not to lost part of it.
Quoted 8 lines
Quoted 4 lines
These definitions seem to be related to the page table, so, as for me,
thenpgtable.his the better place for them. Though, as you want; we'll move this topage_32.h.Well, I like having them next to the pte_t/pgd_t definitions since they relate directly to the size of those structures.
Well. But pte_t/pgd_t are actually in page.h not page_32.h (along with pmd/pud for 64bit)... So maybe we need to put definitions for PMD_T_LOG2/PUD_T_LOG2 too...
Regards, Ilya.
PATCH 1/1 powerpc: add 16K/64K pages support for the 44x PPC32 architectures.
In reply to Benjamin HerrenschmidtThis patch adds support for page sizes bigger than 4K (16K/64K) on PPC 44x.
PGDIR table is much smaller than page in case of 16K/64K pages (512 and 32 bytes resp.) so we allocate PGDIR with kzalloc() instead of __get_free_pages().
PTE table covers rather big memory area in case of 16K/64K pages (32MB and 512MB resp.) so we can easily put FIXMAP and PKMAP in area covered by one PTE table.
--- arch/powerpc/Kconfig | 58 ++++++++++++++++++++++++-------- arch/powerpc/include/asm/highmem.h | 15 +++++++- arch/powerpc/include/asm/mmu-44x.h | 17 +++++++++ arch/powerpc/include/asm/page.h | 13 ++++--- arch/powerpc/include/asm/page_32.h | 7 +++- arch/powerpc/kernel/asm-offsets.c | 4 ++ arch/powerpc/kernel/head_44x.S | 23 ++++++++----- arch/powerpc/kernel/misc_32.S | 12 +++--- arch/powerpc/mm/pgtable_32.c | 23 ++++++++----- arch/powerpc/platforms/Kconfig.cputype | 2 +- 10 files changed, 126 insertions(+), 48 deletions(-)
arch/powerpc/Kconfig +44 -14
@@ -401,23 +401,53 @@ config PPC_HAS_HASH_64K depends on PPC64 default n -config PPC_64K_PAGES - bool "64k page size" - depends on PPC64 - select PPC_HAS_HASH_64K +choice + prompt "Page size" + default PPC_4K_PAGES help - This option changes the kernel logical page size to 64k. On machines - without processor support for 64k pages, the kernel will simulate - them by loading each individual 4k page on demand transparently, - while on hardware with such support, it will be used to map - normal application pages. + Select the kernel logical page size. Increasing the page size + will reduce software overhead at each page boundary, allow + hardware prefetch mechanisms to be more effective, and allow + larger dma transfers increasing IO efficiency and reducing + overhead. However the utilization of memory will increase. + For example, each cached file will using a multiple of the + page size to hold its contents and the difference between the + end of file and the end of page is wasted. + + Some dedicated systems, such as software raid serving with + accelerated calculations, have shown significant increases. + + If you configure a 64 bit kernel for 64k pages but the + processor does not support them, then the kernel will simulate + them with 4k pages, loading them on demand, but with the + reduced software overhead and larger internal fragmentation. + For the 32 bit kernel, a large page option will not be offered + unless it is supported by the configured processor. + + If unsure, choose 4K_PAGES. + +config PPC_4K_PAGES + bool "4k page size" + +config PPC_16K_PAGES + bool "16k page size" if 44x + +config PPC_64K_PAGES + bool "64k page size" if 44x || PPC_STD_MMU_64 + select PPC_HAS_HASH_64K if PPC_STD_MMU_64 + +endchoice config FORCE_MAX_ZONEORDER int "Maximum zone order" - range 9 64 if PPC_64K_PAGES - default "9" if PPC_64K_PAGES - range 13 64 if PPC64 && !PPC_64K_PAGES - default "13" if PPC64 && !PPC_64K_PAGES + range 9 64 if PPC_STD_MMU_64 && PPC_64K_PAGES + default "9" if PPC_STD_MMU_64 && PPC_64K_PAGES + range 13 64 if PPC_STD_MMU_64 && !PPC_64K_PAGES + default "13" if PPC_STD_MMU_64 && !PPC_64K_PAGES + range 9 64 if PPC_STD_MMU_32 && PPC_16K_PAGES + default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES + range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES + default "7" if PPC_STD_MMU_32 && PPC_64K_PAGES range 11 64 default "11" help
@@ -437,7 +467,7 @@ config FORCE_MAX_ZONEORDER config PPC_SUBPAGE_PROT bool "Support setting protections for 4k subpages" - depends on PPC_64K_PAGES + depends on PPC_STD_MMU_64 && PPC_64K_PAGES help This option adds support for a system call to allow user programs to set access permissions (read/write, readonly, or no access)
arch/powerpc/include/asm/highmem.h +13 -2
@@ -38,9 +38,20 @@ extern pte_t *pkmap_page_table;* easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#define LAST_PKMAP (1 << PTE_SHIFT) -#define LAST_PKMAP_MASK (LAST_PKMAP-1) +/* +* We use one full pte table with 4K pages. And with 16K/64K pages pte +* table covers enough memory (32MB and 512MB resp.) that both FIXMAP +* and PKMAP can be placed in single pte table. We use 1024 pages for +* PKMAP in case of 16K/64K pages. +*/ +#define PKMAP_ORDER min(PTE_SHIFT, 10) +#define LAST_PKMAP (1 << PKMAP_ORDER) +#if !defined(CONFIG_PPC_4K_PAGES ) +#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) +#else #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) +#endif +#define LAST_PKMAP_MASK (LAST_PKMAP-1)#define PKMAP_NR (virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)#define PKMAP_ADDR (nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
arch/powerpc/include/asm/mmu-44x.h +17 -0
@@ -4,6 +4,8 @@* PPC440 support */ +#include <asm/page.h> +#define PPC44x_MMUCR_TID 0x000000ff#define PPC44x_MMUCR_STS 0x00010000
@@ -73,4 +75,19 @@ typedef struct {/* Size of the TLBs used for pinning in lowmem */ #define PPC_PIN_SIZE (1 << 28)/* 256M */ +#if (PAGE_SHIFT ==12 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_4K +#elif (PAGE_SHIFT ==14 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_16K +#elif (PAGE_SHIFT ==16 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_64K +#else +#error "Unsupported PAGE_SIZE" +#endif + +#define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2) +#define PPC44x_PGD_OFF_MASK_BIT (PGDIR_SHIFT - PGD_T_LOG2) +#define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2) +#define PPC44x_PTE_ADD_MASK_BIT (32 - PTE_T_LOG2 - PTE_SHIFT) +#endif /* _ASM_POWERPC_MMU_44X_H_ */
arch/powerpc/include/asm/page.h +8 -5
@@ -19,12 +19,15 @@#include <asm/kdump.h> /* -* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software +* On regular PPC32 page size is 4K (but we support 4K/16K/64K pages +* on PPC44x). For PPC64 we support either 4K or 64K software * page size. When using 64K pages however, whether we are really supporting * 64K pages in HW or not is irrelevant to those definitions. */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES )#define PAGE_SHIFT 16 +#elif defined(CONFIG_PPC_16K_PAGES ) +#define PAGE_SHIFT 14#else #define PAGE_SHIFT 12#endif
@@ -151,7 +154,7 @@ typedef struct { pte_basic_t pte; } pte_t;/* 64k pages additionally define a bigger "real PTE" type that gathers * the "second half" part of the PTE for pseudo 64k pages */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC_STD_MMU_64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else typedef struct {pte_t pte; }real_pte_t ;
@@ -191,10 +194,10 @@ typedef pte_basic_t pte_t;#define pte_val (x) (x)#define __pte (x) (x) -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC_STD_MMU_64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else -typedef unsigned long real_pte_t ; +typedef pte_t real_pte_t ;#endif
arch/powerpc/include/asm/page_32.h +5 -2
@@ -19,6 +19,8 @@#define PTE_FLAGS_OFFSET 0#endif +#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2)/* full page */ +#ifndef __ASSEMBLY__/* * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
@@ -26,10 +28,8 @@*/ #ifdef CONFIG_PTE_64BIT typedef unsigned long long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 3)/* 512 ptes per page */ #else typedef unsigned long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 2)/* 1024 ptes per page */ #endif struct page ;
@@ -39,6 +39,9 @@ extern void copy_page(void *to, void *from);#include <asm-generic/page.h> +#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) +#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1) +#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PAGE_32_H */
arch/powerpc/kernel/asm-offsets.c +4 -0
@@ -378,6 +378,10 @@ int main(void) DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));#endif +#ifdef CONFIG_44x +DEFINE (PGD_T_LOG2 ,PGD_T_LOG2 ); +DEFINE (PTE_T_LOG2 ,PTE_T_LOG2 ); +#endif return 0 ; }
arch/powerpc/kernel/head_44x.S +14 -9
@@ -391,12 +391,14 @@ interrupt_base: rlwimi r13,r12,10,30,30 /* Load the PTE */ - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */
@@ -485,12 +487,14 @@ tlb_44x_patch_hwater_D: /* Make up the required permissions */ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */
@@ -554,15 +558,16 @@ tlb_44x_patch_hwater_I: */ finish_tlb_load: /* Combine RPN & ERPN an write WS 0 */ - rlwimi r11,r12,0,0,19 + rlwimi r11,r12,0,0,31-PAGE_SHIFT tlbwe r11,r13,PPC44x_TLB_XLAT /* * Create WS1. This is the faulting address (EPN), * page size, and valid flag. */ - li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K - rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ + li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE + /* Insert valid and page size */ + rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK_BIT,31 tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ /* And WS 2 */
@@ -634,12 +639,12 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data - .align 12 + .align PAGE_SHIFT .globl sdata sdata: .globl empty_zero_page empty_zero_page: - .space 4096 + .space PAGE_SIZE /* * To support >32-bit physical addresses, we use an 8KB pgdir.
arch/powerpc/kernel/misc_32.S +6 -6
@@ -647,8 +647,8 @@ _GLOBAL(__flush_dcache_icache) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */
@@ -688,8 +688,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 isync - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */
@@ -713,7 +713,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) * void clear_pages(void *page, int order) ; */ _GLOBAL(clear_pages) - li r0,4096/L1_CACHE_BYTES + li r0,PAGE_SIZE/L1_CACHE_BYTES slw r0,r0,r4 mtctr r0 #ifdef CONFIG_8xx
@@ -771,7 +771,7 @@ _GLOBAL(copy_page) dcbt r5,r4 li r11,L1_CACHE_BYTES+4 #endif /* MAX_COPY_PREFETCH */ - li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH + li r0,PAGE_SIZE/L1_CACHE_BYTES - MAX_COPY_PREFETCH crclr 4*cr0+eq 2: mtctr r0
arch/powerpc/mm/pgtable_32.c +14 -9
@@ -72,24 +72,29 @@ extern unsigned long p_mapped_by_tlbcam(unsigned long pa);#define p_mapped_by_tlbcam (x) (0UL)#endif /* HAVE_TLBCAM */ -#ifdef CONFIG_PTE_64BIT -/* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */ -#define PGDIR_ORDER 1 -#else -#define PGDIR_ORDER 0 -#endif +#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)pgd_t *pgd_alloc (struct mm_struct *mm) {pgd_t *ret; - ret = (pgd_t *)__get_free_pages (GFP_KERNEL |__GFP_ZERO,PGDIR_ORDER ); +/* pgdir take page or two with 4K pages and a page fraction otherwise */ +#ifndef CONFIG_PPC_4K_PAGES + ret = (pgd_t *)kzalloc (1 <<PGDIR_ORDER ,GFP_KERNEL ); +#else + ret = (pgd_t *)__get_free_pages (GFP_KERNEL |__GFP_ZERO, +PGDIR_ORDER -PAGE_SHIFT ); +#endif return ret; }void pgd_free (struct mm_struct *mm,pgd_t *pgd) { -free_pages ((unsigned long )pgd,PGDIR_ORDER ); +#ifndef CONFIG_PPC_4K_PAGES +kfree ((void *)pgd); +#else +free_pages ((unsigned long )pgd,PGDIR_ORDER -PAGE_SHIFT ); +#endif } __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
@@ -400,7 +405,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)#endif /* CONFIG_DEBUG_PAGEALLOC */ static int fixmaps; -unsigned long FIXADDR_TOP =0xfffff000 ; +unsigned long FIXADDR_TOP = (-PAGE_SIZE );EXPORT_SYMBOL (FIXADDR_TOP );void __set_fixmap (enum fixed_addresses idx,phys_addr_t phys,pgprot_t flags)
arch/powerpc/platforms/Kconfig.cputype +1 -1
@@ -204,7 +204,7 @@ config PPC_STD_MMU_32 config PPC_MM_SLICES bool - default y if HUGETLB_PAGE || PPC_64K_PAGES + default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES) default n config VIRT_CPU_ACCOUNTING
Signature · 1 line
1.5.6.1
Hello guys,
please discard this patch. It just doesn't compile with CONFIG_HIGHMEM set. I'll post updated patch in a short time.
Excuse me.
Regards, Ilya.
PATCH 1/1 powerpc: add 16K/64K pages support for the 44x PPC32 architectures.
This patch adds support for page sizes bigger than 4K (16K/64K) on PPC 44x.
PGDIR table is much smaller than page in case of 16K/64K pages (512 and 32 bytes resp.) so we allocate PGDIR with kzalloc() instead of __get_free_pages().
PTE table covers rather big memory area in case of 16K/64K pages (32MB and 512MB resp.) so we can easily put FIXMAP and PKMAP in area covered by one PTE table.
--- arch/powerpc/Kconfig | 58 ++++++++++++++++++++++++-------- arch/powerpc/include/asm/highmem.h | 19 +++++++++- arch/powerpc/include/asm/mmu-44x.h | 17 +++++++++ arch/powerpc/include/asm/page.h | 13 ++++--- arch/powerpc/include/asm/page_32.h | 7 +++- arch/powerpc/kernel/asm-offsets.c | 4 ++ arch/powerpc/kernel/head_44x.S | 23 ++++++++----- arch/powerpc/kernel/misc_32.S | 12 +++--- arch/powerpc/mm/pgtable_32.c | 23 ++++++++----- arch/powerpc/platforms/Kconfig.cputype | 2 +- 10 files changed, 130 insertions(+), 48 deletions(-)
arch/powerpc/Kconfig +44 -14
@@ -401,23 +401,53 @@ config PPC_HAS_HASH_64K depends on PPC64 default n -config PPC_64K_PAGES - bool "64k page size" - depends on PPC64 - select PPC_HAS_HASH_64K +choice + prompt "Page size" + default PPC_4K_PAGES help - This option changes the kernel logical page size to 64k. On machines - without processor support for 64k pages, the kernel will simulate - them by loading each individual 4k page on demand transparently, - while on hardware with such support, it will be used to map - normal application pages. + Select the kernel logical page size. Increasing the page size + will reduce software overhead at each page boundary, allow + hardware prefetch mechanisms to be more effective, and allow + larger dma transfers increasing IO efficiency and reducing + overhead. However the utilization of memory will increase. + For example, each cached file will using a multiple of the + page size to hold its contents and the difference between the + end of file and the end of page is wasted. + + Some dedicated systems, such as software raid serving with + accelerated calculations, have shown significant increases. + + If you configure a 64 bit kernel for 64k pages but the + processor does not support them, then the kernel will simulate + them with 4k pages, loading them on demand, but with the + reduced software overhead and larger internal fragmentation. + For the 32 bit kernel, a large page option will not be offered + unless it is supported by the configured processor. + + If unsure, choose 4K_PAGES. + +config PPC_4K_PAGES + bool "4k page size" + +config PPC_16K_PAGES + bool "16k page size" if 44x + +config PPC_64K_PAGES + bool "64k page size" if 44x || PPC_STD_MMU_64 + select PPC_HAS_HASH_64K if PPC_STD_MMU_64 + +endchoice config FORCE_MAX_ZONEORDER int "Maximum zone order" - range 9 64 if PPC_64K_PAGES - default "9" if PPC_64K_PAGES - range 13 64 if PPC64 && !PPC_64K_PAGES - default "13" if PPC64 && !PPC_64K_PAGES + range 9 64 if PPC_STD_MMU_64 && PPC_64K_PAGES + default "9" if PPC_STD_MMU_64 && PPC_64K_PAGES + range 13 64 if PPC_STD_MMU_64 && !PPC_64K_PAGES + default "13" if PPC_STD_MMU_64 && !PPC_64K_PAGES + range 9 64 if PPC_STD_MMU_32 && PPC_16K_PAGES + default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES + range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES + default "7" if PPC_STD_MMU_32 && PPC_64K_PAGES range 11 64 default "11" help
@@ -437,7 +467,7 @@ config FORCE_MAX_ZONEORDER config PPC_SUBPAGE_PROT bool "Support setting protections for 4k subpages" - depends on PPC_64K_PAGES + depends on PPC_STD_MMU_64 && PPC_64K_PAGES help This option adds support for a system call to allow user programs to set access permissions (read/write, readonly, or no access)
arch/powerpc/include/asm/highmem.h +17 -2
@@ -38,9 +38,24 @@ extern pte_t *pkmap_page_table;* easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#define LAST_PKMAP (1 << PTE_SHIFT) -#define LAST_PKMAP_MASK (LAST_PKMAP-1) +/* +* We use one full pte table with 4K pages. And with 16K/64K pages pte +* table covers enough memory (32MB and 512MB resp.) that both FIXMAP +* and PKMAP can be placed in single pte table. We use 1024 pages for +* PKMAP in case of 16K/64K pages. +*/ +#ifdef CONFIG_PPC_4K_PAGES +#define PKMAP_ORDER PTE_SHIFT +#else +#define PKMAP_ORDER 10 +#endif +#define LAST_PKMAP (1 << PKMAP_ORDER) +#ifndef CONFIG_PPC_4K_PAGES +#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) +#else #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) +#endif +#define LAST_PKMAP_MASK (LAST_PKMAP-1)#define PKMAP_NR (virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)#define PKMAP_ADDR (nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
arch/powerpc/include/asm/mmu-44x.h +17 -0
@@ -4,6 +4,8 @@* PPC440 support */ +#include <asm/page.h> +#define PPC44x_MMUCR_TID 0x000000ff#define PPC44x_MMUCR_STS 0x00010000
@@ -73,4 +75,19 @@ typedef struct {/* Size of the TLBs used for pinning in lowmem */ #define PPC_PIN_SIZE (1 << 28)/* 256M */ +#if (PAGE_SHIFT ==12 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_4K +#elif (PAGE_SHIFT ==14 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_16K +#elif (PAGE_SHIFT ==16 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_64K +#else +#error "Unsupported PAGE_SIZE" +#endif + +#define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2) +#define PPC44x_PGD_OFF_MASK_BIT (PGDIR_SHIFT - PGD_T_LOG2) +#define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2) +#define PPC44x_PTE_ADD_MASK_BIT (32 - PTE_T_LOG2 - PTE_SHIFT) +#endif /* _ASM_POWERPC_MMU_44X_H_ */
arch/powerpc/include/asm/page.h +8 -5
@@ -19,12 +19,15 @@#include <asm/kdump.h> /* -* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software +* On regular PPC32 page size is 4K (but we support 4K/16K/64K pages +* on PPC44x). For PPC64 we support either 4K or 64K software * page size. When using 64K pages however, whether we are really supporting * 64K pages in HW or not is irrelevant to those definitions. */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES )#define PAGE_SHIFT 16 +#elif defined(CONFIG_PPC_16K_PAGES ) +#define PAGE_SHIFT 14#else #define PAGE_SHIFT 12#endif
@@ -151,7 +154,7 @@ typedef struct { pte_basic_t pte; } pte_t;/* 64k pages additionally define a bigger "real PTE" type that gathers * the "second half" part of the PTE for pseudo 64k pages */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC_STD_MMU_64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else typedef struct {pte_t pte; }real_pte_t ;
@@ -191,10 +194,10 @@ typedef pte_basic_t pte_t;#define pte_val (x) (x)#define __pte (x) (x) -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC_STD_MMU_64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else -typedef unsigned long real_pte_t ; +typedef pte_t real_pte_t ;#endif
arch/powerpc/include/asm/page_32.h +5 -2
@@ -19,6 +19,8 @@#define PTE_FLAGS_OFFSET 0#endif +#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2)/* full page */ +#ifndef __ASSEMBLY__/* * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
@@ -26,10 +28,8 @@*/ #ifdef CONFIG_PTE_64BIT typedef unsigned long long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 3)/* 512 ptes per page */ #else typedef unsigned long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 2)/* 1024 ptes per page */ #endif struct page ;
@@ -39,6 +39,9 @@ extern void copy_page(void *to, void *from);#include <asm-generic/page.h> +#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) +#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1) +#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PAGE_32_H */
arch/powerpc/kernel/asm-offsets.c +4 -0
@@ -378,6 +378,10 @@ int main(void) DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));#endif +#ifdef CONFIG_44x +DEFINE (PGD_T_LOG2 ,PGD_T_LOG2 ); +DEFINE (PTE_T_LOG2 ,PTE_T_LOG2 ); +#endif return 0 ; }
arch/powerpc/kernel/head_44x.S +14 -9
@@ -391,12 +391,14 @@ interrupt_base: rlwimi r13,r12,10,30,30 /* Load the PTE */ - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */
@@ -485,12 +487,14 @@ tlb_44x_patch_hwater_D: /* Make up the required permissions */ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */
@@ -554,15 +558,16 @@ tlb_44x_patch_hwater_I: */ finish_tlb_load: /* Combine RPN & ERPN an write WS 0 */ - rlwimi r11,r12,0,0,19 + rlwimi r11,r12,0,0,31-PAGE_SHIFT tlbwe r11,r13,PPC44x_TLB_XLAT /* * Create WS1. This is the faulting address (EPN), * page size, and valid flag. */ - li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K - rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ + li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE + /* Insert valid and page size */ + rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK_BIT,31 tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ /* And WS 2 */
@@ -634,12 +639,12 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data - .align 12 + .align PAGE_SHIFT .globl sdata sdata: .globl empty_zero_page empty_zero_page: - .space 4096 + .space PAGE_SIZE /* * To support >32-bit physical addresses, we use an 8KB pgdir.
arch/powerpc/kernel/misc_32.S +6 -6
@@ -647,8 +647,8 @@ _GLOBAL(__flush_dcache_icache) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */
@@ -688,8 +688,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 isync - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r3 0: dcbst 0,r3 /* Write line to ram */
@@ -713,7 +713,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) * void clear_pages(void *page, int order) ; */ _GLOBAL(clear_pages) - li r0,4096/L1_CACHE_BYTES + li r0,PAGE_SIZE/L1_CACHE_BYTES slw r0,r0,r4 mtctr r0 #ifdef CONFIG_8xx
@@ -771,7 +771,7 @@ _GLOBAL(copy_page) dcbt r5,r4 li r11,L1_CACHE_BYTES+4 #endif /* MAX_COPY_PREFETCH */ - li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH + li r0,PAGE_SIZE/L1_CACHE_BYTES - MAX_COPY_PREFETCH crclr 4*cr0+eq 2: mtctr r0
arch/powerpc/mm/pgtable_32.c +14 -9
@@ -72,24 +72,29 @@ extern unsigned long p_mapped_by_tlbcam(unsigned long pa);#define p_mapped_by_tlbcam (x) (0UL)#endif /* HAVE_TLBCAM */ -#ifdef CONFIG_PTE_64BIT -/* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */ -#define PGDIR_ORDER 1 -#else -#define PGDIR_ORDER 0 -#endif +#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)pgd_t *pgd_alloc (struct mm_struct *mm) {pgd_t *ret; - ret = (pgd_t *)__get_free_pages (GFP_KERNEL |__GFP_ZERO,PGDIR_ORDER ); +/* pgdir take page or two with 4K pages and a page fraction otherwise */ +#ifndef CONFIG_PPC_4K_PAGES + ret = (pgd_t *)kzalloc (1 <<PGDIR_ORDER ,GFP_KERNEL ); +#else + ret = (pgd_t *)__get_free_pages (GFP_KERNEL |__GFP_ZERO, +PGDIR_ORDER -PAGE_SHIFT ); +#endif return ret; }void pgd_free (struct mm_struct *mm,pgd_t *pgd) { -free_pages ((unsigned long )pgd,PGDIR_ORDER ); +#ifndef CONFIG_PPC_4K_PAGES +kfree ((void *)pgd); +#else +free_pages ((unsigned long )pgd,PGDIR_ORDER -PAGE_SHIFT ); +#endif } __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
@@ -400,7 +405,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)#endif /* CONFIG_DEBUG_PAGEALLOC */ static int fixmaps; -unsigned long FIXADDR_TOP =0xfffff000 ; +unsigned long FIXADDR_TOP = (-PAGE_SIZE );EXPORT_SYMBOL (FIXADDR_TOP );void __set_fixmap (enum fixed_addresses idx,phys_addr_t phys,pgprot_t flags)
arch/powerpc/platforms/Kconfig.cputype +1 -1
@@ -204,7 +204,7 @@ config PPC_STD_MMU_32 config PPC_MM_SLICES bool - default y if HUGETLB_PAGE || PPC_64K_PAGES + default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES) default n config VIRT_CPU_ACCOUNTING
Signature · 1 line
1.5.6.1
Quoted 9 lines · Ilya Yanok
This patch adds support for page sizes bigger than 4K (16K/64K) on PPC 44x.
PGDIR table is much smaller than page in case of 16K/64K pages (512 and 32 bytes resp.) so we allocate PGDIR withkzalloc()instead of__get_free_pages().
PTE table covers rather big memory area in case of 16K/64K pages (32MB and 512MB resp.) so we can easily put FIXMAP and PKMAP in area covered by one PTE table.
Quoted 3 lines
Signed-off-by Yuri Tikhonov <[email protected]>Signed-off-by Vladimir Panfilov <[email protected]>Signed-off-by Ilya Yanok <[email protected]>
I tested this a bit today on a Bamboo board. Overall, it functioned well enough to not crash :). Note that I also included Hollis' memory size alignment patch which is required.
The code looks pretty clean now. I think if we're going to include this patch it should go in now.
Quoted 438 lines
---
arch/powerpc/Kconfig | 58 ++++++++++++++++++++++++-------- arch/powerpc/include/asm/highmem.h | 19 +++++++++- arch/powerpc/include/asm/mmu-44x.h | 17 +++++++++ arch/powerpc/include/asm/page.h | 13 ++++--- arch/powerpc/include/asm/page_32.h | 7 +++- arch/powerpc/kernel/asm-offsets.c | 4 ++ arch/powerpc/kernel/head_44x.S | 23 ++++++++----- arch/powerpc/kernel/misc_32.S | 12 +++--- arch/powerpc/mm/pgtable_32.c | 23 ++++++++----- arch/powerpc/platforms/Kconfig.cputype | 2 +- 10 files changed, 130 insertions(+), 48 deletions(-)arch/powerpc/Kconfig +35
-9@@ -401,23 +401,53 @@ config PPC_HAS_HASH_64K depends on PPC64 default n -config PPC_64K_PAGES - bool "64k page size" - depends on PPC64 - select PPC_HAS_HASH_64K +choice + prompt "Page size" + default PPC_4K_PAGES help - This option changes the kernel logical page size to 64k. On machines - without processor support for 64k pages, the kernel will simulate - them by loading each individual 4k page on demand transparently, - while on hardware with such support, it will be used to map - normal application pages. + Select the kernel logical page size. Increasing the page size + will reduce software overhead at each page boundary, allow + hardware prefetch mechanisms to be more effective, and allow + larger dma transfers increasing IO efficiency and reducing + overhead. However the utilization of memory will increase. + For example, each cached file will using a multiple of the + page size to hold its contents and the difference between the + end of file and the end of page is wasted. + + Some dedicated systems, such as software raid serving with + accelerated calculations, have shown significant increases. + + If you configure a 64 bit kernel for 64k pages but the + processor does not support them, then the kernel will simulate + them with 4k pages, loading them on demand, but with the + reduced software overhead and larger internal fragmentation. + For the 32 bit kernel, a large page option will not be offered + unless it is supported by the configured processor. + + If unsure, choose 4K_PAGES. + +config PPC_4K_PAGES + bool "4k page size" + +config PPC_16K_PAGES + bool "16k page size" if 44x + +config PPC_64K_PAGES + bool "64k page size" if 44x || PPC_STD_MMU_64 + select PPC_HAS_HASH_64K if PPC_STD_MMU_64 + +endchoiceconfig
FORCE_MAX_ZONEORDER
int "Maximum zone order"arch/powerpc/Kconfig +8
-4- range 9 64 if PPC_64K_PAGES - default "9" if PPC_64K_PAGES - range 13 64 if PPC64 && !PPC_64K_PAGES - default "13" if PPC64 && !PPC_64K_PAGES + range 9 64 if PPC_STD_MMU_64 && PPC_64K_PAGES + default "9" if PPC_STD_MMU_64 && PPC_64K_PAGES + range 13 64 if PPC_STD_MMU_64 && !PPC_64K_PAGES + default "13" if PPC_STD_MMU_64 && !PPC_64K_PAGES + range 9 64 if PPC_STD_MMU_32 && PPC_16K_PAGES + default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES + range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES + default "7" if PPC_STD_MMU_32 && PPC_64K_PAGESrange 11 64 default "11" helparch/powerpc/Kconfig +0
-0@@ -437,7 +467,7 @@ config FORCE_MAX_ZONEORDERconfig
PPC_SUBPAGE_PROT
bool "Support setting protections for 4k subpages"arch/powerpc/Kconfig +1
-1- depends on PPC_64K_PAGES + depends on PPC_STD_MMU_64 && PPC_64K_PAGEShelp
This option adds support for a system call to allow user programs to set access permissions (read/write, readonly, or no access)arch/powerpc/include/asm/highmem.h +17
-2@@ -38,9 +38,24 @@ extern pte_t *pkmap_page_table;* easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#define LAST_PKMAP (1 << PTE_SHIFT) -#define LAST_PKMAP_MASK (LAST_PKMAP-1) +/* +* We use one full pte table with 4K pages. And with 16K/64K pages pte +* table covers enough memory (32MB and 512MB resp.) that both FIXMAP +* and PKMAP can be placed in single pte table. We use 1024 pages for +* PKMAP in case of 16K/64K pages. +*/ +#ifdef CONFIG_PPC_4K_PAGES +#define PKMAP_ORDER PTE_SHIFT +#else +#define PKMAP_ORDER 10 +#endif +#define LAST_PKMAP (1 << PKMAP_ORDER) +#ifndef CONFIG_PPC_4K_PAGES +#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) +#else #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK) +#endif +#define LAST_PKMAP_MASK (LAST_PKMAP-1)#define PKMAP_NR (virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)#define PKMAP_ADDR (nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))arch/powerpc/include/asm/mmu-44x.h +17
-0@@ -4,6 +4,8 @@* PPC440 support */ +#include <asm/page.h> +#define PPC44x_MMUCR_TID 0x000000ff#define PPC44x_MMUCR_STS 0x00010000@@ -73,4 +75,19 @@ typedef struct {/* Size of the TLBs used for pinning in lowmem */ #define PPC_PIN_SIZE (1 << 28)/* 256M */ +#if (PAGE_SHIFT ==12 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_4K +#elif (PAGE_SHIFT ==14 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_16K +#elif (PAGE_SHIFT ==16 ) +#define PPC44x_TLBE_SIZE PPC44x_TLB_64K +#else +#error "Unsupported PAGE_SIZE" +#endif + +#define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2) +#define PPC44x_PGD_OFF_MASK_BIT (PGDIR_SHIFT - PGD_T_LOG2) +#define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2) +#define PPC44x_PTE_ADD_MASK_BIT (32 - PTE_T_LOG2 - PTE_SHIFT) +#endif /* _ASM_POWERPC_MMU_44X_H_ */ arch/powerpc/include/asm/page.h +8
-5@@ -19,12 +19,15 @@#include <asm/kdump.h> /* -* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software +* On regular PPC32 page size is 4K (but we support 4K/16K/64K pages +* on PPC44x). For PPC64 we support either 4K or 64K software * page size. When using 64K pages however, whether we are really supporting * 64K pages in HW or not is irrelevant to those definitions. */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES )#define PAGE_SHIFT 16 +#elif defined(CONFIG_PPC_16K_PAGES ) +#define PAGE_SHIFT 14#else #define PAGE_SHIFT 12#endif @@ -151,7 +154,7 @@ typedef struct { pte_basic_t pte; } pte_t;/* 64k pages additionally define a bigger "real PTE" type that gathers * the "second half" part of the PTE for pseudo 64k pages */ -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC_STD_MMU_64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else typedef struct {pte_t pte; }real_pte_t ;@@ -191,10 +194,10 @@ typedef pte_basic_t pte_t;#define pte_val (x) (x)#define __pte (x) (x) -#ifdef CONFIG_PPC_64K_PAGES +#if defined(CONFIG_PPC_64K_PAGES ) && defined(CONFIG_PPC_STD_MMU_64 )typedef struct {pte_t pte;unsigned long hidx; }real_pte_t ;#else -typedef unsigned long real_pte_t ; +typedef pte_t real_pte_t ;#endif arch/powerpc/include/asm/page_32.h +5
-2@@ -19,6 +19,8 @@#define PTE_FLAGS_OFFSET 0#endif +#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2)/* full page */ +#ifndef __ASSEMBLY__/* * The basic type of a PTE - 64 bits for those CPUs with > 32 bit @@ -26,10 +28,8 @@*/ #ifdef CONFIG_PTE_64BIT typedef unsigned long long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 3)/* 512 ptes per page */ #else typedef unsigned long pte_basic_t ; -#define PTE_SHIFT (PAGE_SHIFT - 2)/* 1024 ptes per page */ #endif struct page ;@@ -39,6 +39,9 @@ extern void copy_page(void *to, void *from);#include <asm-generic/page.h> +#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) +#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1) +#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PAGE_32_H */ arch/powerpc/kernel/asm-offsets.c +4
-0@@ -378,6 +378,10 @@ int main(void) DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));#endif +#ifdef CONFIG_44x +DEFINE (PGD_T_LOG2 ,PGD_T_LOG2 ); +DEFINE (PTE_T_LOG2 ,PTE_T_LOG2 ); +#endif return 0 ; }arch/powerpc/kernel/head_44x.S +8
-4@@ -391,12 +391,14 @@ interrupt_base: rlwimi r13,r12,10,30,30 /* Load the PTE */ - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */@@ -485,12 +487,14 @@ tlb_44x_patch_hwater_D: /* Make up the required permissions */ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + /* Compute pgdir/pmd offset */ + rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + /* Compute pte address */ + rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 lwz r11, 0(r12) /* Get high word of pte entry */ lwz r12, 4(r12) /* Get low word of pte entry */@@ -554,15 +558,16 @@ tlb_44x_patch_hwater_I: */
finish_tlb_load:/* Combine RPN & ERPN an write WS 0 */arch/powerpc/kernel/head_44x.S +1
-1- rlwimi r11,r12,0,0,19 + rlwimi r11,r12,0,0,31-PAGE_SHIFTtlbwe r11,r13,PPC44x_TLB_XLAT /* * Create WS1. This is the faulting address (EPN), * page size, and valid flag. */arch/powerpc/kernel/head_44x.S +3
-2- li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K - rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ + li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE + /* Insert valid and page size */ + rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK_BIT,31tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ /* And WS 2 */arch/powerpc/kernel/head_44x.S +1
-1@@ -634,12 +639,12 @@ _GLOBAL(set_context) * goes at the beginning of the data segment, which is page-aligned. */ .data - .align 12 + .align PAGE_SHIFT .globl sdatasdata:
.globlempty_zero_pageempty_zero_page:arch/powerpc/kernel/head_44x.S +1
-1- .space 4096 + .space PAGE_SIZE/*
* To support >32-bit physical addresses, we use an 8KB pgdir.arch/powerpc/kernel/misc_32.S +0
-0@@ -647,8 +647,8 @@ _GLOBAL(__flush_dcache_icache)
BEGIN_FTR_SECTION
blrEND_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)arch/powerpc/kernel/misc_32.S +2
-2- rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */mtctr r4 mr r6,r30: dcbst 0,r3 /* Write line to ram */
arch/powerpc/kernel/misc_32.S +2
-2@@ -688,8 +688,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 isync - rlwinm r3,r3,0,0,19 /* Get page base address */ - li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ + rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ + li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ mtctr r4 mr r6,r30: dcbst 0,r3 /* Write line to ram */
arch/powerpc/kernel/misc_32.S +2
-2@@ -713,7 +713,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) * void clear_pages(void *page, int order) ; */ _GLOBAL(clear_pages) - li r0,4096/L1_CACHE_BYTES + li r0,PAGE_SIZE/L1_CACHE_BYTES slw r0,r0,r4 mtctr r0 #ifdef CONFIG_8xx@@ -771,7 +771,7 @@ _GLOBAL(copy_page) dcbt r5,r4 li r11,L1_CACHE_BYTES+4 #endif /* MAX_COPY_PREFETCH */ - li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH + li r0,PAGE_SIZE/L1_CACHE_BYTES - MAX_COPY_PREFETCH crclr 4*cr0+eq2:
mtctr r0arch/powerpc/mm/pgtable_32.c +14
-9@@ -72,24 +72,29 @@ extern unsigned long p_mapped_by_tlbcam(unsigned long pa);#define p_mapped_by_tlbcam (x) (0UL)#endif /* HAVE_TLBCAM */ -#ifdef CONFIG_PTE_64BIT -/* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */ -#define PGDIR_ORDER 1 -#else -#define PGDIR_ORDER 0 -#endif +#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)pgd_t *pgd_alloc (struct mm_struct *mm) {pgd_t *ret; - ret = (pgd_t *)__get_free_pages (GFP_KERNEL |__GFP_ZERO,PGDIR_ORDER ); +/* pgdir take page or two with 4K pages and a page fraction otherwise */ +#ifndef CONFIG_PPC_4K_PAGES + ret = (pgd_t *)kzalloc (1 <<PGDIR_ORDER ,GFP_KERNEL ); +#else + ret = (pgd_t *)__get_free_pages (GFP_KERNEL |__GFP_ZERO, +PGDIR_ORDER -PAGE_SHIFT ); +#endif return ret; }void pgd_free (struct mm_struct *mm,pgd_t *pgd) { -free_pages ((unsigned long )pgd,PGDIR_ORDER ); +#ifndef CONFIG_PPC_4K_PAGES +kfree ((void *)pgd); +#else +free_pages ((unsigned long )pgd,PGDIR_ORDER -PAGE_SHIFT ); +#endif } __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)@@ -400,7 +405,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)#endif /* CONFIG_DEBUG_PAGEALLOC */ static int fixmaps; -unsigned long FIXADDR_TOP =0xfffff000 ; +unsigned long FIXADDR_TOP = (-PAGE_SIZE );EXPORT_SYMBOL (FIXADDR_TOP );void __set_fixmap (enum fixed_addresses idx,phys_addr_t phys,pgprot_t flags)arch/powerpc/platforms/Kconfig.cputype +0
-0@@ -204,7 +204,7 @@ config PPC_STD_MMU_32config
PPC_MM_SLICES
boolarch/powerpc/platforms/Kconfig.cputype +1
-1- default y if HUGETLB_PAGE || PPC_64K_PAGES + default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES)default n
config
VIRT_CPU_ACCOUNTINGSignature · 6 lines
1.5.6.1 _______________________________________________ Linuxppc-dev mailing list [email protected] https://ozlabs.org/mailman/listinfo/linuxppc-dev
Quoted 14 lines · Josh Boyer
Quoted 9 lines · Ilya Yanok
This patch adds support for page sizes bigger than 4K (16K/64K) on PPC 44x.
PGDIR table is much smaller than page in case of 16K/64K pages (512 and 32 bytes resp.) so we allocate PGDIR withkzalloc()instead of__get_free_pages().
PTE table covers rather big memory area in case of 16K/64K pages (32MB and 512MB resp.) so we can easily put FIXMAP and PKMAP in area covered by one PTE table.Quoted 3 lines
Signed-off-by Yuri Tikhonov <[email protected]>Signed-off-by Vladimir Panfilov <[email protected]>Signed-off-by Ilya Yanok <[email protected]>
Quoted 8 lines
I tested this a bit today on a Bamboo board. Overall, it functioned well enough to not crash :). Note that I also included Hollis' memory size alignment patch which is required.
The code looks pretty clean now. I think if we're going to include this patch it should go in now.
Acked-by Josh Boyer <[email protected]>
Ben, Paul,
What else is needed to get this patch included?
josh
Quoted 9 lines
Quoted 5 lines
The code looks pretty clean now. I think if we're going to include this patch it should go in now.
Acked-by Josh Boyer <[email protected]>Ben, Paul,
What else is needed to get this patch included?
Can you remind us the pre-req ?
Cheers,
Ben.
Quoted 11 lines · Benjamin Herrenschmidt
Quoted 9 lines
Quoted 5 lines
The code looks pretty clean now. I think if we're going to include this patch it should go in now.
Acked-by Josh Boyer <[email protected]>Ben, Paul,
What else is needed to get this patch included?
Can you remind us the pre-req ?
http://patchwork.ozlabs.org/patch/10951/
josh