aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-01-25 08:26:50 -0500
committerTejun Heo <tj@kernel.org>2011-01-25 08:26:50 -0500
commit19df0c2fef010e94e90df514aaf4e73f6b80145c (patch)
tree4b0b9c10622aead0d8b658cca6c49090149a91a8
parentc723fdab8aa728dc2bf0da6a0de8bb9c3f588d84 (diff)
percpu: align percpu readmostly subsection to cacheline
Currently percpu readmostly subsection may share cachelines with other percpu subsections which may result in unnecessary cacheline bounce and performance degradation. This patch adds @cacheline parameter to PERCPU() and PERCPU_VADDR() linker macros, makes each arch linker scripts specify its cacheline size and use it to align percpu subsections. This is based on Shaohua's x86 only patch. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Shaohua Li <shaohua.li@intel.com>
-rw-r--r--arch/alpha/kernel/vmlinux.lds.S2
-rw-r--r--arch/arm/kernel/vmlinux.lds.S2
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S2
-rw-r--r--arch/cris/kernel/vmlinux.lds.S2
-rw-r--r--arch/frv/kernel/vmlinux.lds.S2
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S2
-rw-r--r--arch/m32r/kernel/vmlinux.lds.S2
-rw-r--r--arch/mips/kernel/vmlinux.lds.S2
-rw-r--r--arch/mn10300/kernel/vmlinux.lds.S2
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S2
-rw-r--r--arch/s390/kernel/vmlinux.lds.S2
-rw-r--r--arch/sh/kernel/vmlinux.lds.S2
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S2
-rw-r--r--arch/tile/kernel/vmlinux.lds.S2
-rw-r--r--arch/um/include/asm/common.lds.S2
-rw-r--r--arch/x86/kernel/vmlinux.lds.S4
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S2
-rw-r--r--include/asm-generic/vmlinux.lds.h35
19 files changed, 41 insertions, 32 deletions
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 003ef4c02585..173518f8c8bb 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -38,7 +38,7 @@ SECTIONS
38 __init_begin = ALIGN(PAGE_SIZE); 38 __init_begin = ALIGN(PAGE_SIZE);
39 INIT_TEXT_SECTION(PAGE_SIZE) 39 INIT_TEXT_SECTION(PAGE_SIZE)
40 INIT_DATA_SECTION(16) 40 INIT_DATA_SECTION(16)
41 PERCPU(PAGE_SIZE) 41 PERCPU(64, PAGE_SIZE)
42 /* Align to THREAD_SIZE rather than PAGE_SIZE here so any padding page 42 /* Align to THREAD_SIZE rather than PAGE_SIZE here so any padding page
43 needed for the THREAD_SIZE aligned init_task gets freed after init */ 43 needed for the THREAD_SIZE aligned init_task gets freed after init */
44 . = ALIGN(THREAD_SIZE); 44 . = ALIGN(THREAD_SIZE);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 86b66f3f2031..cf78a03bf810 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -70,7 +70,7 @@ SECTIONS
70#endif 70#endif
71 } 71 }
72 72
73 PERCPU(PAGE_SIZE) 73 PERCPU(32, PAGE_SIZE)
74 74
75#ifndef CONFIG_XIP_KERNEL 75#ifndef CONFIG_XIP_KERNEL
76 . = ALIGN(PAGE_SIZE); 76 . = ALIGN(PAGE_SIZE);
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 4122678529c0..c40d07f708e8 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -136,7 +136,7 @@ SECTIONS
136 136
137 . = ALIGN(16); 137 . = ALIGN(16);
138 INIT_DATA_SECTION(16) 138 INIT_DATA_SECTION(16)
139 PERCPU(4) 139 PERCPU(32, 4)
140 140
141 .exit.data : 141 .exit.data :
142 { 142 {
diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S
index 442218980db0..c62e1346f47c 100644
--- a/arch/cris/kernel/vmlinux.lds.S
+++ b/arch/cris/kernel/vmlinux.lds.S
@@ -107,7 +107,7 @@ SECTIONS
107#endif 107#endif
108 __vmlinux_end = .; /* Last address of the physical file. */ 108 __vmlinux_end = .; /* Last address of the physical file. */
109#ifdef CONFIG_ETRAX_ARCH_V32 109#ifdef CONFIG_ETRAX_ARCH_V32
110 PERCPU(PAGE_SIZE) 110 PERCPU(32, PAGE_SIZE)
111 111
112 .init.ramfs : { 112 .init.ramfs : {
113 INIT_RAM_FS 113 INIT_RAM_FS
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index 8b973f3cc90e..0daae8af5787 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -37,7 +37,7 @@ SECTIONS
37 _einittext = .; 37 _einittext = .;
38 38
39 INIT_DATA_SECTION(8) 39 INIT_DATA_SECTION(8)
40 PERCPU(4096) 40 PERCPU(L1_CACHE_BYTES, 4096)
41 41
42 . = ALIGN(PAGE_SIZE); 42 . = ALIGN(PAGE_SIZE);
43 __init_end = .; 43 __init_end = .;
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 5a4d044dcb1c..787de4a77d82 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -198,7 +198,7 @@ SECTIONS {
198 198
199 /* Per-cpu data: */ 199 /* Per-cpu data: */
200 . = ALIGN(PERCPU_PAGE_SIZE); 200 . = ALIGN(PERCPU_PAGE_SIZE);
201 PERCPU_VADDR(PERCPU_ADDR, :percpu) 201 PERCPU_VADDR(SMP_CACHE_BYTES, PERCPU_ADDR, :percpu)
202 __phys_per_cpu_start = __per_cpu_load; 202 __phys_per_cpu_start = __per_cpu_load;
203 /* 203 /*
204 * ensure percpu data fits 204 * ensure percpu data fits
diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S
index 7da94eaa082b..c194d64cdbb9 100644
--- a/arch/m32r/kernel/vmlinux.lds.S
+++ b/arch/m32r/kernel/vmlinux.lds.S
@@ -53,7 +53,7 @@ SECTIONS
53 __init_begin = .; 53 __init_begin = .;
54 INIT_TEXT_SECTION(PAGE_SIZE) 54 INIT_TEXT_SECTION(PAGE_SIZE)
55 INIT_DATA_SECTION(16) 55 INIT_DATA_SECTION(16)
56 PERCPU(PAGE_SIZE) 56 PERCPU(32, PAGE_SIZE)
57 . = ALIGN(PAGE_SIZE); 57 . = ALIGN(PAGE_SIZE);
58 __init_end = .; 58 __init_end = .;
59 /* freed after init ends here */ 59 /* freed after init ends here */
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 570607b376b5..832afbb87588 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -115,7 +115,7 @@ SECTIONS
115 EXIT_DATA 115 EXIT_DATA
116 } 116 }
117 117
118 PERCPU(PAGE_SIZE) 118 PERCPU(1 << CONFIG_MIPS_L1_CACHE_SHIFT, PAGE_SIZE)
119 . = ALIGN(PAGE_SIZE); 119 . = ALIGN(PAGE_SIZE);
120 __init_end = .; 120 __init_end = .;
121 /* freed after init ends here */ 121 /* freed after init ends here */
diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S
index febbeee7f2f5..968bcd2cb022 100644
--- a/arch/mn10300/kernel/vmlinux.lds.S
+++ b/arch/mn10300/kernel/vmlinux.lds.S
@@ -70,7 +70,7 @@ SECTIONS
70 .exit.text : { EXIT_TEXT; } 70 .exit.text : { EXIT_TEXT; }
71 .exit.data : { EXIT_DATA; } 71 .exit.data : { EXIT_DATA; }
72 72
73 PERCPU(PAGE_SIZE) 73 PERCPU(32, PAGE_SIZE)
74 . = ALIGN(PAGE_SIZE); 74 . = ALIGN(PAGE_SIZE);
75 __init_end = .; 75 __init_end = .;
76 /* freed after init ends here */ 76 /* freed after init ends here */
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index d64a6bbec2aa..8f1e4efd143e 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -145,7 +145,7 @@ SECTIONS
145 EXIT_DATA 145 EXIT_DATA
146 } 146 }
147 147
148 PERCPU(PAGE_SIZE) 148 PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
149 . = ALIGN(PAGE_SIZE); 149 . = ALIGN(PAGE_SIZE);
150 __init_end = .; 150 __init_end = .;
151 /* freed after init ends here */ 151 /* freed after init ends here */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 8a0deefac08d..b9150f07d266 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -160,7 +160,7 @@ SECTIONS
160 INIT_RAM_FS 160 INIT_RAM_FS
161 } 161 }
162 162
163 PERCPU(PAGE_SIZE) 163 PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
164 164
165 . = ALIGN(8); 165 . = ALIGN(8);
166 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) { 166 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index a68ac10213b2..1bc18cdb525b 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -77,7 +77,7 @@ SECTIONS
77 . = ALIGN(PAGE_SIZE); 77 . = ALIGN(PAGE_SIZE);
78 INIT_DATA_SECTION(0x100) 78 INIT_DATA_SECTION(0x100)
79 79
80 PERCPU(PAGE_SIZE) 80 PERCPU(0x100, PAGE_SIZE)
81 . = ALIGN(PAGE_SIZE); 81 . = ALIGN(PAGE_SIZE);
82 __init_end = .; /* freed after init ends here */ 82 __init_end = .; /* freed after init ends here */
83 83
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 7f8a709c3ada..af4d46187a79 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -66,7 +66,7 @@ SECTIONS
66 __machvec_end = .; 66 __machvec_end = .;
67 } 67 }
68 68
69 PERCPU(PAGE_SIZE) 69 PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
70 70
71 /* 71 /*
72 * .exit.text is discarded at runtime, not link time, to deal with 72 * .exit.text is discarded at runtime, not link time, to deal with
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 0c1e6783657f..92b557afe535 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -108,7 +108,7 @@ SECTIONS
108 __sun4v_2insn_patch_end = .; 108 __sun4v_2insn_patch_end = .;
109 } 109 }
110 110
111 PERCPU(PAGE_SIZE) 111 PERCPU(SMP_CACHE_BYTES, PAGE_SIZE)
112 112
113 . = ALIGN(PAGE_SIZE); 113 . = ALIGN(PAGE_SIZE);
114 __init_end = .; 114 __init_end = .;
diff --git a/arch/tile/kernel/vmlinux.lds.S b/arch/tile/kernel/vmlinux.lds.S
index 25fdc0c1839a..c6ce378e0678 100644
--- a/arch/tile/kernel/vmlinux.lds.S
+++ b/arch/tile/kernel/vmlinux.lds.S
@@ -63,7 +63,7 @@ SECTIONS
63 *(.init.page) 63 *(.init.page)
64 } :data =0 64 } :data =0
65 INIT_DATA_SECTION(16) 65 INIT_DATA_SECTION(16)
66 PERCPU(PAGE_SIZE) 66 PERCPU(L2_CACHE_BYTES, PAGE_SIZE)
67 . = ALIGN(PAGE_SIZE); 67 . = ALIGN(PAGE_SIZE);
68 VMLINUX_SYMBOL(_einitdata) = .; 68 VMLINUX_SYMBOL(_einitdata) = .;
69 69
diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S
index ac55b9efa1ce..34bede8aad4a 100644
--- a/arch/um/include/asm/common.lds.S
+++ b/arch/um/include/asm/common.lds.S
@@ -42,7 +42,7 @@
42 INIT_SETUP(0) 42 INIT_SETUP(0)
43 } 43 }
44 44
45 PERCPU(32) 45 PERCPU(32, 32)
46 46
47 .initcall.init : { 47 .initcall.init : {
48 INIT_CALLS 48 INIT_CALLS
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index bf4700755184..cef446f8ac78 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -230,7 +230,7 @@ SECTIONS
230 * output PHDR, so the next output section - .init.text - should 230 * output PHDR, so the next output section - .init.text - should
231 * start another segment - init. 231 * start another segment - init.
232 */ 232 */
233 PERCPU_VADDR(0, :percpu) 233 PERCPU_VADDR(INTERNODE_CACHE_BYTES, 0, :percpu)
234#endif 234#endif
235 235
236 INIT_TEXT_SECTION(PAGE_SIZE) 236 INIT_TEXT_SECTION(PAGE_SIZE)
@@ -305,7 +305,7 @@ SECTIONS
305 } 305 }
306 306
307#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP) 307#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
308 PERCPU(THREAD_SIZE) 308 PERCPU(INTERNODE_CACHE_BYTES, THREAD_SIZE)
309#endif 309#endif
310 310
311 . = ALIGN(PAGE_SIZE); 311 . = ALIGN(PAGE_SIZE);
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index 9b526154c9ba..a2820065927e 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -155,7 +155,7 @@ SECTIONS
155 INIT_RAM_FS 155 INIT_RAM_FS
156 } 156 }
157 157
158 PERCPU(PAGE_SIZE) 158 PERCPU(XCHAL_ICACHE_LINESIZE, PAGE_SIZE)
159 159
160 /* We need this dummy segment here */ 160 /* We need this dummy segment here */
161 161
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6ebb81030d2d..439df587c12c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -15,7 +15,7 @@
15 * HEAD_TEXT_SECTION 15 * HEAD_TEXT_SECTION
16 * INIT_TEXT_SECTION(PAGE_SIZE) 16 * INIT_TEXT_SECTION(PAGE_SIZE)
17 * INIT_DATA_SECTION(...) 17 * INIT_DATA_SECTION(...)
18 * PERCPU(PAGE_SIZE) 18 * PERCPU(CACHELINE_SIZE, PAGE_SIZE)
19 * __init_end = .; 19 * __init_end = .;
20 * 20 *
21 * _stext = .; 21 * _stext = .;
@@ -683,13 +683,18 @@
683 683
684/** 684/**
685 * PERCPU_VADDR - define output section for percpu area 685 * PERCPU_VADDR - define output section for percpu area
686 * @cacheline: cacheline size
686 * @vaddr: explicit base address (optional) 687 * @vaddr: explicit base address (optional)
687 * @phdr: destination PHDR (optional) 688 * @phdr: destination PHDR (optional)
688 * 689 *
689 * Macro which expands to output section for percpu area. If @vaddr 690 * Macro which expands to output section for percpu area.
690 * is not blank, it specifies explicit base address and all percpu 691 *
691 * symbols will be offset from the given address. If blank, @vaddr 692 * @cacheline is used to align subsections to avoid false cacheline
692 * always equals @laddr + LOAD_OFFSET. 693 * sharing between subsections for different purposes.
694 *
695 * If @vaddr is not blank, it specifies explicit base address and all
696 * percpu symbols will be offset from the given address. If blank,
697 * @vaddr always equals @laddr + LOAD_OFFSET.
693 * 698 *
694 * @phdr defines the output PHDR to use if not blank. Be warned that 699 * @phdr defines the output PHDR to use if not blank. Be warned that
695 * output PHDR is sticky. If @phdr is specified, the next output 700 * output PHDR is sticky. If @phdr is specified, the next output
@@ -700,7 +705,7 @@
700 * If there is no need to put the percpu section at a predetermined 705 * If there is no need to put the percpu section at a predetermined
701 * address, use PERCPU(). 706 * address, use PERCPU().
702 */ 707 */
703#define PERCPU_VADDR(vaddr, phdr) \ 708#define PERCPU_VADDR(cacheline, vaddr, phdr) \
704 VMLINUX_SYMBOL(__per_cpu_load) = .; \ 709 VMLINUX_SYMBOL(__per_cpu_load) = .; \
705 .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ 710 .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
706 - LOAD_OFFSET) { \ 711 - LOAD_OFFSET) { \
@@ -708,7 +713,9 @@
708 *(.data..percpu..first) \ 713 *(.data..percpu..first) \
709 . = ALIGN(PAGE_SIZE); \ 714 . = ALIGN(PAGE_SIZE); \
710 *(.data..percpu..page_aligned) \ 715 *(.data..percpu..page_aligned) \
716 . = ALIGN(cacheline); \
711 *(.data..percpu..readmostly) \ 717 *(.data..percpu..readmostly) \
718 . = ALIGN(cacheline); \
712 *(.data..percpu) \ 719 *(.data..percpu) \
713 *(.data..percpu..shared_aligned) \ 720 *(.data..percpu..shared_aligned) \
714 VMLINUX_SYMBOL(__per_cpu_end) = .; \ 721 VMLINUX_SYMBOL(__per_cpu_end) = .; \
@@ -717,18 +724,18 @@
717 724
718/** 725/**
719 * PERCPU - define output section for percpu area, simple version 726 * PERCPU - define output section for percpu area, simple version
727 * @cacheline: cacheline size
720 * @align: required alignment 728 * @align: required alignment
721 * 729 *
722 * Align to @align and outputs output section for percpu area. This 730 * Align to @align and outputs output section for percpu area. This macro
723 * macro doesn't maniuplate @vaddr or @phdr and __per_cpu_load and 731 * doesn't manipulate @vaddr or @phdr and __per_cpu_load and
724 * __per_cpu_start will be identical. 732 * __per_cpu_start will be identical.
725 * 733 *
726 * This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except 734 * This macro is equivalent to ALIGN(@align); PERCPU_VADDR(@cacheline,,)
727 * that __per_cpu_load is defined as a relative symbol against 735 * except that __per_cpu_load is defined as a relative symbol against
728 * .data..percpu which is required for relocatable x86_32 736 * .data..percpu which is required for relocatable x86_32 configuration.
729 * configuration.
730 */ 737 */
731#define PERCPU(align) \ 738#define PERCPU(cacheline, align) \
732 . = ALIGN(align); \ 739 . = ALIGN(align); \
733 .data..percpu : AT(ADDR(.data..percpu) - LOAD_OFFSET) { \ 740 .data..percpu : AT(ADDR(.data..percpu) - LOAD_OFFSET) { \
734 VMLINUX_SYMBOL(__per_cpu_load) = .; \ 741 VMLINUX_SYMBOL(__per_cpu_load) = .; \
@@ -736,7 +743,9 @@
736 *(.data..percpu..first) \ 743 *(.data..percpu..first) \
737 . = ALIGN(PAGE_SIZE); \ 744 . = ALIGN(PAGE_SIZE); \
738 *(.data..percpu..page_aligned) \ 745 *(.data..percpu..page_aligned) \
746 . = ALIGN(cacheline); \
739 *(.data..percpu..readmostly) \ 747 *(.data..percpu..readmostly) \
748 . = ALIGN(cacheline); \
740 *(.data..percpu) \ 749 *(.data..percpu) \
741 *(.data..percpu..shared_aligned) \ 750 *(.data..percpu..shared_aligned) \
742 VMLINUX_SYMBOL(__per_cpu_end) = .; \ 751 VMLINUX_SYMBOL(__per_cpu_end) = .; \