Commit 6f4441ef authored by Jeremy Kerr's avatar Jeremy Kerr Committed by Benjamin Herrenschmidt

powerpc: Dynamically allocate slb_shadow from memblock

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: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 1a8f6f97
...@@ -99,12 +99,28 @@ static inline void free_lppacas(void) { } ...@@ -99,12 +99,28 @@ static inline void free_lppacas(void) { }
* 3 persistent SLBs are registered here. The buffer will be zero * 3 persistent SLBs are registered here. The buffer will be zero
* initially, hence will all be invaild until we actually write them. * initially, hence will all be invaild until we actually write them.
*/ */
static struct slb_shadow slb_shadow[] __cacheline_aligned = { static struct slb_shadow *slb_shadow;
[0 ... (NR_CPUS-1)] = {
.persistent = cpu_to_be32(SLB_NUM_BOLTED), static void __init allocate_slb_shadows(int nr_cpus, int limit)
.buffer_length = cpu_to_be32(sizeof(struct slb_shadow)), {
}, 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 */ #endif /* CONFIG_PPC_STD_MMU_64 */
...@@ -142,7 +158,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) ...@@ -142,7 +158,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
new_paca->__current = &init_task; new_paca->__current = &init_task;
new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL; new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL;
#ifdef CONFIG_PPC_STD_MMU_64 #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 */ #endif /* CONFIG_PPC_STD_MMU_64 */
} }
...@@ -190,6 +206,8 @@ void __init allocate_pacas(void) ...@@ -190,6 +206,8 @@ void __init allocate_pacas(void)
allocate_lppacas(nr_cpu_ids, limit); 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 */ /* Can't use for_each_*_cpu, as they aren't functional yet */
for (cpu = 0; cpu < nr_cpu_ids; cpu++) for (cpu = 0; cpu < nr_cpu_ids; cpu++)
initialise_paca(&paca[cpu], cpu); initialise_paca(&paca[cpu], cpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment