diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2013-12-04 22:42:40 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-12-08 19:40:26 -0500 |
commit | 6f4441ef7009b9ec063678d906eb762318689494 (patch) | |
tree | 1915c5320503665a0a1dedf24b8c97a88caccc64 | |
parent | 1a8f6f97ea4dbaaa21b05cae2dacea47e4aea37b (diff) |
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: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/kernel/paca.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 9095a6f7ac2c..623c356fe34f 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -99,12 +99,28 @@ static inline void free_lppacas(void) { } | |||
99 | * 3 persistent SLBs are registered here. The buffer will be zero | 99 | * 3 persistent SLBs are registered here. The buffer will be zero |
100 | * initially, hence will all be invaild until we actually write them. | 100 | * initially, hence will all be invaild until we actually write them. |
101 | */ | 101 | */ |
102 | static struct slb_shadow slb_shadow[] __cacheline_aligned = { | 102 | static struct slb_shadow *slb_shadow; |
103 | [0 ... (NR_CPUS-1)] = { | 103 | |
104 | .persistent = cpu_to_be32(SLB_NUM_BOLTED), | 104 | static void __init allocate_slb_shadows(int nr_cpus, int limit) |
105 | .buffer_length = cpu_to_be32(sizeof(struct slb_shadow)), | 105 | { |
106 | }, | 106 | int size = PAGE_ALIGN(sizeof(struct slb_shadow) * nr_cpus); |
107 | }; | 107 | slb_shadow = __va(memblock_alloc_base(size, PAGE_SIZE, limit)); |
108 | memset(slb_shadow, 0, size); | ||
109 | } | ||
110 | |||
111 | static struct slb_shadow * __init init_slb_shadow(int cpu) | ||
112 | { | ||
113 | struct slb_shadow *s = &slb_shadow[cpu]; | ||
114 | |||
115 | s->persistent = cpu_to_be32(SLB_NUM_BOLTED); | ||
116 | s->buffer_length = cpu_to_be32(sizeof(*s)); | ||
117 | |||
118 | return s; | ||
119 | } | ||
120 | |||
121 | #else /* CONFIG_PPC_STD_MMU_64 */ | ||
122 | |||
123 | static void __init allocate_slb_shadows(int nr_cpus, int limit) { } | ||
108 | 124 | ||
109 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 125 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
110 | 126 | ||
@@ -142,7 +158,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) | |||
142 | new_paca->__current = &init_task; | 158 | new_paca->__current = &init_task; |
143 | new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL; | 159 | new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL; |
144 | #ifdef CONFIG_PPC_STD_MMU_64 | 160 | #ifdef CONFIG_PPC_STD_MMU_64 |
145 | new_paca->slb_shadow_ptr = &slb_shadow[cpu]; | 161 | new_paca->slb_shadow_ptr = init_slb_shadow(cpu); |
146 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 162 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
147 | } | 163 | } |
148 | 164 | ||
@@ -190,6 +206,8 @@ void __init allocate_pacas(void) | |||
190 | 206 | ||
191 | allocate_lppacas(nr_cpu_ids, limit); | 207 | allocate_lppacas(nr_cpu_ids, limit); |
192 | 208 | ||
209 | allocate_slb_shadows(nr_cpu_ids, limit); | ||
210 | |||
193 | /* Can't use for_each_*_cpu, as they aren't functional yet */ | 211 | /* Can't use for_each_*_cpu, as they aren't functional yet */ |
194 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) | 212 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) |
195 | initialise_paca(&paca[cpu], cpu); | 213 | initialise_paca(&paca[cpu], cpu); |