* [PATCH 1/2] arch/powerpc: Make slb_shadow a local @ 2013-12-05 3:31 Jeremy Kerr 2013-12-05 3:31 ` [PATCH 2/2] arch/powerpc: Dynamically allocate slb_shadow from memblock Jeremy Kerr 0 siblings, 1 reply; 3+ messages in thread From: Jeremy Kerr @ 2013-12-05 3:31 UTC (permalink / raw) To: linuxppc-dev; +Cc: Michael Neuling The only external user of slb_shadow is the pseries lpar code, and it can access through the paca array instead. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> --- arch/powerpc/include/asm/lppaca.h | 2 -- arch/powerpc/kernel/paca.c | 2 +- arch/powerpc/platforms/pseries/lpar.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 844c28de..d0a2a2f9 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -132,8 +132,6 @@ struct slb_shadow { } save_area[SLB_NUM_BOLTED]; } ____cacheline_aligned; -extern struct slb_shadow slb_shadow[]; - /* * Layout of entries in the hypervisor's dispatch trace log buffer. */ diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 0620eaaa..9095a6f7 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -99,7 +99,7 @@ static inline void free_lppacas(void) { } * 3 persistent SLBs are registered here. The buffer will be zero * initially, hence will all be invaild until we actually write them. */ -struct slb_shadow slb_shadow[] __cacheline_aligned = { +static struct slb_shadow slb_shadow[] __cacheline_aligned = { [0 ... (NR_CPUS-1)] = { .persistent = cpu_to_be32(SLB_NUM_BOLTED), .buffer_length = cpu_to_be32(sizeof(struct slb_shadow)), diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 4fca3def..28cf0f33 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -92,7 +92,7 @@ void vpa_init(int cpu) * PAPR says this feature is SLB-Buffer but firmware never * reports that. All SPLPAR support SLB shadow buffer. */ - addr = __pa(&slb_shadow[cpu]); + addr = __pa(paca[cpu].slb_shadow_ptr); if (firmware_has_feature(FW_FEATURE_SPLPAR)) { ret = register_slb_shadow(hwcpu, addr); if (ret) ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] arch/powerpc: Dynamically allocate slb_shadow from memblock 2013-12-05 3:31 [PATCH 1/2] arch/powerpc: Make slb_shadow a local Jeremy Kerr @ 2013-12-05 3:31 ` Jeremy Kerr 2013-12-05 3:42 ` [PATCH v2] " Jeremy Kerr 0 siblings, 1 reply; 3+ messages in thread From: Jeremy Kerr @ 2013-12-05 3:31 UTC (permalink / raw) To: linuxppc-dev; +Cc: Michael Neuling Currently, the slb_shadow buffer is our largest symbol: [jk@pablo linux]$ nm --size-sort -r -S obj/vmlinux | head -1 c000000000da0000 0000000000040000 d slb_shadow - we allocate 128 bytes per cpu; so 256k with NR_CPUS=2048. As we have constant initialisers, it's allocated in .text, causing a larger vmlinux image. We may also allocate unecessary slb_shadow buffers (> no. pacas), since we use the build-time NR_CPUS rather than the run-time nr_cpu_ids. We could move this to the bss, but then we still have the NR_CPUS vs nr_cpu_ids potential for overallocation. This change dynamically allocates the slb_shadow array, during initialise_pacas(). At a cost of 104 bytes of text, we save 256k of data: [jk@pablo linux]$ size obj/vmlinux{.orig,} text data bss dec hex filename 9202795 5244676 1169576 15617047 ee4c17 obj/vmlinux.orig 9202899 4982532 1169576 15355007 ea4c7f obj/vmlinux Tested on pseries. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> --- arch/powerpc/kernel/paca.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 9095a6f7..ad7a485f 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -99,12 +99,28 @@ static inline void free_lppacas(void) { } * 3 persistent SLBs are registered here. The buffer will be zero * initially, hence will all be invaild until we actually write them. */ -static struct slb_shadow slb_shadow[] __cacheline_aligned = { - [0 ... (NR_CPUS-1)] = { - .persistent = cpu_to_be32(SLB_NUM_BOLTED), - .buffer_length = cpu_to_be32(sizeof(struct slb_shadow)), - }, -}; +static struct slb_shadow *slb_shadow; + +static void __init allocate_slb_shadows(int nr_cpus, int limit) +{ + int size = PAGE_ALIGN(sizeof(struct slb_shadow) * nr_cpus); + slb_shadow = __va(memblock_alloc_base(size, PAGE_SIZE, limit)); + memset(slb_shadow, 0, size); +} + +static struct slb_shadow * __init init_slb_shadow(int cpu) +{ + struct slb_shadow *s = &slb_shadow[cpu]; + + s->persistent = ARRAY_SIZE(s->save_area); + s->buffer_length = sizeof(*s); + + return s; +} + +#else /* CONFIG_PPC_STD_MMU_64 */ + +static void __init allocate_slb_shadows(int nr_cpus, int limit) { } #endif /* CONFIG_PPC_STD_MMU_64 */ @@ -142,7 +158,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) new_paca->__current = &init_task; new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL; #ifdef CONFIG_PPC_STD_MMU_64 - new_paca->slb_shadow_ptr = &slb_shadow[cpu]; + new_paca->slb_shadow_ptr = init_slb_shadow(cpu); #endif /* CONFIG_PPC_STD_MMU_64 */ } @@ -190,6 +206,8 @@ void __init allocate_pacas(void) allocate_lppacas(nr_cpu_ids, limit); + allocate_slb_shadows(nr_cpu_ids, limit); + /* Can't use for_each_*_cpu, as they aren't functional yet */ for (cpu = 0; cpu < nr_cpu_ids; cpu++) initialise_paca(&paca[cpu], cpu); ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2] arch/powerpc: Dynamically allocate slb_shadow from memblock 2013-12-05 3:31 ` [PATCH 2/2] arch/powerpc: Dynamically allocate slb_shadow from memblock Jeremy Kerr @ 2013-12-05 3:42 ` Jeremy Kerr 0 siblings, 0 replies; 3+ messages in thread From: Jeremy Kerr @ 2013-12-05 3:42 UTC (permalink / raw) To: linuxppc-dev; +Cc: Michael Neuling Currently, the slb_shadow buffer is our largest symbol: [jk@pablo linux]$ nm --size-sort -r -S obj/vmlinux | head -1 c000000000da0000 0000000000040000 d slb_shadow - we allocate 128 bytes per cpu; so 256k with NR_CPUS=2048. As we have constant initialisers, it's allocated in .text, causing a larger vmlinux image. We may also allocate unecessary slb_shadow buffers (> no. pacas), since we use the build-time NR_CPUS rather than the run-time nr_cpu_ids. We could move this to the bss, but then we still have the NR_CPUS vs nr_cpu_ids potential for overallocation. This change dynamically allocates the slb_shadow array, during initialise_pacas(). At a cost of 104 bytes of text, we save 256k of data: [jk@pablo linux]$ size obj/vmlinux{.orig,} text data bss dec hex filename 9202795 5244676 1169576 15617047 ee4c17 obj/vmlinux.orig 9202899 4982532 1169576 15355007 ea4c7f obj/vmlinux Tested on pseries. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> --- v2: don't drop the endian conversion, use SLB_NUM_BOLTED --- arch/powerpc/kernel/paca.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 9095a6f7..623c356f 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -99,12 +99,28 @@ static inline void free_lppacas(void) { } * 3 persistent SLBs are registered here. The buffer will be zero * initially, hence will all be invaild until we actually write them. */ -static struct slb_shadow slb_shadow[] __cacheline_aligned = { - [0 ... (NR_CPUS-1)] = { - .persistent = cpu_to_be32(SLB_NUM_BOLTED), - .buffer_length = cpu_to_be32(sizeof(struct slb_shadow)), - }, -}; +static struct slb_shadow *slb_shadow; + +static void __init allocate_slb_shadows(int nr_cpus, int limit) +{ + int size = PAGE_ALIGN(sizeof(struct slb_shadow) * nr_cpus); + slb_shadow = __va(memblock_alloc_base(size, PAGE_SIZE, limit)); + memset(slb_shadow, 0, size); +} + +static struct slb_shadow * __init init_slb_shadow(int cpu) +{ + struct slb_shadow *s = &slb_shadow[cpu]; + + s->persistent = cpu_to_be32(SLB_NUM_BOLTED); + s->buffer_length = cpu_to_be32(sizeof(*s)); + + return s; +} + +#else /* CONFIG_PPC_STD_MMU_64 */ + +static void __init allocate_slb_shadows(int nr_cpus, int limit) { } #endif /* CONFIG_PPC_STD_MMU_64 */ @@ -142,7 +158,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) new_paca->__current = &init_task; new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL; #ifdef CONFIG_PPC_STD_MMU_64 - new_paca->slb_shadow_ptr = &slb_shadow[cpu]; + new_paca->slb_shadow_ptr = init_slb_shadow(cpu); #endif /* CONFIG_PPC_STD_MMU_64 */ } @@ -190,6 +206,8 @@ void __init allocate_pacas(void) allocate_lppacas(nr_cpu_ids, limit); + allocate_slb_shadows(nr_cpu_ids, limit); + /* Can't use for_each_*_cpu, as they aren't functional yet */ for (cpu = 0; cpu < nr_cpu_ids; cpu++) initialise_paca(&paca[cpu], cpu); ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-12-05 3:42 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-12-05 3:31 [PATCH 1/2] arch/powerpc: Make slb_shadow a local Jeremy Kerr 2013-12-05 3:31 ` [PATCH 2/2] arch/powerpc: Dynamically allocate slb_shadow from memblock Jeremy Kerr 2013-12-05 3:42 ` [PATCH v2] " Jeremy Kerr
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).