Message ID | 1444821634-1689-11-git-send-email-suzuki.poulose@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote: > diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h > index da32354..736ed4c 100644 > --- a/arch/arm64/include/asm/page.h > +++ b/arch/arm64/include/asm/page.h > @@ -24,6 +24,9 @@ > #ifdef CONFIG_ARM64_64K_PAGES > #define PAGE_SHIFT 16 > #define CONT_SHIFT 5 > +#elif defined(CONFIG_ARM64_16K_PAGES) > +#define PAGE_SHIFT 14 > +#define CONT_SHIFT 9 > #else > #define PAGE_SHIFT 12 > #define CONT_SHIFT 4 Suzuki, Is CONT_SHIFT correct? I thought it should be 7? The ARM-ARM says that a contiguous 3rd level lookup is 128 entries. Thanks, Jeremy
On 14/10/15 16:40, Jeremy Linton wrote: > On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote: >> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h >> index da32354..736ed4c 100644 >> --- a/arch/arm64/include/asm/page.h >> +++ b/arch/arm64/include/asm/page.h >> @@ -24,6 +24,9 @@ >> #ifdef CONFIG_ARM64_64K_PAGES >> #define PAGE_SHIFT 16 >> #define CONT_SHIFT 5 >> +#elif defined(CONFIG_ARM64_16K_PAGES) >> +#define PAGE_SHIFT 14 >> +#define CONT_SHIFT 9 >> #else >> #define PAGE_SHIFT 12 >> #define CONT_SHIFT 4 > > Suzuki, > > Is CONT_SHIFT correct? I thought it should be 7? The ARM-ARM says that a contiguous 3rd level lookup is 128 entries. > Err, you are right. I tested it with 9 and I still got contiguous mappings. May be because we anyway have 7 contiguous bits and the kernel text is read-only. I will fix that, thanks for spotting. Suzuki
Hi, > +config ARM64_16K_PAGES > + bool "16KB" > + help > + The system will use 16KB pages support. AArch32 emulation > + requires applications compiled with 16K(or multiple of 16K) > + aligned segments. Nit: missing space before '(' Nit: 'a multiple of' > @@ -503,6 +517,7 @@ config XEN > config FORCE_MAX_ZONEORDER > int > default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE) > + default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE) > default "11" I'm a little lost here. How are these numbers derived? > menuconfig ARMV8_DEPRECATED > @@ -689,9 +704,9 @@ config COMPAT > the user helper functions, VFP support and the ptrace interface are > handled appropriately by the kernel. > > - If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you > - will only be able to execute AArch32 binaries that were compiled with > - 64k aligned segments. > + If you use a page size other than 4KB(i.e, 16KB or 64KB), please be aware Nit: missing space before '(' please. > diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h > index 8b9884c..a294c70 100644 > --- a/arch/arm64/include/asm/fixmap.h > +++ b/arch/arm64/include/asm/fixmap.h > @@ -55,8 +55,10 @@ enum fixed_addresses { > * Temporary boot-time mappings, used by early_ioremap(), > * before ioremap() is functional. > */ > -#ifdef CONFIG_ARM64_64K_PAGES > +#if defined(CONFIG_ARM64_64K_PAGES) > #define NR_FIX_BTMAPS 4 > +#elif defined (CONFIG_ARM64_16K_PAGES) > +#define NR_FIX_BTMAPS 16 > #else > #define NR_FIX_BTMAPS 64 > #endif We could include <linux/sizes.h> and simplify this to: #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE) Which works for me locally. > diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h > index 5eac6a2..90c7ff2 100644 > --- a/arch/arm64/include/asm/thread_info.h > +++ b/arch/arm64/include/asm/thread_info.h > @@ -25,6 +25,8 @@ > > #ifdef CONFIG_ARM64_4K_PAGES > #define THREAD_SIZE_ORDER 2 > +#elif defined(CONFIG_ARM64_16K_PAGES) > +#define THREAD_SIZE_ORDER 0 > #endif > #define THREAD_SIZE 16384 The above looks correct. As an open/general question, why do both THREAD_SIZE_ORDER and THREAD_SIZE exist? One really should be defined in terms of the other. As far as I can tell,the only user of THREAD_SIZE_ORDER outside of arch code is fork.c, which could calculate it as: ilog2(DIV_ROUND_UP(THREAD_SIZE, PAGE_SIZE)) Though I suspect we can't do that in a macro here for fear of a fragile build, so that's something for another time. > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S > index b6aa9e0..2ed57a8 100644 > --- a/arch/arm64/kernel/head.S > +++ b/arch/arm64/kernel/head.S > @@ -624,7 +624,12 @@ ENDPROC(__secondary_switched) > #define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN64_SHIFT > #define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN64_ON > > -#else > +#elif defined(CONFIG_ARM64_16K_PAGES) > + > +#define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN16_SHIFT > +#define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN16_ON > + > +#elif defined(CONFIG_ARM64_4K_PAGES) > > #define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN4_SHIFT > #define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN4_ON I assume you'll s/ON/SUPPORTED/ per comments in another thread. Otherwise this looks fine to me. Thanks, Mark.
On 15/10/15 15:06, Mark Rutland wrote: > Hi, > I have fixed all the nits locally. Thanks for pointing them out. >> config FORCE_MAX_ZONEORDER >> int >> default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE) >> + default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE) >> default "11" > > I'm a little lost here. How are these numbers derived? > I struggled to find the right value for 16K. Thanks to Steve Capper for the following explanation. I will add it as a comment. All allocations from the buddy allocator have to have compound order strictly less than MAX_ORDER. i.e, the maximum allocation size is (MAX_ORDER - 1) PAGES. To align with the transparent huge page size, we get : (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT Which gives us: MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1 = PAGE_SHIFT - 2 That raises an interesting question about the selection of the value for 4K. Shouldn't that be 10 instead of 11 ? Steve ? >> -#ifdef CONFIG_ARM64_64K_PAGES >> +#if defined(CONFIG_ARM64_64K_PAGES) >> #define NR_FIX_BTMAPS 4 >> +#elif defined (CONFIG_ARM64_16K_PAGES) >> +#define NR_FIX_BTMAPS 16 >> #else >> #define NR_FIX_BTMAPS 64 >> #endif > > We could include <linux/sizes.h> and simplify this to: > > #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE) > > Which works for me locally. Nice cleanup. I will pick that as a separate patch in the series. > >> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h >> index 5eac6a2..90c7ff2 100644 >> --- a/arch/arm64/include/asm/thread_info.h >> +++ b/arch/arm64/include/asm/thread_info.h >> @@ -25,6 +25,8 @@ >> >> #ifdef CONFIG_ARM64_4K_PAGES >> #define THREAD_SIZE_ORDER 2 >> +#elif defined(CONFIG_ARM64_16K_PAGES) >> +#define THREAD_SIZE_ORDER 0 >> #endif >> #define THREAD_SIZE 16384 > > The above looks correct. > > As an open/general question, why do both THREAD_SIZE_ORDER and > THREAD_SIZE exist? One really should be defined in terms of the other. I think its mainly for choosing the mechanism for stack allocation. If it is a multiple of a page, you allocate a page. If not, uses a kmem_cache. >> #define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN4_SHIFT >> #define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN4_ON > > I assume you'll s/ON/SUPPORTED/ per comments in another thread. > Yes Thanks Suzuki
On 15 October 2015 at 15:48, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote: > On 15/10/15 15:06, Mark Rutland wrote: >> >> Hi, >> > > I have fixed all the nits locally. Thanks for pointing them out. > >>> config FORCE_MAX_ZONEORDER >>> int >>> default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE) >>> + default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE) >>> default "11" >> >> >> I'm a little lost here. How are these numbers derived? >> > > I struggled to find the right value for 16K. Thanks to Steve Capper > for the following explanation. I will add it as a comment. > > All allocations from the buddy allocator have to have compound order > strictly less than MAX_ORDER. i.e, the maximum allocation size is > (MAX_ORDER - 1) PAGES. To align with the transparent huge page size, > we get : > > (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT > > Which gives us: > > MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1 > = PAGE_SHIFT - 2 > > That raises an interesting question about the selection of the value > for 4K. Shouldn't that be 10 instead of 11 ? > > Steve ? Hi, My understanding is that 11 is a "good minimum" value for the page allocator with 4KB pages. (There are references to it being 10 in 2.4 kernels but raised to 11 on 2.6 kernels?) We need to raise the minimum when we have a 16KB or 64KB PAGE_SIZE to be able allocate a 32MB or 512MB Transparent HugePages. Cheers, -- Steve > >>> -#ifdef CONFIG_ARM64_64K_PAGES >>> +#if defined(CONFIG_ARM64_64K_PAGES) >>> #define NR_FIX_BTMAPS 4 >>> +#elif defined (CONFIG_ARM64_16K_PAGES) >>> +#define NR_FIX_BTMAPS 16 >>> #else >>> #define NR_FIX_BTMAPS 64 >>> #endif >> >> >> We could include <linux/sizes.h> and simplify this to: >> >> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE) >> >> Which works for me locally. > > > Nice cleanup. I will pick that as a separate patch in the series. > >> >>> diff --git a/arch/arm64/include/asm/thread_info.h >>> b/arch/arm64/include/asm/thread_info.h >>> index 5eac6a2..90c7ff2 100644 >>> --- a/arch/arm64/include/asm/thread_info.h >>> +++ b/arch/arm64/include/asm/thread_info.h >>> @@ -25,6 +25,8 @@ >>> >>> #ifdef CONFIG_ARM64_4K_PAGES >>> #define THREAD_SIZE_ORDER 2 >>> +#elif defined(CONFIG_ARM64_16K_PAGES) >>> +#define THREAD_SIZE_ORDER 0 >>> #endif >>> #define THREAD_SIZE 16384 >> >> >> The above looks correct. >> >> As an open/general question, why do both THREAD_SIZE_ORDER and >> THREAD_SIZE exist? One really should be defined in terms of the other. > > > I think its mainly for choosing the mechanism for stack allocation. If it > is a multiple of a page, you allocate a page. If not, uses a kmem_cache. > > >>> #define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN4_SHIFT >>> #define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN4_ON >> >> >> I assume you'll s/ON/SUPPORTED/ per comments in another thread. >> > > Yes > > Thanks > Suzuki >
On 15/10/15 16:36, Steve Capper wrote: > On 15 October 2015 at 15:48, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote: >> On 15/10/15 15:06, Mark Rutland wrote: >>> >>> Hi, >>> >> >> I have fixed all the nits locally. Thanks for pointing them out. >> >>>> config FORCE_MAX_ZONEORDER >>>> int >>>> default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE) >>>> + default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE) >>>> default "11" >>> >>> >>> I'm a little lost here. How are these numbers derived? >>> >> >> I struggled to find the right value for 16K. Thanks to Steve Capper >> for the following explanation. I will add it as a comment. >> >> All allocations from the buddy allocator have to have compound order >> strictly less than MAX_ORDER. i.e, the maximum allocation size is >> (MAX_ORDER - 1) PAGES. To align with the transparent huge page size, >> we get : >> >> (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT >> >> Which gives us: >> >> MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1 >> = PAGE_SHIFT - 2 >> >> That raises an interesting question about the selection of the value >> for 4K. Shouldn't that be 10 instead of 11 ? >> >> Steve ? > > Hi, > My understanding is that 11 is a "good minimum" value for the page > allocator with 4KB pages. > (There are references to it being 10 in 2.4 kernels but raised to 11 > on 2.6 kernels?) > > We need to raise the minimum when we have a 16KB or 64KB PAGE_SIZE to > be able allocate a 32MB or 512MB Transparent HugePages. > Thanks Steve, for the clarification. I will add the following comment to the Kconfig # # All allocations from the buddy allocator have to have compound order # strictly less than MAX_ORDER. i.e, the maximum allocation size is # (MAX_ORDER - 1) PAGES. To align with the transparent huge page size, # we get : # # (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT # # Which gives us: # # MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1 # = PAGE_SHIFT - 2 # # However for 4K, we choose a higher default value 11 as opposed to 10, (giving us size 4M) # matching the default value used by the generic code. # Thanks Suzuki
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 13b51a0..e78045c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -173,7 +173,8 @@ config PGTABLE_LEVELS default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42 default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48 default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39 - default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48 + default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47 + default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48 source "init/Kconfig" @@ -363,6 +364,13 @@ config ARM64_4K_PAGES help This feature enables 4KB pages support. +config ARM64_16K_PAGES + bool "16KB" + help + The system will use 16KB pages support. AArch32 emulation + requires applications compiled with 16K(or multiple of 16K) + aligned segments. + config ARM64_64K_PAGES bool "64KB" help @@ -376,6 +384,7 @@ endchoice choice prompt "Virtual address space size" default ARM64_VA_BITS_39 if ARM64_4K_PAGES + default ARM64_VA_BITS_47 if ARM64_16K_PAGES default ARM64_VA_BITS_42 if ARM64_64K_PAGES help Allows choosing one of multiple possible virtual address @@ -390,6 +399,10 @@ config ARM64_VA_BITS_42 bool "42-bit" depends on ARM64_64K_PAGES +config ARM64_VA_BITS_47 + bool "47-bit" + depends on ARM64_16K_PAGES + config ARM64_VA_BITS_48 bool "48-bit" @@ -399,6 +412,7 @@ config ARM64_VA_BITS int default 39 if ARM64_VA_BITS_39 default 42 if ARM64_VA_BITS_42 + default 47 if ARM64_VA_BITS_47 default 48 if ARM64_VA_BITS_48 config CPU_BIG_ENDIAN @@ -466,7 +480,7 @@ config ARCH_WANT_GENERAL_HUGETLB def_bool y config ARCH_WANT_HUGE_PMD_SHARE - def_bool y if ARM64_4K_PAGES + def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES config HAVE_ARCH_TRANSPARENT_HUGEPAGE def_bool y @@ -503,6 +517,7 @@ config XEN config FORCE_MAX_ZONEORDER int default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE) + default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE) default "11" menuconfig ARMV8_DEPRECATED @@ -689,9 +704,9 @@ config COMPAT the user helper functions, VFP support and the ptrace interface are handled appropriately by the kernel. - If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you - will only be able to execute AArch32 binaries that were compiled with - 64k aligned segments. + If you use a page size other than 4KB(i.e, 16KB or 64KB), please be aware + that you will only be able to execute AArch32 binaries that were compiled + with page size aligned segments. If you want to execute 32-bit userspace applications, say Y. diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h index 8b9884c..a294c70 100644 --- a/arch/arm64/include/asm/fixmap.h +++ b/arch/arm64/include/asm/fixmap.h @@ -55,8 +55,10 @@ enum fixed_addresses { * Temporary boot-time mappings, used by early_ioremap(), * before ioremap() is functional. */ -#ifdef CONFIG_ARM64_64K_PAGES +#if defined(CONFIG_ARM64_64K_PAGES) #define NR_FIX_BTMAPS 4 +#elif defined (CONFIG_ARM64_16K_PAGES) +#define NR_FIX_BTMAPS 16 #else #define NR_FIX_BTMAPS 64 #endif diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index da32354..736ed4c 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -24,6 +24,9 @@ #ifdef CONFIG_ARM64_64K_PAGES #define PAGE_SHIFT 16 #define CONT_SHIFT 5 +#elif defined(CONFIG_ARM64_16K_PAGES) +#define PAGE_SHIFT 14 +#define CONT_SHIFT 9 #else #define PAGE_SHIFT 12 #define CONT_SHIFT 4 diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 5eac6a2..90c7ff2 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -25,6 +25,8 @@ #ifdef CONFIG_ARM64_4K_PAGES #define THREAD_SIZE_ORDER 2 +#elif defined(CONFIG_ARM64_16K_PAGES) +#define THREAD_SIZE_ORDER 0 #endif #define THREAD_SIZE 16384 diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index b6aa9e0..2ed57a8 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -624,7 +624,12 @@ ENDPROC(__secondary_switched) #define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN64_SHIFT #define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN64_ON -#else +#elif defined(CONFIG_ARM64_16K_PAGES) + +#define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN16_SHIFT +#define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN16_ON + +#elif defined(CONFIG_ARM64_4K_PAGES) #define id_aa64mmfr0_tgran_shift ID_AA64MMFR0_TGRAN4_SHIFT #define id_aa64mmfr0_tgran_on ID_AA64MMFR0_TGRAN4_ON diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 5c7e920..6a7d5cd 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -19,6 +19,7 @@ if VIRTUALIZATION config KVM bool "Kernel-based Virtual Machine (KVM) support" depends on OF + depends on !ARM64_16K_PAGES select MMU_NOTIFIER select PREEMPT_NOTIFIERS select ANON_INODES @@ -33,6 +34,8 @@ config KVM select HAVE_KVM_IRQFD ---help--- Support hosting virtualized guest machines. + We don't support KVM with 16K page tables yet, due to the multiple + levels of fake page tables. If unsure, say N. diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 91cb2ea..3a4b8b1 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -30,7 +30,9 @@ #ifdef CONFIG_ARM64_64K_PAGES #define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K -#else +#elif defined(CONFIG_ARM64_16K_PAGES) +#define TCR_TG_FLAGS TCR_TG0_16K | TCR_TG1_16K +#else /* CONFIG_ARM64_4K_PAGES */ #define TCR_TG_FLAGS TCR_TG0_4K | TCR_TG1_4K #endif