diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2008-05-12 09:44:40 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-25 01:03:46 -0400 |
commit | 63cc8c75156462d4b42cbdd76c293b7eee7ddbfe (patch) | |
tree | e014b4c61399f8f74347352e6ea76ddf1502dcfa | |
parent | 75d3bce2fc0a80f435fe12f2c9ed2632c8ac29e4 (diff) |
percpu: introduce DEFINE_PER_CPU_PAGE_ALIGNED() macro
While examining holes in percpu section I found this :
c05f5000 D per_cpu__current_task
c05f5000 D __per_cpu_start
c05f5004 D per_cpu__cpu_number
c05f5008 D per_cpu__irq_regs
c05f500c d per_cpu__cpu_devices
c05f5040 D per_cpu__cyc2ns
<Big Hole of about 4000 bytes>
c05f6000 d per_cpu__cpuid4_info
c05f6004 d per_cpu__cache_kobject
c05f6008 d per_cpu__index_kobject
<Big Hole of about 4000 bytes>
c05f7000 D per_cpu__gdt_page
This is because gdt_page is a percpu variable, defined with
a page alignement, and linker is doing its job, two times because of .o
nesting in the build process.
I introduced a new macro DEFINE_PER_CPU_PAGE_ALIGNED() to avoid
wasting this space. All page aligned variables (only one at this time)
are put in a separate
subsection .data.percpu.page_aligned, at the very begining of percpu zone.
Before patch , on a x86_32 machine :
.data.percpu 30232 3227471872
.data.percpu 22168 3227471872
Thats 8064 bytes saved for each CPU.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/vmlinux_32.lds.S | 1 | ||||
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 1 | ||||
-rw-r--r-- | include/linux/percpu.h | 7 |
4 files changed, 10 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index d0463a946247..b2f54fafb8bc 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include "cpu.h" | 22 | #include "cpu.h" |
23 | 23 | ||
24 | DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { | 24 | DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { |
25 | [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, | 25 | [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, |
26 | [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, | 26 | [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, |
27 | [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, | 27 | [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, |
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S index ce5ed083a1e9..0f7c29a8c4ea 100644 --- a/arch/x86/kernel/vmlinux_32.lds.S +++ b/arch/x86/kernel/vmlinux_32.lds.S | |||
@@ -189,6 +189,7 @@ SECTIONS | |||
189 | . = ALIGN(PAGE_SIZE); | 189 | . = ALIGN(PAGE_SIZE); |
190 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { | 190 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { |
191 | __per_cpu_start = .; | 191 | __per_cpu_start = .; |
192 | *(.data.percpu.page_aligned) | ||
192 | *(.data.percpu) | 193 | *(.data.percpu) |
193 | *(.data.percpu.shared_aligned) | 194 | *(.data.percpu.shared_aligned) |
194 | __per_cpu_end = .; | 195 | __per_cpu_end = .; |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index f054778e916c..69e5c1182fde 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -348,6 +348,7 @@ | |||
348 | . = ALIGN(align); \ | 348 | . = ALIGN(align); \ |
349 | __per_cpu_start = .; \ | 349 | __per_cpu_start = .; \ |
350 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \ | 350 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \ |
351 | *(.data.percpu.page_aligned) \ | ||
351 | *(.data.percpu) \ | 352 | *(.data.percpu) \ |
352 | *(.data.percpu.shared_aligned) \ | 353 | *(.data.percpu.shared_aligned) \ |
353 | } \ | 354 | } \ |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 4cdd393e71e1..2edacc8e6b8b 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -23,12 +23,19 @@ | |||
23 | __attribute__((__section__(SHARED_ALIGNED_SECTION))) \ | 23 | __attribute__((__section__(SHARED_ALIGNED_SECTION))) \ |
24 | PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \ | 24 | PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \ |
25 | ____cacheline_aligned_in_smp | 25 | ____cacheline_aligned_in_smp |
26 | |||
27 | #define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ | ||
28 | __attribute__((__section__(".data.percpu.page_aligned"))) \ | ||
29 | PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name | ||
26 | #else | 30 | #else |
27 | #define DEFINE_PER_CPU(type, name) \ | 31 | #define DEFINE_PER_CPU(type, name) \ |
28 | PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name | 32 | PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name |
29 | 33 | ||
30 | #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ | 34 | #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ |
31 | DEFINE_PER_CPU(type, name) | 35 | DEFINE_PER_CPU(type, name) |
36 | |||
37 | #define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ | ||
38 | DEFINE_PER_CPU(type, name) | ||
32 | #endif | 39 | #endif |
33 | 40 | ||
34 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) | 41 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) |