Messages in this thread Patch in this message | | | Date | Sat, 12 Jan 2008 21:56:35 +0100 | From | Sam Ravnborg <> | Subject | Re: [PATCH 0/4] __cpuinitconst and __devinitconst |
| |
On Fri, Jan 11, 2008 at 08:44:28PM +0100, Sam Ravnborg wrote: > Hi Jan. > > On Fri, Jan 11, 2008 at 08:55:29AM +0000, Jan Beulich wrote: > > Since __cpuinitdata/__devinitdata don't allow const to be specified with > > them (otherwise .init.data sections with and without the writeable attribute > > will be generated by the compiler), and since __devinitdata except for > > embedded systems evaluates to <empty> unconditionally and > > __cpuinitdata at least in most production kernel configurations also > > likely evaluates to <empty>, it seems appropriate to add an additional > > attribute allowing the respective objects to end up in .rodata rather than > > .data when not used at initialization time only. > > How about a slightly diffrent approach... > Consider > __cpuinitconst => function is placed in section .init.const.text > __devinitconst => function is placed in section .init.const.text > > Then we in the linker scrip can distingush between the two > and locate the sections as appropriate. > > This will require some updates to modpost but are align with an > idea I have had for a while. > All of the following should have dedicated sections associated > unconditionally: > > __init > __cpuinit > __meminit > __initdata > __cpuinitdata > __meminitdata > > And then in the linker script we decide what to do with the section. > In the built-in case we put them in the "to-be-discarded" section. > In the module case we put them as today. > > The primary tasks needed to accomplish this is: > 1) Update all arch linker scripts (and some of them looks ugly) > 2) Teach modpost about the new sections > > If you following the suggestion above this is a simple step > in this direction which would be good.
The following patch implment first step in this direction. It is only an RFC as I have not touched anything else than 64 bit x86 for the arch specific parts. But it should show what I tried to say above.
On top of x86.git mm-branch.
Sam
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index ba8ea97..26c1d81 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -155,12 +155,16 @@ SECTIONS __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { _sinittext = .; + INIT_TEXT *(.init.text) _einittext = .; } - __initdata_begin = .; - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } - __initdata_end = .; + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { + __initdata_begin = .; + INIT_DATA + __initdata_end = .; + } + . = ALIGN(16); __setup_start = .; .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } @@ -187,8 +191,12 @@ SECTIONS } /* .exit.text is discard at runtime, not link time, to deal with references from .altinstructions and .eh_frame */ - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } - .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { + EXIT_TEXT + } + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { + EXIT_DATA + } /* vdso blob that is mapped into user space */ vdso_start = . ; diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 9f584cc..2f359d9 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -9,10 +9,48 @@ /* Align . to a 8 byte boundary equals to maximum function alignment. */ #define ALIGN_FUNCTION() . = ALIGN(8) +#ifdef CONFIG_HOTPLUG +#define DEV_KEEP(sec) +#define DEV_DISCARD(sec) *(.dev##sec) +#else +#define DEV_KEEP(sec) *(.dev##sec) +#define DEV_DISCARD(sec) +#endif + +#ifdef CONFIG_HOTPLUG_CPU +#define CPU_KEEP(sec) +#define CPU_DISCARD(sec) *(.cpu##sec) +#else +#define CPU_KEEP(sec) *(.cpu##sec) +#define CPU_DISCARD(sec) +#endif + +#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ + || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) +#define MEM_KEEP(sec) +#define MEM_DISCARD(sec) *(.mem##sec) +#else +#define MEM_KEEP(sec) *(.mem##sec) +#define MEM_DISCARD(sec) +#endif + + /* .data section */ #define DATA_DATA \ *(.data) \ *(.data.init.refok) \ + DEV_KEEP(init.data) \ + DEV_KEEP(init.data.const) \ + DEV_KEEP(exit.data) \ + DEV_KEEP(exit.data.const) \ + CPU_KEEP(init.data) \ + CPU_KEEP(init.data.const) \ + CPU_KEEP(exit.data) \ + CPU_KEEP(exit.data.const) \ + MEM_KEEP(init.data) \ + MEM_KEEP(init.data.const) \ + MEM_KEEP(exit.data) \ + MEM_KEEP(exit.data.const) \ . = ALIGN(8); \ VMLINUX_SYMBOL(__start___markers) = .; \ *(__markers) \ @@ -159,7 +197,14 @@ ALIGN_FUNCTION(); \ *(.text) \ *(.text.init.refok) \ - *(.exit.text.refok) + *(.exit.text.refok) \ + DEV_KEEP(init.text) \ + DEV_KEEP(exit.text) \ + CPU_KEEP(init.text) \ + CPU_KEEP(exit.text) \ + MEM_KEEP(init.text) \ + MEM_KEEP(exit.text) + /* sched.text is aling to function alignment to secure we have same * address even at second ld pass when generating System.map */ @@ -255,6 +300,36 @@ *(.initcall7.init) \ *(.initcall7s.init) +#define INIT_DATA \ + *(.init.data) \ + DEV_DISCARD(init.data) \ + DEV_DISCARD(init.data.const) \ + CPU_DISCARD(init.data) \ + CPU_DISCARD(init.data.const) \ + MEM_DISCARD(init.data) \ + MEM_DISCARD(init.data.const) + +#define INIT_TEXT \ + *(.init.text) \ + DEV_DISCARD(init.text) \ + CPU_DISCARD(init.text) \ + MEM_DISCARD(init.text) + +#define EXIT_DATA \ + *(.exit.data) \ + DEV_DISCARD(exit.data) \ + DEV_DISCARD(exit.data.const) \ + CPU_DISCARD(exit.data) \ + CPU_DISCARD(exit.data.const) \ + MEM_DISCARD(exit.data) \ + MEM_DISCARD(exit.data.const) + +#define EXIT_TEXT \ + *(.exit.text) \ + DEV_DISCARD(exit.text) \ + CPU_DISCARD(exit.text) \ + MEM_DISCARD(exit.text) + #define PERCPU(align) \ . = ALIGN(align); \ __per_cpu_start = .; \ diff --git a/include/linux/init.h b/include/linux/init.h index 86e7e94..b72897d 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -254,42 +254,26 @@ void __init parse_early_param(void); #define __initdata_or_module __initdata #endif /*CONFIG_MODULES*/ -#ifdef CONFIG_HOTPLUG -#define __devinit -#define __devinitdata -#define __devexit -#define __devexitdata -#else -#define __devinit __init -#define __devinitdata __initdata -#define __devexit __exit -#define __devexitdata __exitdata -#endif - -#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_CPUINIT) -#define __cpuinit -#define __cpuinitdata -#define __cpuexit -#define __cpuexitdata -#else -#define __cpuinit __init -#define __cpuinitdata __initdata -#define __cpuexit __exit -#define __cpuexitdata __exitdata -#endif - -#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ - || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) -#define __meminit -#define __meminitdata -#define __memexit -#define __memexitdata -#else -#define __meminit __init -#define __meminitdata __initdata -#define __memexit __exit -#define __memexitdata __exitdata -#endif +#define __devinit __attribute__ ((__section__ (".devinit.text"))) +#define __devinitdata __attribute__ ((__section__ (".devinit.data"))) +#define __devinitcdata __attribute__ ((__section__ (".devinit.data.const"))) +#define __devexit __attribute__ ((__section__ (".devexit.text"))) +#define __devexitdata __attribute__ ((__section__ (".devexit.data"))) +#define __devexitcdata __attribute__ ((__section__ (".devexit.data.const"))) + +#define __cpuinit __attribute__ ((__section__ (".cpuinit.text"))) +#define __cpuinitdata __attribute__ ((__section__ (".cpuinit.data"))) +#define __cpuinitcdata __attribute__ ((__section__ (".cpuinit.data.const"))) +#define __cpuexit __attribute__ ((__section__ (".cpuexit.text"))) +#define __cpuexitdata __attribute__ ((__section__ (".cpuexit.data"))) +#define __cpuexitcdata __attribute__ ((__section__ (".cpuexit.data.const"))) + +#define __meminit __attribute__ ((__section__ (".meminit.text"))) +#define __meminitdata __attribute__ ((__section__ (".meminit.data"))) +#define __meminitcdata __attribute__ ((__section__ (".meminit.data.const"))) +#define __memexit __attribute__ ((__section__ (".memexit.text"))) +#define __memexitdata __attribute__ ((__section__ (".memexit.data"))) +#define __memexitcdata __attribute__ ((__section__ (".memexit.data.const"))) /* Functions marked as __devexit may be discarded at kernel link time, depending on config options. Newer versions of binutils detect references from
| |