Allow percpu variables to be page-aligned
Subsystems (9)
PATCH 2/2 Allow percpu variables to be page-aligned
Let's allow page-alignment in general for per-cpu data (wanted by Xen, and Ingo suggested KVM as well).
Because larger alignments can use more room, we increase the max per-cpu memory to 64k rather than 32k: it's getting a little tight.
--- arch/alpha/kernel/vmlinux.lds.S | 2 +- arch/arm/kernel/vmlinux.lds.S | 2 +- arch/cris/arch-v32/vmlinux.lds.S | 1 + arch/frv/kernel/vmlinux.lds.S | 1 + arch/i386/kernel/vmlinux.lds.S | 2 +- arch/m32r/kernel/vmlinux.lds.S | 2 +- arch/mips/kernel/vmlinux.lds.S | 2 +- arch/parisc/kernel/vmlinux.lds.S | 2 +- arch/powerpc/kernel/setup_64.c | 4 ++-- arch/powerpc/kernel/vmlinux.lds.S | 6 +----- arch/ppc/kernel/vmlinux.lds.S | 2 +- arch/s390/kernel/vmlinux.lds.S | 2 +- arch/sh/kernel/vmlinux.lds.S | 2 +- arch/sh64/kernel/vmlinux.lds.S | 2 +- arch/sparc/kernel/vmlinux.lds.S | 2 +- arch/sparc64/kernel/smp.c | 6 +++--- arch/x86_64/kernel/setup64.c | 4 ++-- arch/x86_64/kernel/vmlinux.lds.S | 2 +- arch/xtensa/kernel/vmlinux.lds.S | 2 +- init/main.c | 4 ++-- kernel/module.c | 8 ++++---- 21 files changed, 29 insertions(+), 31 deletions(-)
===================================================================
arch/alpha/kernel/vmlinux.lds.S +1 -1
@@ -69,7 +69,7 @@ SECTIONS . = ALIGN(8); SECURITY_INIT - . = ALIGN(64); + . = ALIGN(8192); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/arm/kernel/vmlinux.lds.S +1 -1
@@ -59,7 +59,7 @@ SECTIONS usr/built-in.o(.init.ramfs) __initramfs_end = .; #endif - . = ALIGN(64); + . = ALIGN(4096); __per_cpu_start = .; *(.data.percpu) __per_cpu_end = .;
===================================================================
arch/cris/arch-v32/vmlinux.lds.S +1 -0
@@ -91,6 +91,7 @@ SECTIONS } SECURITY_INIT + . = ALIGN (8192); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/frv/kernel/vmlinux.lds.S +1 -0
@@ -57,6 +57,7 @@ SECTIONS __alt_instructions_end = .; .altinstr_replacement : { *(.altinstr_replacement) } + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/i386/kernel/vmlinux.lds.S +1 -1
@@ -194,7 +194,7 @@ SECTIONS __initramfs_end = .; } #endif - . = ALIGN(L1_CACHE_BYTES); + . = ALIGN(4096); .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { __per_cpu_start = .; *(.data.percpu)
===================================================================
arch/m32r/kernel/vmlinux.lds.S +1 -1
@@ -110,7 +110,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/mips/kernel/vmlinux.lds.S +1 -1
@@ -119,7 +119,7 @@ SECTIONS .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(_PAGE_SIZE); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/parisc/kernel/vmlinux.lds.S +1 -1
@@ -181,7 +181,7 @@ SECTIONS .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(ASM_PAGE_SIZE); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/powerpc/kernel/setup_64.c +2 -2
@@ -583,14 +583,14 @@ void __init setup_per_cpu_areas(void)char *ptr;/* Copy section for each CPU (we discard the original) */ - size =ALIGN (__per_cpu_end - __per_cpu_start,SMP_CACHE_BYTES ); + size =ALIGN (__per_cpu_end - __per_cpu_start,PAGE_SIZE );#ifdef CONFIG_MODULES if (size <PERCPU_ENOUGH_ROOM ) size =PERCPU_ENOUGH_ROOM ;#endif for_each_possible_cpu (i) { - ptr =alloc_bootmem_node (NODE_DATA (cpu_to_node (i)), size); + ptr =alloc_bootmem_pages_node (NODE_DATA (cpu_to_node (i)), size);if (!ptr)panic ("Cannot allocate cpu data for CPU %d\n" , i);
===================================================================
arch/powerpc/kernel/vmlinux.lds.S +1 -5
@@ -139,11 +139,7 @@ SECTIONS __initramfs_end = .; } #endif -#ifdef CONFIG_PPC32 - . = ALIGN(32); -#else - . = ALIGN(128); -#endif + . = ALIGN(PAGE_SIZE); .data.percpu : { __per_cpu_start = .; *(.data.percpu)
===================================================================
arch/ppc/kernel/vmlinux.lds.S +1 -1
@@ -130,7 +130,7 @@ SECTIONS __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/s390/kernel/vmlinux.lds.S +1 -1
@@ -99,7 +99,7 @@ SECTIONS . = ALIGN(2); __initramfs_end = .; #endif - . = ALIGN(256); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/sh/kernel/vmlinux.lds.S +1 -1
@@ -54,7 +54,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : { *(.data.page_aligned) } - . = ALIGN(L1_CACHE_BYTES); + . = ALIGN(PAGE_SIZE); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/sh64/kernel/vmlinux.lds.S +1 -1
@@ -85,7 +85,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : C_PHYS(.data.page_aligned) { *(.data.page_aligned) } - . = ALIGN(L1_CACHE_BYTES); + . = ALIGN(PAGE_SIZE); __per_cpu_start = .; .data.percpu : C_PHYS(.data.percpu) { *(.data.percpu) } __per_cpu_end = . ;
===================================================================
arch/sparc/kernel/vmlinux.lds.S +1 -1
@@ -65,7 +65,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/sparc64/kernel/smp.c +3 -3
@@ -1449,11 +1449,11 @@ void __init setup_per_cpu_areas(void)/* Copy section for each CPU (we discard the original) */ goal =PERCPU_ENOUGH_ROOM ; - __per_cpu_shift =0 ; -for (size =1UL ; size < goal; size <<=1UL ) + __per_cpu_shift =PAGE_SHIFT ; +for (size =PAGE_SIZE ; size < goal; size <<=1UL ) __per_cpu_shift++; - ptr =alloc_bootmem (size *NR_CPUS ); + ptr =alloc_bootmem_pages (size *NR_CPUS ); __per_cpu_base = ptr - __per_cpu_start;
===================================================================
arch/x86_64/kernel/setup64.c +2 -2
@@ -103,9 +103,9 @@ void __init setup_per_cpu_areas(void)if (!NODE_DATA (cpu_to_node (i))) {printk ("cpu with no node %d, num_online_nodes %d\n" , i,num_online_nodes ()); - ptr =alloc_bootmem (size); + ptr =alloc_bootmem_pages (size); }else { - ptr =alloc_bootmem_node (NODE_DATA (cpu_to_node (i)), size); + ptr =alloc_bootmem_pages_node (NODE_DATA (cpu_to_node (i)), size); }if (!ptr)panic ("Cannot allocate cpu data for CPU %d\n" , i);
===================================================================
arch/x86_64/kernel/vmlinux.lds.S +1 -1
@@ -194,7 +194,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } __per_cpu_end = .;
===================================================================
arch/xtensa/kernel/vmlinux.lds.S +1 -1
@@ -198,7 +198,7 @@ SECTIONS __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; - . = ALIGN(32); + . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .;
===================================================================
init/main.c +2 -2
@@ -370,8 +370,8 @@ static void __init setup_per_cpu_areas(v/* Copy section for each CPU (we discard the original) */ - size =ALIGN (PERCPU_ENOUGH_ROOM ,SMP_CACHE_BYTES ); - ptr =alloc_bootmem (size * nr_possible_cpus); + size =ALIGN (PERCPU_ENOUGH_ROOM ,PAGE_SIZE ); + ptr =alloc_bootmem_pages (size * nr_possible_cpus);for_each_possible_cpu (i) { __per_cpu_offset[i] = ptr - __per_cpu_start;
===================================================================
kernel/module.c +4 -4
@@ -346,10 +346,10 @@ static void *percpu_modalloc(unsigned lounsigned int i;void *ptr; -if (align >SMP_CACHE_BYTES ) { -printk (KERN_WARNING "%s: per-cpu alignment %li > %i\n" , - name, align,SMP_CACHE_BYTES ); - align =SMP_CACHE_BYTES ; +if (align >PAGE_SIZE ) { +printk (KERN_WARNING "%s: per-cpu alignment %li > %li\n" , + name, align,PAGE_SIZE ); + align =PAGE_SIZE ; } ptr = __per_cpu_start;
Quoted 5 lines · Jeremy Fitzhardinge
Let's allow page-alignment in general for per-cpu data (wanted by Xen, and Ingo suggested KVM as well).
Because larger alignments can use more room, we increase the max per-cpu memory to 64k rather than 32k: it's getting a little tight.
The second paragraph of the comment is dated. You are not changing the per-cpu memory size at all now.
The code itself looks sane.
Although we should probably fail the module load if the requested alignment is to great, but that is just picking nits, and is no worse than what we do today.
Eric
Quoted 18 lines
===================================================================
kernel/module.c +4
-4@@ -346,10 +346,10 @@ static void *percpu_modalloc(unsigned lounsigned int i;void *ptr; -if (align >SMP_CACHE_BYTES ) { -printk (KERN_WARNING "%s: per-cpu alignment %li > %i\n" , - name, align,SMP_CACHE_BYTES ); - align =SMP_CACHE_BYTES ; +if (align >PAGE_SIZE ) { +printk (KERN_WARNING "%s: per-cpu alignment %li > %li\n" , + name, align,PAGE_SIZE ); + align =PAGE_SIZE ; } ptr = __per_cpu_start;
Quoted 6 lines · Eric W. Biederman
Quoted 3 lines · Jeremy Fitzhardinge
Let's allow page-alignment in general for per-cpu data (wanted by Xen, and Ingo suggested KVM as well).
Quoted 7 lines
Quoted 3 lines
Because larger alignments can use more room, we increase the max per-cpu memory to 64k rather than 32k: it's getting a little tight.
The second paragraph of the comment is dated. You are not changing the per-cpu memory size at all now.
Yup.
Quoted 4 lines
Although we should probably fail the module load if the requested alignment is to great, but that is just picking nits, and is no worse than what we do today.
Yes. And we barely support a module's use of page-aligned data, since it would potentially chew through the percpu space very quickly.
J