parisc: fix module loading failure of large kernel modules (take 2)
Subsystems (3)
Helge Deller
maintainerPATCH 1/1 parisc: fix module loading failure of large kernel modules (take 2)
This is the second take of the patch series. Changes to previous version:
- new CONFIG_HAVE_MODULE_SECTION_STUBS config option
- put stub entries of a code section in front of the section
____________
The parisc port (esp. the 32bit kernel) currently lacks the ability to load large kernel modules like xfs or ipv6. This is a long outstanding bug and has already been reported a few times, e.g.:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350482,
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=401439,
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=508489
The symptom is like this:
# modprobe xfs FATAL: Error inserting xfs (/lib/modules/2.6.26-1-parisc/kernel/fs/xfs/xfs.ko): Invalid module format
In dmesg:
module xfs relocation of symbol xfs_btree_read_bufs is out of range (0x3ffefffe in 17 bits)
The reason for the failure is, that the architecture only provides the R_PARISC_PCREL17F (for 32bit kernels) and R_PARISC_PCREL22F (for PA2.0 and 64bit kernels) relocations, which sometimes can't reach the target address of the stub entry if the kernel module is too large. Currently parisc (like other architectures) creates one big PLT section for all stubs at the beginning of the init and core sections.
The following two patches changes the parisc module loader to put stubs for the code sections in front of each section, so that the distance to the stubs more easily fits into the available 17/22 bits.
The first patch touches the generic module loader and adds a call to the new module_additional_section_size() function to get_offset() if CONFIG_HAVE_MODULE_SECTION_STUBS is defined. On parisc this function returns the additional bytes for the stub area of a given section.
The second patch implements the parisc-specific changes.
Tested with 32- and 64bit parisc kernels.
Helge
Helge Deller
maintainerPATCH 1/2 module.c: fix module loading failure of large modules (take 2)
[PATCH 1/2] module.c: fix module loading failure of large modules (take 2)
When creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
include/linux/moduleloader.h +3 -0
@@ -13,6 +13,9 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,char *secstrings, struct module *mod); +unsigned long module_additional_section_size (struct module *mod, +unsigned int section); +/* Allocator used for allocating struct module, core sections and init sections. Returns NULL on failure. */ void *module_alloc (unsigned long size);
init/Kconfig +3 -0
@@ -908,6 +908,9 @@ config MODULE_SRCVERSION_ALL the version). With this option, such a "srcversion" field will be created for all modules. If unsure, say N. +config HAVE_MODULE_SECTION_STUBS + bool + config KMOD def_bool y help
kernel/module.c +8 -3
@@ -1579,10 +1579,15 @@ static int simplify_symbols(Elf_Shdr *sechdrs, }/* Update size with this section: return offset. */ -static long get_offset (unsigned int *size,Elf_Shdr *sechdr) +static long get_offset (struct module *mod,unsigned int *size, +Elf_Shdr *sechdr,unsigned int section) {long ret; +#ifdef CONFIG_HAVE_MODULE_SECTION_STUBS +/* allocate some memory for stubs in front of each section */ + *size +=module_additional_section_size (mod, section); +#endif ret =ALIGN (*size, sechdr->sh_addralign ?:1 ); *size = ret + sechdr->sh_size;return ret;
@@ -1622,7 +1627,7 @@ static void layout_sections(struct module *mod, || strncmp(secstrings + s->sh_name, ".init", 5) == 0)continue ; - s->sh_entsize =get_offset (&mod->core_size, s); + s->sh_entsize =get_offset (mod, &mod->core_size, s, i);DEBUGP ("\t%s\n" , secstrings + s->sh_name); }if (m ==0 )
@@ -1640,7 +1645,7 @@ static void layout_sections(struct module *mod, || strncmp(secstrings + s->sh_name, ".init", 5) != 0)continue ; - s->sh_entsize = (get_offset (&mod->init_size, s) + s->sh_entsize = (get_offset (mod, &mod->init_size, s, i) |INIT_OFFSET_MASK );DEBUGP ("\t%s\n" , secstrings + s->sh_name); }
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 1/2] module.c: fix module loading failure of large modules (take 2)
Ugh, I fail at typing, resending for rusty's benefit.
Quoted 88 lines · Kyle McMartin
[Adding rusty to CC]
include/linux/moduleloader.h int module_frob_arch_sections(Elf_Ehdr *hdr, · line 18
Quoted 3 lines · Helge Deller
include/linux/moduleloader.h +3
-0+unsigned long module_additional_section_size (struct module *mod, +unsigned int section); +I think this would be more palatable as
#ifdef
HAVE_MODULE_SECTION_STUBS
unsigned long module_additional_section_size(struct module *mod,unsigned int section); #else static inline unsigned long module_additional_section_size(struct module *mod, unsigned int section) { return 0; }#endif
and removing the conditional in
kernel/module.c, possibly the symbol should be "arch_module_a..." just to make it clear to anyone reading.Anyway, it's up to rusty.
Rusty, we'd like to get this patch in, so I can merge the dependent parisc-specific patch.
regards, Kyle
Quoted 57 lines
/* Allocator used for allocating struct module, core sections and init
sections. Returns NULL on failure. */
void *module_alloc(unsigned long size);init/Kconfig +3
-0@@ -908,6 +908,9 @@ config MODULE_SRCVERSION_ALL the version). With this option, such a "srcversion" field will be created for all modules. If unsure, say N. +config HAVE_MODULE_SECTION_STUBS + bool + config KMOD def_bool y helpkernel/module.c +8
-3@@ -1579,10 +1579,15 @@ static int simplify_symbols(Elf_Shdr *sechdrs, }/* Update size with this section: return offset. */ -static long get_offset (unsigned int *size,Elf_Shdr *sechdr) +static long get_offset (struct module *mod,unsigned int *size, +Elf_Shdr *sechdr,unsigned int section) {long ret; +#ifdef CONFIG_HAVE_MODULE_SECTION_STUBS +/* allocate some memory for stubs in front of each section */ + *size +=module_additional_section_size (mod, section); +#endif ret =ALIGN (*size, sechdr->sh_addralign ?:1 ); *size = ret + sechdr->sh_size;return ret;@@ -1622,7 +1627,7 @@ static void layout_sections(struct module *mod, || strncmp(secstrings + s->sh_name, ".init", 5) == 0)continue ; - s->sh_entsize =get_offset (&mod->core_size, s); + s->sh_entsize =get_offset (mod, &mod->core_size, s, i);DEBUGP ("\t%s\n" , secstrings + s->sh_name); }if (m ==0 )@@ -1640,7 +1645,7 @@ static void layout_sections(struct module *mod, || strncmp(secstrings + s->sh_name, ".init", 5) != 0)continue ; - s->sh_entsize = (get_offset (&mod->init_size, s) + s->sh_entsize = (get_offset (mod, &mod->init_size, s, i) |INIT_OFFSET_MASK );DEBUGP ("\t%s\n" , secstrings + s->sh_name); }
Helge Deller
maintainerRe: [PATCH 1/2] module.c: fix module loading failure of large modules (take 2)
Quoted 29 lines · Kyle McMartin
Ugh, I fail at typing, resending for rusty's benefit.
Quoted 26 lines · Kyle McMartin
[Adding rusty to CC]
include/linux/moduleloader.h int module_frob_arch_sections(Elf_Ehdr *hdr, · line 18
Quoted 3 lines · Helge Deller
include/linux/moduleloader.h +3
-0+unsigned long module_additional_section_size (struct module *mod, +unsigned int section); +I think this would be more palatable as
#ifdef
HAVE_MODULE_SECTION_STUBS
unsigned long module_additional_section_size(struct module *mod,unsigned int section); #else static inline unsigned long module_additional_section_size(struct module *mod, unsigned int section) { return 0; }#endif
and removing the conditional in
kernel/module.c, possibly the symbol should be "arch_module_a..." just to make it clear to anyone reading.Anyway, it's up to rusty.
Rusty, we'd like to get this patch in, so I can merge the dependent parisc-specific patch.
Rusty, I think I've a cleaner patch for that and will send it soon...
Helge
Helge Deller
maintainerRe: [PATCH 1/2] module.c: fix module loading failure of large modules (take 3)
Quoted 5 lines · Helge Deller
Quoted 4 lines · Kyle McMartin
Quoted 4 lines
Anyway, it's up to rusty.
Rusty, we'd like to get this patch in, so I can merge the dependent parisc-specific patch.
Rusty,
While my initial patch (http://lkml.org/lkml/2008/12/29/274) added a new CONFIG option and an optional callback function, this version instead reuses the ElfHdr.sh_entsize field to tell the layout function how many bytes to reserve.
It seems that only the IA64 module loader is affected by that change, so the trivial patch for IA64 is below as well.
Other architectures use the sh_entsize field as well, but only for bootloaders (x86, mips) or for special purpose loaders (powerpc cell), but not for kernel modules. So the patch below should be pretty safe.
Personally I prefer this patch, but if you think my initial patch is better, I'd be happy as well.
arch/ia64/kernel/module.c | 4 +++- kernel/module.c | 37 ++++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 18 deletions(-)
[PATCH 1/2] module.c: fix module loading failure of large modules (take 3)
When creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. The amount of to-be allocated memory is returned by the architecture's module_frob_arch_sections() function in the sechdrs.sh_entsize field. By default this field is initialized by the module loader to zero. Additional memory in front of code sections is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
arch/ia64/kernel/module.c +3 -1
@@ -53,6 +53,8 @@#define MAX_LTOFF ((uint64_t) (1 << 22))/* max. allowable linkage-table offset */ +#define INIT_LAYOUT_MASK (1UL << (BITS_PER_LONG-1)) +/* Define some relocation helper macros/types: */ #define FORMAT_SHIFT 0
@@ -804,7 +806,7 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind target_sec = sechdrs + sechdrs[relsec].sh_info; -if (target_sec->sh_entsize == ~0UL ) +if (!(target_sec->sh_entsize &INIT_LAYOUT_MASK ))/* * If target section wasn't allocated, we don't need to relocate it. * Happens, e.g., for debug sections.
kernel/module.c +20 -17
@@ -62,8 +62,9 @@#define ARCH_SHF_SMALL 0#endif -/* If this is set, the section belongs in the init part of the module */ -#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) +#define INIT_LAYOUT_MASK (1UL << (BITS_PER_LONG-1))/* section-layout done */ +#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-2))/* part of init section */ +#define INIT_STRIP_MASK (INIT_OFFSET_MASK | INIT_LAYOUT_MASK)/* List of modules, protected by module_mutex or preempt_disable * (delete uses stop_machine/add uses RCU list operations). */
@@ -1583,6 +1584,8 @@ static long get_offset(unsigned int *size, Elf_Shdr *sechdr) {long ret; +/* architectures can request sh_entsize bytes in front of a section */ + *size += (sechdr->sh_entsize & ~INIT_STRIP_MASK ); ret =ALIGN (*size, sechdr->sh_addralign ?:1 ); *size = ret + sechdr->sh_size;return ret;
@@ -1590,8 +1593,8 @@ static long get_offset(unsigned int *size, Elf_Shdr *sechdr)/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld might -- code, read-only data, read-write data, small data. Tally -sizes, and place the offsets into sh_entsize fields: high bit means it -belongs in init. */ +sizes, and place the offsets into sh_entsize fields: INIT_OFFSET_MASK +indicates that it belongs in init. */ static void layout_sections(struct module *mod, const Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
@@ -1608,9 +1611,6 @@ static void layout_sections(struct module *mod, };unsigned int m, i; -for (i =0 ; i < hdr->e_shnum; i++) - sechdrs[i].sh_entsize = ~0UL ; -DEBUGP ("Core section allocation order:\n" );for (m =0 ; m <ARRAY_SIZE (masks); ++m) {for (i =0 ; i < hdr->e_shnum; ++i) {
@@ -1618,11 +1618,12 @@ static void layout_sections(struct module *mod,if ((s->sh_flags & masks[m][0 ]) != masks[m][0 ] || (s->sh_flags & masks[m][1 ]) - || s->sh_entsize != ~0UL + || (s->sh_entsize &INIT_LAYOUT_MASK ) ||strncmp (secstrings + s->sh_name,".init" ,5 ) ==0 )continue ; - s->sh_entsize =get_offset (&mod->core_size, s); + s->sh_entsize =get_offset (&mod->core_size, s) + |INIT_LAYOUT_MASK ;DEBUGP ("\t%s\n" , secstrings + s->sh_name); }if (m ==0 )
@@ -1636,12 +1637,12 @@ static void layout_sections(struct module *mod,if ((s->sh_flags & masks[m][0 ]) != masks[m][0 ] || (s->sh_flags & masks[m][1 ]) - || s->sh_entsize != ~0UL + || (s->sh_entsize &INIT_LAYOUT_MASK ) ||strncmp (secstrings + s->sh_name,".init" ,5 ) !=0 )continue ; s->sh_entsize = (get_offset (&mod->init_size, s) - |INIT_OFFSET_MASK ); + |INIT_OFFSET_MASK |INIT_LAYOUT_MASK );DEBUGP ("\t%s\n" , secstrings + s->sh_name); }if (m ==0 )
@@ -1986,7 +1987,11 @@ static noinline struct module *load_module(void __user *umod, mod->state =MODULE_STATE_COMING ; -/* Allow arches to frob section contents and sizes. */ +/* Allow arches to frob section contents, sh_entsize will tell the +* the section layouter how much space to allocate in front of each +* section */ +for (i =0 ; i < hdr->e_shnum; i++) + sechdrs[i].sh_entsize =0UL ; err =module_frob_arch_sections (hdr, sechdrs, secstrings, mod);if (err <0 ) goto free_mod;
@@ -2034,11 +2039,9 @@ static noinline struct module *load_module(void __user *umod,if (!(sechdrs[i].sh_flags &SHF_ALLOC ))continue ; -if (sechdrs[i].sh_entsize &INIT_OFFSET_MASK ) - dest = mod->module_init - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK ); -else - dest = mod->module_core + sechdrs[i].sh_entsize; + dest = ((sechdrs[i].sh_entsize &INIT_OFFSET_MASK ) ? + mod->module_init : mod->module_core) + + (sechdrs[i].sh_entsize & ~INIT_STRIP_MASK );if (sechdrs[i].sh_type !=SHT_NOBITS ) memcpy(dest, (void *)sechdrs[i].sh_addr,
Helge Deller
maintainerPATCH 2/2 parisc: fix module loading failure of large modules (take 2)
In reply to Helge Deller[PATCH 2/2] parisc: fix module loading failure of large modules (take 2)
On 32bit (and sometimes 64bit) and with big kernel modules like xfs or ipv6 the relocation types R_PARISC_PCREL17F and R_PARISC_PCREL22F may fail to reach their PLT stub if we only create one big stub array for all sections at the beginning of the core or init section.
With this patch we now instead add individual PLT stub entries directly in front of the code sections where the stubs are actually called. This reduces the distance between the PCREL location and the stub entry so that the relocations can be fulfilled.
The kernel module loader will call module_additional_section_size() and request us to return the amount of additional memory we need for the stubs of each section. This memory will then be allocated in front of the code code segment when the kernel layouts the final addresses of all sections.
Tested with 32- and 64bit kernels.
arch/parisc/Kconfig +1 -0
@@ -9,6 +9,7 @@ config PARISC def_bool y select HAVE_IDE select HAVE_OPROFILE + select HAVE_MODULE_SECTION_STUBS select RTC_CLASS select RTC_DRV_PARISC help
arch/parisc/include/asm/module.h +4 -2
@@ -23,8 +23,10 @@ struct mod_arch_specific {unsigned long got_offset, got_count, got_max;unsigned long fdesc_offset, fdesc_count, fdesc_max; -unsigned long stub_offset, stub_count, stub_max; -unsigned long init_stub_offset, init_stub_count, init_stub_max; +struct { +unsigned long stub_offset; +unsigned int stub_entries; + } *section;int unwind_section;struct unwind_table *unwind; };
arch/parisc/kernel/module.c +136 -81
353 lines not on this page · raw message
Helge Deller
maintainerRe: [PATCH 2/2] parisc: fix module loading failure of large modules (take 3)
[PATCH 2/2] parisc: fix module loading failure of large modules (take 3)
On 32bit (and sometimes 64bit) and with big kernel modules like xfs or ipv6 the relocation types R_PARISC_PCREL17F and R_PARISC_PCREL22F may fail to reach their PLT stub if we only create one big stub array for all sections at the beginning of the core or init section.
With this patch we now instead add individual PLT stub entries directly in front of the code sections where the stubs are actually called. This reduces the distance between the PCREL location and the stub entry so that the relocations can be fulfilled.
The kernel module loader will allocate as much memory in front of the code code segment as we return in the sechdrs.sh_entsize field.
Tested with 32- and 64bit kernels.
arch/parisc/include/asm/module.h +4 -2
@@ -23,8 +23,10 @@ struct mod_arch_specific {unsigned long got_offset, got_count, got_max;unsigned long fdesc_offset, fdesc_count, fdesc_max; -unsigned long stub_offset, stub_count, stub_max; -unsigned long init_stub_offset, init_stub_count, init_stub_max; +struct { +unsigned long stub_offset; +unsigned int stub_entries; + } *section;int unwind_section;struct unwind_table *unwind; };
arch/parisc/kernel/module.c +132 -81
344 lines not on this page · raw message
Quoted 30 lines · On Tuesday 30 December 2008 07:04:54 Helge Deller wrote:
This is the second take of the patch series. Changes to previous version:
- newCONFIG_HAVE_MODULE_SECTION_STUBSconfig option
- put stub entries of a code section in front of the section____________
The parisc port (esp. the 32bit kernel) currently lacks the ability to load large kernel modules like xfs or ipv6. This is a long outstanding bug and has already been reported a few times, e.g.:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350482,
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=401439,
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=508489The symptom is like this:
# modprobe xfs FATAL: Error inserting xfs (/lib/modules/2.6.26-1-parisc/kernel/fs/xfs/xfs.ko): Invalid module formatIn dmesg:
module xfs relocation of symbolxfs_btree_read_bufsis out of range (0x3ffefffein 17 bits)The reason for the failure is, that the architecture only provides the
R_PARISC_PCREL17F(for 32bit kernels) andR_PARISC_PCREL22F(for PA2.0 and 64bit kernels) relocations, which sometimes can't reach the target address of the stub entry if the kernel module is too large. Currently parisc (like other architectures) creates one big PLT section for all stubs at the beginning of the init and core sections.
Quoted 3 lines
The following two patches changes the parisc module loader to put stubs for the code sections in front of each section, so that the distance to the stubs more easily fits into the available 17/22 bits.
So now any one section has to pass 17 bits to break? How close are you with the xfs module?
But it's kind of nasty, overloading sh_entsize further. Could we instead do something like add a arch_module_section_size() weak fn which you can overload? We'd use that in get_offset() so our layout and size calculations were correct, and use sh_size everywhere else.
Cheers,
Rusty.
Helge Deller
maintainerQuoted 31 lines · Rusty Russell
Quoted 30 lines · On Tuesday 30 December 2008 07:04:54 Helge Deller wrote:
This is the second take of the patch series. Changes to previous version:
- newCONFIG_HAVE_MODULE_SECTION_STUBSconfig option
- put stub entries of a code section in front of the section____________
The parisc port (esp. the 32bit kernel) currently lacks the ability to load large kernel modules like xfs or ipv6. This is a long outstanding bug and has already been reported a few times, e.g.:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350482,
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=401439,
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=508489The symptom is like this:
# modprobe xfs FATAL: Error inserting xfs (/lib/modules/2.6.26-1-parisc/kernel/fs/xfs/xfs.ko): Invalid module formatIn dmesg:
module xfs relocation of symbolxfs_btree_read_bufsis out of range (0x3ffefffein 17 bits)The reason for the failure is, that the architecture only provides the
R_PARISC_PCREL17F(for 32bit kernels) andR_PARISC_PCREL22F(for PA2.0 and 64bit kernels) relocations, which sometimes can't reach the target address of the stub entry if the kernel module is too large. Currently parisc (like other architectures) creates one big PLT section for all stubs at the beginning of the init and core sections.
Quoted 6 lines
Quoted 3 lines
The following two patches changes the parisc module loader to put stubs for the code sections in front of each section, so that the distance to the stubs more easily fits into the available 17/22 bits.
So now any one section has to pass 17 bits to break? How close are you with the xfs module?
I did not tested it very much, but xfs is around 1.1M on disk, and ~750K when loaded. I think it breaked being 1/4 through the relocations.
Quoted 3 lines
But it's kind of nasty, overloading
sh_entsizefurther. Could we instead do something like add aarch_module_section_size()weak fn which you can overload?
Sure. I'll respin the patch.
Quoted 2 lines
We'd use that in
get_offset()so our layout and size calculations were correct,
Yes, good.
Quoted 1 line
and use
sh_sizeeverywhere else.
BTW, although the comment states that arches can change section sizes in the module_frob_arch_sections() function:
/* Allow arches to frob section contents and sizes. */
it will break horrible if you do so.
What I found was, that if you change sh_size, at least the module references / dependency chain will break when running lsmod.
Helge
Quoted 6 lines · On Wednesday 31 December 2008 09:32:41 Helge Deller wrote:
BTW, although the comment states that arches can change section sizes in the
module_frob_arch_sections()function:
/* Allow arches to frob section contents and sizes. */
it will break horrible if you do so.
What I found was, that if you changesh_size, at least the module references / dependency chain will break when running lsmod.
Well, you can change the size of NOBITS sections: other things are likely to be less successful. You could probably make them smaller, though.
Cheers,
Rusty.
Helge Deller
maintainerRe: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Rusty Russell[PATCH 1/2] module.c: fix module loading failure of large kernel modules
When creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
Differences of this patch to previous versions:
- added weak funtion arch_module_section_size()
- no kernel config options needed
- no overloading of sh_entsize
diffstat:
include/linux/moduleloader.h | 4 ++++ kernel/module.c | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-)
include/linux/moduleloader.h +4 -0
@@ -13,6 +13,10 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,char *secstrings, struct module *mod); +/* Additional bytes needed by arch in front of individual sections */ +unsigned int arch_module_section_size (struct module *mod, +unsigned int section); +/* Allocator used for allocating struct module, core sections and init sections. Returns NULL on failure. */ void *module_alloc (unsigned long size);
kernel/module.c +13 -3
@@ -1578,11 +1578,21 @@ static int simplify_symbols(Elf_Shdr *sechdrs,return ret; } +/* Additional bytes needed by arch in front of individual sections */ +unsigned int __attribute__ ((weak))arch_module_section_size ( +struct module *mod,unsigned int section) +{ +/* default implementation just returns zero */ +return 0 ; +} +/* Update size with this section: return offset. */ -static long get_offset (unsigned int *size,Elf_Shdr *sechdr) +static long get_offset (struct module *mod,unsigned int *size, +Elf_Shdr *sechdr,unsigned int section) {long ret; + *size +=arch_module_section_size (mod, section); ret =ALIGN (*size, sechdr->sh_addralign ?:1 ); *size = ret + sechdr->sh_size;return ret;
@@ -1622,7 +1632,7 @@ static void layout_sections(struct module *mod, || strncmp(secstrings + s->sh_name, ".init", 5) == 0)continue ; - s->sh_entsize =get_offset (&mod->core_size, s); + s->sh_entsize =get_offset (mod, &mod->core_size, s, i);DEBUGP ("\t%s\n" , secstrings + s->sh_name); }if (m ==0 )
@@ -1640,7 +1650,7 @@ static void layout_sections(struct module *mod, || strncmp(secstrings + s->sh_name, ".init", 5) != 0)continue ; - s->sh_entsize = (get_offset (&mod->init_size, s) + s->sh_entsize = (get_offset (mod, &mod->init_size, s, i) |INIT_OFFSET_MASK );DEBUGP ("\t%s\n" , secstrings + s->sh_name); }
Helge Deller
maintainerPATCH 2/2 parisc: fix module loading failure of large modules
[PATCH 2/2] parisc: fix module loading failure of large modules (take 3)
On 32bit (and sometimes 64bit) and with big kernel modules like xfs or ipv6 the relocation types R_PARISC_PCREL17F and R_PARISC_PCREL22F may fail to reach their PLT stub if we only create one big stub array for all sections at the beginning of the core or init section.
With this patch we now instead add individual PLT stub entries directly in front of the code sections where the stubs are actually called. This reduces the distance between the PCREL location and the stub entry so that the relocations can be fulfilled.
While calculating the final layout of the kernel module in memory, the kernel module loader calls arch_module_section_size() to request the to be reserved amount of memory in front of each individual section.
Tested with 32- and 64bit kernels.
diffstat:
include/asm/module.h | 6 - kernel/module.c | 217 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 140 insertions(+), 83 deletions(-)
arch/parisc/include/asm/module.h +4 -2
@@ -23,8 +23,10 @@ struct mod_arch_specific {unsigned long got_offset, got_count, got_max;unsigned long fdesc_offset, fdesc_count, fdesc_max; -unsigned long stub_offset, stub_count, stub_max; -unsigned long init_stub_offset, init_stub_count, init_stub_max; +struct { +unsigned long stub_offset; +unsigned int stub_entries; + } *section;int unwind_section;struct unwind_table *unwind; };
arch/parisc/kernel/module.c +136 -81
353 lines not on this page · raw message
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Helge DellerQuoted 4 lines · On Wednesday 31 December 2008 22:01:18 Helge Deller wrote:
include/linux/moduleloader.h +4
-0+/* Additional bytes needed by arch in front of individual sections */ +unsigned int arch_module_section_size (struct module *mod, +unsigned int section); +
...
kernel/module.c static int simplify_symbols(Elf_Shdr *sechdrs, · line 1587
Quoted 7 lines
kernel/module.c +7
-0+/* Additional bytes needed by arch in front of individual sections */ +unsigned int __attribute__ ((weak))arch_module_section_size ( +struct module *mod,unsigned int section) +{ +/* default implementation just returns zero */ +return 0 ; +}
Not quite what I had in mind... let me show you:
/* Bytes needed for a section: default is just the section size. */ unsigned int __attribute__((weak))arch_module_section_size(struct module *mod, Elf_Shdr *sechdrs, unsigned int sec)
{
return sechdrs[sec].sh_size;
}Otherwise I'd have called it "arch_module_extra_size()".
Cheers,
Rusty.
Helge Deller
maintainerRe: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 3 lines · Rusty Russell
Not quite what I had in mind... let me show you:
...
Otherwise I'd have called it "arch_module_extra_size()".
Hmm, this needs more thinking then.
So, in summary this would be your proposed change (?):
+/* Bytes needed for a section: default is just the section size. */ +unsigned int __attribute__((weak))
+arch_module_section_size(struct module *mod, Elf_Shdr *sechdrs, unsigned int sec) +{
+ return sechdrs[sec].sh_size;
+}
+
/* Update size with this section: return offset. */
-static long get_offset(unsigned int *size, Elf_Shdr *sechdr)
+static long get_offset(struct module *mod, unsigned int *size,
+ Elf_Shdr *sechdr, unsigned int section)
{
long ret;
ret = ALIGN(*size, sechdr->sh_addralign ?: 1);
- *size = ret + sechdr->sh_size;
+ *size = ret + arch_module_section_size(mod, sechdr, section);
return ret;}
This would mean that I can increase the section size in the arch-specific function by returning a bigger value than sh_size.
This would give me space at the end of the section, but not at the beginning (which is what I need), as sh_entsize (the offset into memory) will stay the same as before.
Example: Having an initial value for core_size of zero, the code bits of the very first section are still copied into the very first byte in memory, leaving me no room for the stubs.
The important part of get_offset() is, which value is returned to the caller. Let's try another example which would work for me:
+static long get_offset(struct module *mod, unsigned int *size,
+ Elf_Shdr *sechdr, unsigned int section)
{
- long ret;
+ long ret, sect_size;
+ sect_size = arch_module_section_size(mod, sechdr, section);
+ *size += (sect_size - sechdr->sh_size);
ret = ALIGN(*size, sechdr->sh_addralign ?: 1);
*size = ret + sechdr->sh_size;
return ret;IMHO, this is hackish and ugly.
A last option for me would be to set core_size to the initial value of bytes which I would need for section 1 and returning in arch_module_section_size() when asked for the size of section 1 the sum of sh_size[section 1] + additional_bytes_needed_for_section_2, and so on...
Any proposals?
Helge
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 10 lines · On Thursday 01 January 2009 00:43:56 Helge Deller wrote:
Quoted 3 lines · Rusty Russell
Not quite what I had in mind... let me show you:
...
Otherwise I'd have called it "arch_module_extra_size()".This would mean that I can increase the section size in the arch-specific function by returning a bigger value than
sh_size.
This would give me space at the end of the section, but not at the beginning (which is what I need), assh_entsize(the offset into memory) will stay the same as before.
Ah, OK. I assumed that extra room at the end was sufficient.
So I've taken your previous patch and renamed the function to arch_mod_section_prepend(). If we decide not to kill those bad gcc versions, I'll stick it in some other random file (lib/weak.c? Blech...)
BTW, this is very late for this merge window. I would have liked to see this a month ago :(
Subject: module: fix module loading failure of large kernel modules for parisc
Date: Wed, 31 Dec 2008 12:31:18 +0100
From: Helge Deller <[email protected]>
When creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
include/linux/moduleloader.h +3 -0
@@ -12,6 +12,9 @@ int module_frob_arch_sections(Elf_Ehdr * Elf_Shdr *sechdrs, char *secstrings, struct module *mod); + +/* Additional bytes needed by arch in front of individual sections */ +unsigned int arch_mod_section_prepend (struct module *mod,unsigned int section);/* Allocator used for allocating struct module, core sections and init sections. Returns NULL on failure. */
kernel/module.c +13 -3
@@ -1588,11 +1588,21 @@ static int simplify_symbols(Elf_Shdr *sereturn ret; } +/* Additional bytes needed by arch in front of individual sections */ +unsigned int __weak arch_mod_section_prepend (struct module *mod, +unsigned int section) +{ +/* default implementation just returns zero */ +return 0 ; +} +/* Update size with this section: return offset. */ -static long get_offset (unsigned int *size,Elf_Shdr *sechdr) +static long get_offset (struct module *mod,unsigned int *size, +Elf_Shdr *sechdr,unsigned int section) {long ret; + *size +=arch_mod_section_prepend (mod, section); ret =ALIGN (*size, sechdr->sh_addralign ?:1 ); *size = ret + sechdr->sh_size;return ret;
@@ -1632,7 +1642,7 @@ static void layout_sections(struct modul || strncmp(secstrings + s->sh_name, ".init", 5) == 0)continue ; - s->sh_entsize =get_offset (&mod->core_size, s); + s->sh_entsize =get_offset (mod, &mod->core_size, s, i);DEBUGP ("\t%s\n" , secstrings + s->sh_name); }if (m ==0 )
@@ -1650,7 +1660,7 @@ static void layout_sections(struct modul || strncmp(secstrings + s->sh_name, ".init", 5) != 0)continue ; - s->sh_entsize = (get_offset (&mod->init_size, s) + s->sh_entsize = (get_offset (mod, &mod->init_size, s, i) |INIT_OFFSET_MASK );DEBUGP ("\t%s\n" , secstrings + s->sh_name); }
Helge Deller
maintainerRe: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 11 lines · Rusty Russell
Quoted 9 lines · On Thursday 01 January 2009 00:43:56 Helge Deller wrote:
Quoted 3 lines · Rusty Russell
Not quite what I had in mind... let me show you:
...
Otherwise I'd have called it "arch_module_extra_size()".This would mean that I can increase the section size in the arch-specific function by returning a bigger value than
sh_size.
This would give me space at the end of the section, but not at the beginning (which is what I need), assh_entsize(the offset into memory) will stay the same as before.
Quoted 4 lines
Ah, OK. I assumed that extra room at the end was sufficient.
So I've taken your previous patch and renamed the function to
arch_mod_section_prepend().
Thanks a lot !!!!
Patch below is ok and I'll adjust the parisc-specific patch acordingly.
Quoted 2 lines
If we decide not to kill those bad gcc versions,
I'll stick it in some other random file (lib/weak.c? Blech...)
Andrew has pulled in the patch from Adrian in his -mm tree, so we should be safe now.
Quoted 2 lines
BTW, this is very late for this merge window. I would have liked to see this a month ago :(
Yes, sorry, I didn't had a patch available earlier.
I hope it's still in-time though, esp. as this will fix one of our longest outstanding bugs on parisc and is quite important for us.
Thanks,
Helge
Quoted 71 lines
Subject: module: fix module loading failure of large kernel modules for parisc
Date: Wed, 31 Dec 2008 12:31:18 +0100
From: Helge Deller <[email protected]>When creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
Signed-off-by Helge Deller <[email protected]>Signed-off-by Rusty Russell <[email protected]> (renamed fn)include/linux/moduleloader.h +3
-0@@ -12,6 +12,9 @@ int module_frob_arch_sections(Elf_Ehdr * Elf_Shdr *sechdrs, char *secstrings, struct module *mod); + +/* Additional bytes needed by arch in front of individual sections */ +unsigned int arch_mod_section_prepend (struct module *mod,unsigned int section);/* Allocator used for allocating struct module, core sections and init sections. Returns NULL on failure. */ kernel/module.c +13
-3@@ -1588,11 +1588,21 @@ static int simplify_symbols(Elf_Shdr *sereturn ret; } +/* Additional bytes needed by arch in front of individual sections */ +unsigned int __weak arch_mod_section_prepend (struct module *mod, +unsigned int section) +{ +/* default implementation just returns zero */ +return 0 ; +} +/* Update size with this section: return offset. */ -static long get_offset (unsigned int *size,Elf_Shdr *sechdr) +static long get_offset (struct module *mod,unsigned int *size, +Elf_Shdr *sechdr,unsigned int section) {long ret; + *size +=arch_mod_section_prepend (mod, section); ret =ALIGN (*size, sechdr->sh_addralign ?:1 ); *size = ret + sechdr->sh_size;return ret;@@ -1632,7 +1642,7 @@ static void layout_sections(struct modul || strncmp(secstrings + s->sh_name, ".init", 5) == 0)continue ; - s->sh_entsize =get_offset (&mod->core_size, s); + s->sh_entsize =get_offset (mod, &mod->core_size, s, i);DEBUGP ("\t%s\n" , secstrings + s->sh_name); }if (m ==0 )@@ -1650,7 +1660,7 @@ static void layout_sections(struct modul || strncmp(secstrings + s->sh_name, ".init", 5) != 0)continue ; - s->sh_entsize = (get_offset (&mod->init_size, s) + s->sh_entsize = (get_offset (mod, &mod->init_size, s, i) |INIT_OFFSET_MASK );DEBUGP ("\t%s\n" , secstrings + s->sh_name); }
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Helge DellerQuoted 11 lines · Helge Deller
[PATCH 1/2]
module.c: fix module loading failure of large kernel modulesWhen creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
Differences of this patch to previous versions:
- added weak funtionarch_module_section_size()
This doesn't work.
We've had this bug several times now, and one of them just very recently.
Some gcc versions will inline weak functions if they are in scope - even if there is a non-weak function somewhere else. So you MUST NOT have the weak definition in the same file (or indirectly called through some inline functions in a header file) as the call. Because if you do, then any user with the wrong version of gcc will get the weak function semantics, even if it was meant to be overridden by something else.
kernel/module.c static int simplify_symbols(Elf_Shdr *sechdrs, · line 1583
Quoted 3 lines
kernel/module.c +3
-0+/* Additional bytes needed by arch in front of individual sections */ +unsigned int __attribute__ ((weak))arch_module_section_size ( +struct module *mod,unsigned int section)
We don't write out that whole "__attribute__" crud. We use
unsigned in __weak arch_module_section_size(struct module *mod, unsigned int section)
instead. But as mentioned, it needs to be in another compilation unit.
Linus
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 6 lines
Some gcc versions will inline weak functions if they are in scope - even if there is a non-weak function somewhere else. So you MUST NOT have the weak definition in the same file (or indirectly called through some inline functions in a header file) as the call. Because if you do, then any user with the wrong version of gcc will get the weak function semantics, even if it was meant to be overridden by something else.
Does this mean lib/swiotlb.c is broken now? It has eg:
void * __weak swiotlb_alloc_boot(size_t size, unsigned long nslabs)
and then
void __init
swiotlb_init_with_default_size(size_t default_size)
{
...
io_tlb_start = swiotlb_alloc_boot(bytes, io_tlb_nslabs);later on in the same file.
(I just notice this because I saw the warning about swiotlb_alloc_boot() not being __init but calling __alloc_bootmem_low and so I looked at the code yesterday)
- R.
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 2 lines · Roland Dreier
Does this mean
lib/swiotlb.cis broken now?
Yes it does.
Quoted 6 lines
It has eg:
void *
__weakswiotlb_alloc_boot(size_t size, unsigned long nslabs)and then
Quoted 7 lines
void __init swiotlb_init_with_default_size(size_t default_size) { ... io_tlb_start = swiotlb_alloc_boot(bytes, io_tlb_nslabs);later on in the same file.
Good eyes.
Ingo? This comes from commit b81ea27b2329bf44b30c427800954f845896d476, by Ian, through Jeremy.
Quoted 3 lines
(I just notice this because I saw the warning about
swiotlb_alloc_boot()not being__initbut calling__alloc_bootmem_lowand so I looked at the code yesterday)
Lucky us. What's nasty about this is that most developers probably have updated versions of gcc, and are then surprised when some odd user has insane behavior that doesn't match the source code - because the compiler did something unexpected.
I guess I could make a sparse rule for this, but nobody seems to run or care about sparse anyway. Sad.
Linus
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 3 lines · Linus Torvalds
I guess I could make a sparse rule for this, but nobody seems to run or care about sparse anyway. Sad.
Ho humm. Looks like a sparse rule might be in order. These are just from my (smallish) personal config. I haven't checked them all, but I did check the first two, and yes, sparse did get it right.
init/main.c:548:24: warning: Calling weak function 'smp_setup_processor_id' in file scope init/main.c:674:24: warning: Calling weak function 'thread_info_cache_init' in file scope arch/x86/kernel/e820.c:1364:38: warning: Calling weak function 'machine_specific_memory_setup' in file scope arch/x86/kernel/e820.c:1371:20: warning: Calling weak function 'memory_setup' in file scope arch/x86/kernel/reboot.c:386:22: warning: Calling weak function 'mach_reboot_fixups' in file scope kernel/sched.c:7720:26: warning: Calling weak function 'arch_update_cpu_topology' in file scope kernel/sched.c:7808:41: warning: Calling weak function 'arch_update_cpu_topology' in file scope kernel/fork.c:229:29: warning: Calling weak function 'arch_dup_task_struct' in file scope kernel/fork.c:1325:44: warning: Calling weak function 'idle_regs' in file scope kernel/sched_clock.c:158:19: warning: Calling weak function 'sched_clock' in file scope kernel/sched_clock.c:207:19: warning: Calling weak function 'sched_clock' in file scope kernel/time/timekeeping.c:283:43: warning: Calling weak function 'read_persistent_clock' in file scope kernel/time/timekeeping.c:318:43: warning: Calling weak function 'read_persistent_clock' in file scope kernel/time/timekeeping.c:353:50: warning: Calling weak function 'read_persistent_clock' in file scope mm/vmalloc.c:1645:18: warning: Calling weak function 'vmalloc_sync_all' in file scope mm/hugetlb.c:1039:32: warning: Calling weak function 'alloc_bootmem_huge_page' in file scope mm/sparse.c:448:29: warning: Calling weak function 'vmemmap_populate_print_last' in file scope fs/pipe.c:1069:18: warning: Calling weak function 'sys_pipe2' in file scope fs/proc/meminfo.c:145:21: warning: Calling weak function 'arch_report_meminfo' in file scope drivers/acpi/pci_irq.c:676:21: warning: Calling weak function 'acpi_unregister_gsi' in file scope drivers/char/mem.c:168:23: warning: Calling weak function 'unxlate_dev_mem_ptr' in file scope drivers/char/mem.c:172:22: warning: Calling weak function 'unxlate_dev_mem_ptr' in file scope drivers/char/mem.c:240:23: warning: Calling weak function 'unxlate_dev_mem_ptr' in file scope drivers/char/mem.c:246:22: warning: Calling weak function 'unxlate_dev_mem_ptr' in file scope drivers/char/mem.c:318:12: warning: Calling weak function 'map_devmem' in file scope drivers/char/mem.c:324:14: warning: Calling weak function 'unmap_devmem' in file scope drivers/char/mem.c:349:35: warning: Calling weak function 'phys_mem_access_prot_allowed' in file scope drivers/char/mem.c:365:15: warning: Calling weak function 'unmap_devmem' in file scope drivers/pci/probe.c:1159:36: warning: Calling weak function 'set_pci_bus_resources_arch_default' in file scope drivers/pci/pci.c:1015:24: warning: Calling weak function 'pcibios_disable_device' in file scope drivers/pci/pci.c:1043:37: warning: Calling weak function 'pcibios_set_pcie_reset_state' in file scope drivers/pci/pci-sysfs.c:897:39: warning: Calling weak function 'pcibios_add_platform_entries' in file scope drivers/pci/msi.c:49:27: warning: Calling weak function 'arch_setup_msi_irq' in file scope drivers/pci/msi.c:69:25: warning: Calling weak function 'arch_teardown_msi_irq' in file scope drivers/pci/msi.c:421:27: warning: Calling weak function 'arch_setup_msi_irqs' in file scope drivers/pci/msi.c:492:27: warning: Calling weak function 'arch_setup_msi_irqs' in file scope drivers/pci/msi.c:562:29: warning: Calling weak function 'arch_msi_check_device' in file scope drivers/pci/msi.c:654:24: warning: Calling weak function 'arch_teardown_msi_irqs' in file scope lib/swiotlb.c:141:28: warning: Calling weak function 'swiotlb_phys_to_bus' in file scope lib/swiotlb.c:146:41: warning: Calling weak function 'swiotlb_bus_to_phys' in file scope lib/swiotlb.c:156:28: warning: Calling weak function 'swiotlb_phys_to_bus' in file scope lib/swiotlb.c:167:30: warning: Calling weak function 'swiotlb_phys_to_bus' in file scope lib/swiotlb.c:168:28: warning: Calling weak function 'swiotlb_phys_to_bus' in file scope lib/swiotlb.c:204:35: warning: Calling weak function 'swiotlb_alloc_boot' in file scope lib/swiotlb.c:260:31: warning: Calling weak function 'swiotlb_alloc' in file scope lib/swiotlb.c:336:58: warning: Calling weak function 'swiotlb_arch_range_needs_mapping' in file scope lib/swiotlb.c:336:58: warning: Calling weak function 'swiotlb_arch_range_needs_mapping' in file scope
I bet there are others that I don't see just because I don't compile the code.
The appended trial sparse diff is against sparse -git as of a couple of days ago if anybody wants to run it themselves.
The _logical_ fix would be to add "noinline" to the definition of "__weak", but that's reported not to help. I think the bug may be in the assembler that pre-links the call if it sees it in file scope. Or maybe gcc doesn't honor noinline for empty functions. Whatever.
Regardless, it's a damn pain.
Linus
--- evaluate.c | 7 +++++++ parse.c | 7 ++++--- symbol.h | 3 ++- 3 files changed, 13 insertions(+), 4 deletions(-)
evaluate.c +7 -0
@@ -2744,6 +2744,13 @@ static int evaluate_symbol_call(struct expression *expr)if (ctype->op && ctype->op->evaluate)return ctype->op->evaluate (expr); +if (ctype->ctype.modifiers &MOD_WEAK ) { +struct symbol *fn = ctype->ctype.base_type; + +if (fn->stmt || fn->inline_stmt) +warning (expr->pos,"Calling weak function '%s' in file scope" ,show_ident (ctype->ident)); + } +if (ctype->ctype.modifiers &MOD_INLINE ) {int ret;struct symbol *curr = current_fn;
parse.c +4 -3
@@ -289,6 +289,9 @@ static struct init_keyword { { "word", NS_KEYWORD, MOD_LONG, .op = &mode_spec_op }, { "__word__", NS_KEYWORD, MOD_LONG, .op = &mode_spec_op }, + { "weak", NS_KEYWORD, MOD_WEAK, .op = &attr_mod_op }, + { "__weak__", NS_KEYWORD, MOD_WEAK, .op = &attr_mod_op }, +/* Ignored attributes */ { "nothrow", NS_KEYWORD, .op = &ignore_attr_op }, { "__nothrow", NS_KEYWORD, .op = &ignore_attr_op },
@@ -317,8 +320,6 @@ static struct init_keyword { { "__sentinel__", NS_KEYWORD, .op = &ignore_attr_op }, { "regparm", NS_KEYWORD, .op = &ignore_attr_op }, { "__regparm__", NS_KEYWORD, .op = &ignore_attr_op }, - { "weak", NS_KEYWORD, .op = &ignore_attr_op }, - { "__weak__", NS_KEYWORD, .op = &ignore_attr_op }, { "alias", NS_KEYWORD, .op = &ignore_attr_op }, { "__alias__", NS_KEYWORD, .op = &ignore_attr_op }, { "pure", NS_KEYWORD, .op = &ignore_attr_op },
@@ -1582,7 +1583,7 @@ static struct statement *start_function(struct symbol *sym)start_function_scope (); ret =alloc_symbol (sym->pos,SYM_NODE ); ret->ctype = sym->ctype.base_type->ctype; - ret->ctype.modifiers &= ~(MOD_STORAGE |MOD_CONST |MOD_VOLATILE |MOD_INLINE |MOD_ADDRESSABLE |MOD_NOCAST |MOD_NODEREF |MOD_ACCESSED |MOD_TOPLEVEL ); + ret->ctype.modifiers &= ~(MOD_STORAGE |MOD_CONST |MOD_VOLATILE |MOD_INLINE |MOD_ADDRESSABLE |MOD_NOCAST |MOD_NODEREF |MOD_ACCESSED |MOD_TOPLEVEL |MOD_WEAK ); ret->ctype.modifiers |= (MOD_AUTO |MOD_REGISTER );bind_symbol (ret, &return_ident,NS_ITERATOR ); stmt->ret = ret;
symbol.h +2 -1
@@ -185,6 +185,7 @@ struct symbol {#define MOD_LONGLONG 0x0800#define MOD_TYPEDEF 0x1000 +#define MOD_WEAK 0x2000#define MOD_INLINE 0x40000#define MOD_ADDRESSABLE 0x80000
@@ -205,7 +206,7 @@ struct symbol {#define MOD_BITWISE 0x80000000#define MOD_NONLOCAL (MOD_EXTERN | MOD_TOPLEVEL) -#define MOD_STORAGE (MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | MOD_INLINE | MOD_TOPLEVEL | MOD_FORCE) +#define MOD_STORAGE (MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | MOD_INLINE | MOD_TOPLEVEL | MOD_FORCE | MOD_WEAK)#define MOD_SIGNEDNESS (MOD_SIGNED | MOD_UNSIGNED | MOD_EXPLICITLY_SIGNED)#define MOD_SPECIFIER (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG | MOD_SIGNEDNESS)#define MOD_SIZE (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG)
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Linus TorvaldsQuoted 3 lines
I guess I could make a sparse rule for this, but nobody seems to run or care about sparse anyway. Sad.
There is some increased janitorial effort recently. Try to grep for [Ss]+parse in the shortlog for the last couple of months.
Sam
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 5 lines · Sam Ravnborg
Quoted 2 lines
I guess I could make a sparse rule for this, but nobody seems to run or care about sparse anyway. Sad.
There is some increased janitorial effort recently. Try to grep for [Ss]+parse in the shortlog for the last couple of months.
in the x86 space there's a lot of Sparse activity as well: a number of developers do systematic runs of Sparse and keep the tree Sparse-clean.
The moment this spreads to a critical mass of subsystems we can start automating it. (as i was able to automate the checking of -Werr builds on x86, with arbitrary random .config's)
Ingo
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Linus TorvaldsQuoted 9 lines · On Wed, 31 Dec 2008 09:47:19 -0800 (PST) Linus Torvalds…
Quoted 4 lines
(I just notice this because I saw the warning about
swiotlb_alloc_boot()not being__initbut calling__alloc_bootmem_lowand so I looked at the code yesterday)Lucky us. What's nasty about this is that most developers probably have updated versions of gcc, and are then surprised when some odd user has insane behavior that doesn't match the source code - because the compiler did something unexpected.
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
Quoted 2 lines
I guess I could make a sparse rule for this, but nobody seems to run or care about sparse anyway. Sad.
No, there are some people who regularly run sparse and fix stuff. Pending things here include:
y:/usr/src/25> grep sparse series input-ads7846c-sparse-lock-annotation.patch hugetlb-fix-sparse-warnings.patch lib-fix-sparse-shadowed-variable-warning.patch lib-proportionsc-trivial-sparse-lock-annotation.patch nvidia-fix-sparse-warnings.patch viafb-fix-sparse-warnings.patch pm3fb-fix-sparse-warning.patch neofb-fix-sparse-warnings.patch i810-fix-sparse-warnings.patch intelfb-fix-sparse-warnings.patch
Which is a good way for it to be used.
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 3 lines · Andrew Morton
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
If it really is just those releases, then yes, considering the number of cases we apparently have, and considering how ugly it is in some cases to move the weak function anywhere else, maybe banning those versions is the proper thing to do.
It probably won't hurt very many people - yeah, some people will be forced to upgrade, but I have this memory of early 4.1 having had other bugs anyway, so it's probably a good idea.
Linus
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
From: Linus Torvalds <[email protected]>
Date: Wed, 31 Dec 2008 13:22:53 -0800 (PST)
Quoted 5 lines · Andrew Morton
Quoted 3 lines
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
Quoted 8 lines
If it really is just those releases, then yes, considering the number of cases we apparently have, and considering how ugly it is in some cases to move the weak function anywhere else, maybe banning those versions is the proper thing to do.
It probably won't hurt very many people - yeah, some people will be forced to upgrade, but I have this memory of early 4.1 having had other bugs anyway, so it's probably a good idea.
I think this is probably the best way to handle this.
PATCH 1/1 kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 13 lines · David Miller
From: Linus Torvalds <[email protected]>
Date: Wed, 31 Dec 2008 13:22:53 -0800 (PST)Quoted 10 lines · Andrew Morton
Quoted 3 lines
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
If it really is just those releases, then yes, considering the number of cases we apparently have, and considering how ugly it is in some cases to move the weak function anywhere else, maybe banning those versions is the proper thing to do.
Quoted 5 lines
Quoted 3 lines
It probably won't hurt very many people - yeah, some people will be forced to upgrade, but I have this memory of early 4.1 having had other bugs anyway, so it's probably a good idea.
I think this is probably the best way to handle this.
okay - to move this matter from the discussion-space to the solution-space, how about the patch below? (tested on x86 with a non-affected compiler version.)
Ingo
-------------->
Quoted 1 line
From
e6346e5ab54dcf12888a79dfd5402f5de09b3fadMon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Fri, 2 Jan 2009 12:46:22 +0100
Subject: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Impact: fix crashes that can trigger if built with GCC 4.1.0 or 4.1.1
GCC 4.1.0 and 4.1.1 has a bug that can miscompile __weak symbols, by inlining __weak functions into same-file call sites - breaking the kernel if the __weak symbol is overriden later on.
In the past we tried to work around this problem by artificially isolating call site and definition site - but these bugs tend to pop up regularly:
43a2563: sparseirq: move __weak symbols into separate compilation unit 13a0c3c: sparseirq: work around compiler optimizing away __weak functions
And Linus has extended Sparse to report same-file callsites for __weak symbols - which gave two dozen hits.
We have not found a clean way to work around this bug on the source code level (noinline and explicit barrier()s are ignored by GCC), so we do not allow these compilers (which are quite rare these days, have other bugs and are superceded by the 4.1.2 bugfix release anyway).
Kernel builds under gcc 410 or 411 will now fail with this error message:
Sorry, your compiler is too old, too buggy or not recognized.
--- include/linux/compiler.h | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-)
include/linux/compiler.h +15 -2
@@ -36,12 +36,25 @@ extern void __chk_io_ptr(const volatile void __iomem *);#ifdef __KERNEL__ -#if __GNUC__ >=4 +/* +* GCC 4.1.0 and 4.1.1 has a bug that can miscompile __weak symbols, +* by inlining __weak functions into same-file call sites - breaking the +* kernel if the __weak symbol is overriden later on. +* +* We have not found a clean way to work around this bug on the source +* code level, so we do not allow these compilers (which are quite +* rare these days, have other bugs and are superceded by the 4.1.2 +* bugfix release anyway): +*/ +#define gcc41_inlining_bug \ + (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1) + +#if __GNUC__ >=4 && !gcc41_inlining_bug# include <linux/compiler-gcc4.h> #elif __GNUC__ ==3 && __GNUC_MINOR__ >=2 # include <linux/compiler-gcc3.h> #else -# error Sorry, your compiler is too old/not recognized. +# error Sorry, your compiler is too old, too buggy or not recognized.#endif #define notrace __attribute__((no_instrument_function))
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 20 lines · Ingo Molnar
Quoted 17 lines · David Miller
From: Linus Torvalds <[email protected]>
Date: Wed, 31 Dec 2008 13:22:53 -0800 (PST)Quoted 13 lines · Andrew Morton
Quoted 3 lines
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
If it really is just those releases, then yes, considering the number of cases we apparently have, and considering how ugly it is in some cases to move the weak function anywhere else, maybe banning those versions is the proper thing to do.
It probably won't hurt very many people - yeah, some people will be forced to upgrade, but I have this memory of early 4.1 having had other bugs anyway, so it's probably a good idea.
Quoted 5 lines
Quoted 1 line
I think this is probably the best way to handle this.
okay - to move this matter from the discussion-space to the solution-space, how about the patch below? (tested on x86 with a non-affected compiler version.)
...or we can just merge Adrian's patch from June 2008 which also fixes the issue nicely.
OTOH your patch has an advantage of addressing the problem in the more appropriate place (include/linux/compiler.h) and from what I see allows us to remove previous gcc 4.1.0 check from init/main.c?
Quoted 70 lines
Ingo
-------------->
Frome6346e5ab54dcf12888a79dfd5402f5de09b3fadMon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Fri, 2 Jan 2009 12:46:22 +0100
Subject: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1Impact: fix crashes that can trigger if built with GCC 4.1.0 or 4.1.1
GCC 4.1.0 and 4.1.1 has a bug that can miscompile
__weaksymbols, by inlining__weakfunctions into same-file call sites - breaking the kernel if the__weaksymbol is overriden later on.In the past we tried to work around this problem by artificially isolating call site and definition site - but these bugs tend to pop up regularly:
43a2563: sparseirq: move
__weaksymbols into separate compilation unit 13a0c3c: sparseirq: work around compiler optimizing away__weakfunctionsAnd Linus has extended Sparse to report same-file callsites for
__weaksymbols - which gave two dozen hits.We have not found a clean way to work around this bug on the source code level (noinline and explicit barrier()s are ignored by GCC), so we do not allow these compilers (which are quite rare these days, have other bugs and are superceded by the 4.1.2 bugfix release anyway).
Kernel builds under gcc 410 or 411 will now fail with this error message:
Sorry, your compiler is too old, too buggy or not recognized.
Signed-off-by Ingo Molnar <[email protected]>--- include/linux/compiler.h | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-)include/linux/compiler.h +15
-2@@ -36,12 +36,25 @@ extern void __chk_io_ptr(const volatile void __iomem *);#ifdef __KERNEL__ -#if __GNUC__ >=4 +/* +* GCC 4.1.0 and 4.1.1 has a bug that can miscompile __weak symbols, +* by inlining __weak functions into same-file call sites - breaking the +* kernel if the __weak symbol is overriden later on. +* +* We have not found a clean way to work around this bug on the source +* code level, so we do not allow these compilers (which are quite +* rare these days, have other bugs and are superceded by the 4.1.2 +* bugfix release anyway): +*/ +#define gcc41_inlining_bug \ + (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1) + +#if __GNUC__ >=4 && !gcc41_inlining_bug# include <linux/compiler-gcc4.h> #elif __GNUC__ ==3 && __GNUC_MINOR__ >=2 # include <linux/compiler-gcc3.h> #else -# error Sorry, your compiler is too old/not recognized. +# error Sorry, your compiler is too old, too buggy or not recognized.#endif #define notrace __attribute__((no_instrument_function))
PATCH 1/1 kbuild: Remove gcc 4.1.0 quirk from init/main.c
Quoted 21 lines · Bartlomiej Zolnierkiewicz
Quoted 20 lines · Ingo Molnar
Quoted 17 lines · David Miller
From: Linus Torvalds <[email protected]>
Date: Wed, 31 Dec 2008 13:22:53 -0800 (PST)Quoted 13 lines · Andrew Morton
Quoted 3 lines
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
If it really is just those releases, then yes, considering the number of cases we apparently have, and considering how ugly it is in some cases to move the weak function anywhere else, maybe banning those versions is the proper thing to do.
It probably won't hurt very many people - yeah, some people will be forced to upgrade, but I have this memory of early 4.1 having had other bugs anyway, so it's probably a good idea.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
I think this is probably the best way to handle this.
okay - to move this matter from the discussion-space to the solution-space, how about the patch below? (tested on x86 with a non-affected compiler version.)
...or we can just merge Adrian's patch from June 2008 which also fixes the issue nicely.
didnt know about that patch, but yeah, sure.
Quoted 3 lines
OTOH your patch has an advantage of addressing the problem in the more appropriate place (
include/linux/compiler.h) and from what I see allows us to remove previous gcc 4.1.0 check frominit/main.c?
Good spotting - find followup cleanup patch below.
Ingo
------------------->
Quoted 1 line
From
d23cbaaa342e5555a919a543095d656415a55950Mon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Fri, 2 Jan 2009 16:16:16 +0100
Subject: [PATCH] kbuild: Remove gcc 4.1.0 quirk from init/main.c
Impact: cleanup
We now have a cleaner check for gcc 4.1.0/4.1.1 trouble in include/linux/compiler.h, so remove the 4.1.0 quirk from init/main.c.
--- init/main.c | 9 --------- 1 files changed, 0 insertions(+), 9 deletions(-)
init/main.c +0 -8
@@ -75,15 +75,6 @@#include <asm/smp.h> #endif -/* -* This is one of the first .c files built. Error out early if we have compiler -* trouble. -*/ - -#if __GNUC__ ==4 && __GNUC_MINOR__ ==1 && __GNUC_PATCHLEVEL__ ==0 -#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended. -#endif
Re: [PATCH] kbuild: Remove gcc 4.1.0 quirk from init/main.c
Quoted 5 lines
From
d23cbaaa342e5555a919a543095d656415a55950Mon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Fri, 2 Jan 2009 16:16:16 +0100
Subject: [PATCH] kbuild: Remove gcc 4.1.0 quirk frominit/main.c
Quoted 8 lines
Impact: cleanup
We now have a cleaner check for gcc 4.1.0/4.1.1 trouble in
include/linux/compiler.h, so remove the 4.1.0 quirk frominit/main.c.Reported-by Bartlomiej Zolnierkiewicz <[email protected]>Signed-off-by Ingo Molnar <[email protected]>
This should be applied despite Linus' different approach in compiler.h.
Quoted 24 lines
--- init/main.c | 9 --------- 1 files changed, 0 insertions(+), 9 deletions(-)init/main.c +0
-9@@ -75,15 +75,6 @@#include <asm/smp.h> #endif -/* -* This is one of the first .c files built. Error out early if we have compiler -* trouble. -*/ - -#if __GNUC__ ==4 && __GNUC_MINOR__ ==1 && __GNUC_PATCHLEVEL__ ==0 -#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended. -#endif -static int kernel_init (void *);extern void init_IRQ (void );
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Ingo MolnarQuoted 12 lines · Ingo Molnar
include/linux/compiler.h +5
-1@@ -36,12 +36,25 @@ extern void __chk_io_ptr(const volatile void __iomem *);#ifdef __KERNEL__ -#if __GNUC__ >=4 +/* +* GCC 4.1.0 and 4.1.1 has a bug that can miscompile __weak symbols, +* by inlining __weak functions into same-file call sites - breaking the +* kernel if the __weak symbol is overriden later on. +*
include/linux/compiler.h extern void __chk_io_ptr(const volatile void __iomem *); · line 53
Quoted 10 lines
include/linux/compiler.h +9
-0+* We have not found a clean way to work around this bug on the source +* code level, so we do not allow these compilers (which are quite +* rare these days, have other bugs and are superceded by the 4.1.2 +* bugfix release anyway): +*/ +#define gcc41_inlining_bug \ + (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1) + +#if __GNUC__ >=4 && !gcc41_inlining_bug# include <linux/compiler-gcc4.h>
I think this is wrong.
Just move the check into <linux/compiler-gcc4.h>
It makes no sense to do stuff that is specific to gcc4 in the general gcc header file. It seems you did this just in order to re-use a (bad) generic error case.
Linus
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 4 lines · Linus Torvalds
I think this is wrong.
Just move the check into <
linux/compiler-gcc4.h>
In fact, looking at that whole mess, I redid it all. It was disgusting how conditionals in gcc4.h needed to double-check that __GNUC__ really was 4 (rather than something bigger), which largely negated the whole nice clean compiler version separation.
I pushed out my preferred version, which fixes up the whole thing. The gcc4 header file now only gets included for __GNUC__ == 4, and when we ever see a __GNUC__ of 5, it will automatically DTRT and try to include <linux/compiler-gcc5.h> instead of #4.
And then the check in gcc4.h for 4.1.0 and 4.1.1 is much simplified. The two patches I pushed out add functionality, but don't actually add any new lines (the first simplification patch removes more lines than it adds, and the second one that adds the __weak bug test adds as mahy lines as the cleanup removed).
And it all looks more logical too, imho.
Linus
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 18 lines · Linus Torvalds
Quoted 4 lines · Linus Torvalds
I think this is wrong.
Just move the check into <
linux/compiler-gcc4.h>In fact, looking at that whole mess, I redid it all. It was disgusting how conditionals in
gcc4.hneeded to double-check that__GNUC__really was 4 (rather than something bigger), which largely negated the whole nice clean compiler version separation.I pushed out my preferred version, which fixes up the whole thing. The gcc4 header file now only gets included for
__GNUC__== 4, and when we ever see a__GNUC__of 5, it will automatically DTRT and try to include <linux/compiler-gcc5.h> instead of #4.
Quoted 7 lines
And then the check in
gcc4.hfor 4.1.0 and 4.1.1 is much simplified. The two patches I pushed out add functionality, but don't actually add any new lines (the first simplification patch removes more lines than it adds, and the second one that adds the__weakbug test adds as mahy lines as the cleanup removed).And it all looks more logical too, imho.
yeah, agreed, much cleaner.
The gcc3 check for gcc 3.0 and 3.1 can be pushed into gcc3 as well - not sure whether you fixed that. (i fixed it in the patch i just sent - but i didnt notice the gcc5 mess in gcc4.h that you fixed)
Ingo
PATCH 1/1 Disallow gcc versions 3.{0,1}
Quoted 7 lines · Ingo Molnar
Quoted 1 line
And it all looks more logical too, imho.
yeah, agreed, much cleaner.
The gcc3 check for gcc 3.0 and 3.1 can be pushed into gcc3 as well - not sure whether you fixed that. (i fixed it in the patch i just sent - but i didnt notice the gcc5 mess in
gcc4.hthat you fixed)
ok, i see them now:
f9d1425: Disallow gcc versions 4.1.{0,1}
f153b82: Sanitize gcc version header includes
agreed, much cleaner.
One small issue - i think this now allows gcc 3.0 and 3.1 again - which we didnt before. Dont we need the patch below - am i missing something?
Ingo
------------------->
Quoted 1 line
From
1458f25412a838968e845ec0bc1b18db70cba7cdMon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Fri, 2 Jan 2009 18:53:14 +0100
Subject: [PATCH] Disallow gcc versions 3.{0,1}
GCC 3.0 and 3.1 are too old to build a working kernel.
--- include/linux/compiler-gcc3.h | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
include/linux/compiler-gcc3.h +4 -0
@@ -2,6 +2,10 @@#error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead."#endif +#if __GNUC_MINOR__ <2 +# error Sorry, your compiler is too old - please upgrade it. +#endif +#if __GNUC_MINOR__ >=3 # define __used __attribute__((__used__))#else
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Ingo MolnarQuoted 4 lines · Ingo Molnar
The gcc3 check for gcc 3.0 and 3.1 can be pushed into gcc3 as well - not sure whether you fixed that. (i fixed it in the patch i just sent - but i didnt notice the gcc5 mess in
gcc4.hthat you fixed)
I just dropped it. Gcc 3.0 and 3.1 are so old that we simply don't care.
Nobody who has compiled a kernel in the last two years can possibly have those versions: we've failed the build on them since December 2006. And there obviously won't be any new users either. So consider it a generational garbage collection event.
Of course, if we really want to check for old compiler versions, we can add the check back (to the gcc3 header file where it belongs), but it does seem to be entirely historical.
Linus
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 9 lines · Linus Torvalds
Quoted 4 lines · Ingo Molnar
The gcc3 check for gcc 3.0 and 3.1 can be pushed into gcc3 as well - not sure whether you fixed that. (i fixed it in the patch i just sent - but i didnt notice the gcc5 mess in
gcc4.hthat you fixed)I just dropped it. Gcc 3.0 and 3.1 are so old that we simply don't care.
we didnt support it for quite some time. If you look at that ugly version check you replaced:
#if __GNUC__ >= 4 && !gcc41_inlining_bug
# include <linux/compiler-gcc4.h> #elif __GNUC__ == 3 && __GNUC_MINOR__ >= 2 # include <linux/compiler-gcc3.h> #else # error Sorry, your compiler is too old, too buggy or not recognized. #endif
it has a hidden 'gcc 3.0 / 3.1 is not supported' condition in it. So what i tried to point out that your patch causes a regression here - we dont filter out gcc 3.0/3.1 out anymore.
Ingo
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 3 lines · Ingo Molnar
So what i tried to point out that your patch causes a regression here - we dont filter out gcc 3.0/3.1 out anymore.
What I tried to tell you was that we don't care - nobody can have it anyway. If somebody tried to compile the kernel with it, we've already refused for the last 2+ years. So there are no old users out there. And there certainly aren't any new ones.
Linus
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 5 lines · Linus Torvalds
What I tried to tell you was that we don't care - nobody can have it anyway. If somebody tried to compile the kernel with it, we've already refused for the last 2+ years. So there are no old users out there. And there certainly aren't any new ones.
.. but we cetrtainly can add the check back easily enough if you really want to, of course. I just don't think there is much point.
Linus
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Linus TorvaldsQuoted 11 lines · Linus Torvalds
Quoted 3 lines · Ingo Molnar
So what i tried to point out that your patch causes a regression here - we dont filter out gcc 3.0/3.1 out anymore.
What I tried to tell you was that we don't care - nobody can have it anyway. If somebody tried to compile the kernel with it, we've already refused for the last 2+ years. So there are no old users out there. And there certainly aren't any new ones.
Yes some people (including me) still have them and are happy that there is a check to prevent accidental builds with an inappropriate compiler.
Willy
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 3 lines · Willy Tarreau
Yes some people (including me) still have them and are happy that there is a check to prevent accidental builds with an inappropriate compiler.
Heh, ok. If people really do actively have that version, let's add the check back in.
Linus
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Linus TorvaldsQuoted 18 lines · Linus Torvalds
Quoted 4 lines · Linus Torvalds
I think this is wrong.
Just move the check into <
linux/compiler-gcc4.h>In fact, looking at that whole mess, I redid it all. It was disgusting how conditionals in
gcc4.hneeded to double-check that__GNUC__really was 4 (rather than something bigger), which largely negated the whole nice clean compiler version separation.I pushed out my preferred version, which fixes up the whole thing. The gcc4 header file now only gets included for
__GNUC__== 4, and when we ever see a__GNUC__of 5, it will automatically DTRT and try to include <linux/compiler-gcc5.h> instead of #4.
Quoted 7 lines
And then the check in
gcc4.hfor 4.1.0 and 4.1.1 is much simplified. The two patches I pushed out add functionality, but don't actually add any new lines (the first simplification patch removes more lines than it adds, and the second one that adds the__weakbug test adds as mahy lines as the cleanup removed).And it all looks more logical too, imho.
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.
Not that I actually try to run these beasts but just being able to do cross compile has served me well.
Last I looked (only few days ago) crosstool-ng did not support sparc :-(
Sam
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 6 lines · Sam Ravnborg
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.Not that I actually try to run these beasts but just being able to do cross compile has served me well.
We _could_ make a "CONFIG_COMPILE_ONLY" check, but wouldn't it be even nicer to make sure the cross-compiles are something that might actually be expected to work?
I realize that cross-tools tend to lag a bit - the pressure to maintain them tends to be much lower - but I was sure we had somebody who did a reasonable cross-compiler toolchain. Is gcc-4.1 really the most modern thing that is easily available?
Linus
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 10 lines · Linus Torvalds
Quoted 6 lines · Sam Ravnborg
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.Not that I actually try to run these beasts but just being able to do cross compile has served me well.
Quoted 8 lines
We _could_ make a "
CONFIG_COMPILE_ONLY" check, but wouldn't it be even nicer to make sure the cross-compiles are something that might actually be expected to work?I realize that cross-tools tend to lag a bit - the pressure to maintain them tends to be much lower - but I was sure we had somebody who did a reasonable cross-compiler toolchain. Is gcc-4.1 really the most modern thing that is easily available?
Asked google and it found following page:
http://www.kernel.org/pub/tools/crosstool/
Architecuter OK? gcc version
---------------------------------
alpha No gcc 4.0.2 arm Yes gcc 3.4.5 ia64 Yes gcc 3.4.5 m68k Yes gcc 3.4.5 mips Yes gcc 3.4.5 sh4 Yes gcc 3.4.5 sparc Yes gcc 3.4.5 sparc64 Yes gcc 3.4.5 x86_64 Yes gcc 3.4.5
So from this list of tool chains we can continue to do cross builds of all except alpha.
But the gcc version is getting ancient..
Why it shall be so hard to do cross build toolchains is above my imagination but then I also never looked at what it involes.
Added Vegard that maintain these pages.
Sam
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 34 lines · Sam Ravnborg
Quoted 7 lines · Linus Torvalds
Quoted 5 lines · Sam Ravnborg
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.Not that I actually try to run these beasts but just being able to do cross compile has served me well.
Quoted 8 lines
We _could_ make a "
CONFIG_COMPILE_ONLY" check, but wouldn't it be even nicer to make sure the cross-compiles are something that might actually be expected to work?I realize that cross-tools tend to lag a bit - the pressure to maintain them tends to be much lower - but I was sure we had somebody who did a reasonable cross-compiler toolchain. Is gcc-4.1 really the most modern thing that is easily available?
Asked google and it found following page:
http://www.kernel.org/pub/tools/crosstool/
Architecuter OK? gcc version
---------------------------------alpha No gcc 4.0.2 arm Yes gcc 3.4.5 ia64 Yes gcc 3.4.5 m68k Yes gcc 3.4.5 mips Yes gcc 3.4.5 sh4 Yes gcc 3.4.5 sparc Yes gcc 3.4.5 sparc64 Yes gcc 3.4.5 x86_64 Yes gcc 3.4.5
Quoted 8 lines
So from this list of tool chains we can continue to do cross builds of all except alpha.
But the gcc version is getting ancient..Why it shall be so hard to do cross build toolchains is above my imagination but then I also never looked at what it involes.
Added Vegard that maintain these pages.
I doubt that these are any more recent, but the filenames don't say:
http://userweb.kernel.org/~akpm/cross-compilers/
Yes, it is an ongoing problem.
Signature · 1 line
~Randy
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Linus TorvaldsQuoted 10 lines · Linus Torvalds
Quoted 6 lines · Sam Ravnborg
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.Not that I actually try to run these beasts but just being able to do cross compile has served me well.
Quoted 8 lines
We _could_ make a "
CONFIG_COMPILE_ONLY" check, but wouldn't it be even nicer to make sure the cross-compiles are something that might actually be expected to work?I realize that cross-tools tend to lag a bit - the pressure to maintain them tends to be much lower - but I was sure we had somebody who did a reasonable cross-compiler toolchain. Is gcc-4.1 really the most modern thing that is easily available?
FWIW, I'm using 4.3 on all targets at the moment. Seegit://git.kernel.org/pub/scm/linux/kernel/git/viro/toolchain.git/
for fedora-based variant of that sucker. And yes, it does include cross-to-sparc; all but sh/sh64, in fact (sh had serious compiler breakage around 4.3.0 and backporting from -HEAD was far beyond what I considered reasonable at that point).
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 7 lines · Al Viro
FWIW, I'm using 4.3 on all targets at the moment. See
git://git.kernel.org/pub/scm/linux/kernel/git/viro/toolchain.git/
for fedora-based variant of that sucker. And yes, it does include cross-to-sparc; all but sh/sh64, in fact (sh had serious compiler breakage around 4.3.0 and backporting from -HEAD was far beyond what I considered reasonable at that point).
The full opensuse distribution also has a couple of spec files for generating cross compilers from recent versions. These are for icecream, but can be relatively easily adapted (or the binaries reused)
In general I don't think building cross compilers is as hard as it used to be, so it can be reasonably done without any support scripts too.
Really no excuse to still use the old crosstool crap :)
-Andi
Signature · 1 line
[email protected]
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 9 lines · Andi Kleen
Quoted 7 lines · Al Viro
FWIW, I'm using 4.3 on all targets at the moment. See
git://git.kernel.org/pub/scm/linux/kernel/git/viro/toolchain.git/
for fedora-based variant of that sucker. And yes, it does include cross-to-sparc; all but sh/sh64, in fact (sh had serious compiler breakage around 4.3.0 and backporting from -HEAD was far beyond what I considered reasonable at that point).
Quoted 8 lines
The full opensuse distribution also has a couple of spec files for generating cross compilers from recent versions. These are for icecream, but can be relatively easily adapted (or the binaries reused)
In general I don't think building cross compilers is as hard as it used to be, so it can be reasonably done without any support scripts too.
*snort*
Well, the only support script here is "call rpmbuild with the right arguments" (and kmk, which is about running kernel cross-build conveniently and has nothing to do with building cross-toolchain itself).
I'll need to update that to more current gcc anyway (and see if that takes care of sh/sh64), so if you can dig those .spec out... throw them my way and I'll add them to repository.
How well do they handle the targets for which you have no glibc-dev binary rpms, BTW? I needed headers for ia64 and ppc64; both fortunately are among the generally supported targets...
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Linus TorvaldsQuoted 4 lines · Linus Torvalds
I realize that cross-tools tend to lag a bit - the pressure to maintain them tends to be much lower - but I was sure we had somebody who did a reasonable cross-compiler toolchain. Is gcc-4.1 really the most modern thing that is easily available?
Not sure about crosstool and other platforms but I'm using gcc 4.3.2+ for ARM (on x86_64) and building it is straightforward. Just unpack binutils, gcc (and optionally glibc); configure; make; make install.
Prerequisites: kernel headers and minimal glibc installed. (Some recent glibc versions require a patch or two).
Signature · 1 line
Krzysztof Halasa
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Sam RavnborgQuoted 4 lines · Sam Ravnborg
Quoted 1 line
And it all looks more logical too, imho.
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.
hm, i just did a successful cross-build from x86 to alpha:
KSYM .tmp_kallsyms2.S AS .tmp_kallsyms2.o LD vmlinux SYSMAP System.map SYSMAP .tmp_System.map
phoenix:~/linux/linux> head -6 /dev/shm/tip/build/.config #
# Automatically generated make config: don't edit # Linux kernel version: 2.6.28
# Fri Jan 2 19:28:14 2009
#
CONFIG_ALPHA=y
with these commits present:
f9d1425: Disallow gcc versions 4.1.{0,1}
f153b82: Sanitize gcc version header includes
what type of cross-build breakage do they cause?
Ingo
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 24 lines · Ingo Molnar
Quoted 4 lines · Sam Ravnborg
Quoted 1 line
And it all looks more logical too, imho.
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.hm, i just did a successful cross-build from x86 to alpha:
KSYM .tmp_kallsyms2.S AS .tmp_kallsyms2.o LD vmlinux SYSMAP System.map SYSMAP .tmp_System.mapphoenix:~/linux/linux> head -6
/dev/shm/tip/build/.config#
# Automatically generated make config: don't edit # Linux kernel version: 2.6.28
# Fri Jan 2 19:28:14 2009
#
CONFIG_ALPHA=y
Quoted 6 lines
with these commits present:
f9d1425: Disallow gcc versions 4.1.{0,1}
f153b82: Sanitize gcc version header includeswhat type of cross-build breakage do they cause?
The default gcc made by demo-alpha with crosstool is version 4.1.0:
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/alpha-unknown-linux-gnu/bin/alpha-unknown-linux-gnu-gcc --version
alpha-unknown-linux-gnu-gcc (GCC) 4.1.0
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Sam
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 32 lines · Sam Ravnborg
Quoted 24 lines · Ingo Molnar
Quoted 4 lines · Sam Ravnborg
Quoted 1 line
And it all looks more logical too, imho.
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.hm, i just did a successful cross-build from x86 to alpha:
KSYM .tmp_kallsyms2.S AS .tmp_kallsyms2.o LD vmlinux SYSMAP System.map SYSMAP .tmp_System.mapphoenix:~/linux/linux> head -6
/dev/shm/tip/build/.config#
# Automatically generated make config: don't edit # Linux kernel version: 2.6.28
# Fri Jan 2 19:28:14 2009
#
CONFIG_ALPHA=yQuoted 6 lines
with these commits present:
f9d1425: Disallow gcc versions 4.1.{0,1}
f153b82: Sanitize gcc version header includeswhat type of cross-build breakage do they cause?
Quoted 7 lines
The default gcc made by demo-alpha with crosstool is version 4.1.0:
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/alpha-unknown-linux-gnu/bin/alpha-unknown-linux-gnu-gcc--version
alpha-unknown-linux-gnu-gcc (GCC) 4.1.0
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ah, ok. I build cross-compilers from scratch, so i have 4.3.3-pre:
phoenix:~/linux/linux> /opt/crossgcc/cross/bin/alpha-linux-gcc -v [...]
gcc version 4.3.3 20081123 (prerelease) (GCC)
Ingo
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 12 lines · Ingo Molnar
Quoted 9 lines · Sam Ravnborg
Quoted 1 line
what type of cross-build breakage do they cause?
The default gcc made by demo-alpha with crosstool is version 4.1.0:
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/alpha-unknown-linux-gnu/bin/alpha-unknown-linux-gnu-gcc--version
alpha-unknown-linux-gnu-gcc (GCC) 4.1.0
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Quoted 7 lines
ah, ok. I build cross-compilers from scratch, so i have 4.3.3-pre:
phoenix:~/linux/linux>
/opt/crossgcc/cross/bin/alpha-linux-gcc-v [...]
gcc version 4.3.3 20081123 (prerelease) (GCC)Ingo
I forwarded the thread to Dan Kegel to make him aware, that the used gcc version in crosstools makes problems.
Signature · 1 line
Bye bye ... Detlef
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Sam RavnborgQuoted 9 lines
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.Not that I actually try to run these beasts but just being able to do cross compile has served me well.
Last I looked (only few days ago) crosstool-ng did not support sparc :-(
There are also various variants of 4.1.1 around with the fix for that inline bug backported (I think that's the case of the compiler that ships with the Cell SDK for example).
What a f. mess :-(
Cheers,
Ben.
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Quoted 5 lines · Benjamin Herrenschmidt
Quoted 5 lines
Bugger....
Now I cannot do cross compile for: alpha, arm, m68k and sparc.
Quoted 9 lines
Quoted 4 lines
Not that I actually try to run these beasts but just being able to do cross compile has served me well.
Last I looked (only few days ago) crosstool-ng did not support sparc :-(
There are also various variants of 4.1.1 around with the fix for that inline bug backported (I think that's the case of the compiler that ships with the Cell SDK for example).
We could add a feature check during the early phase of the kernel build so we know if gcc has this bug or not.
But this would be the first time to do so IIRC - today we only do some limited check to see if certain options are supported.
Sam
Re: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
In reply to Linus TorvaldsQuoted 28 lines · Linus Torvalds
Quoted 12 lines · Ingo Molnar
include/linux/compiler.h +5
-1@@ -36,12 +36,25 @@ extern void __chk_io_ptr(const volatile void __iomem *);#ifdef __KERNEL__ -#if __GNUC__ >=4 +/* +* GCC 4.1.0 and 4.1.1 has a bug that can miscompile __weak symbols, +* by inlining __weak functions into same-file call sites - breaking the +* kernel if the __weak symbol is overriden later on. +* include/linux/compiler.h extern void __chk_io_ptr(const volatile void __iomem *); · line 53
Quoted 10 lines
include/linux/compiler.h +9
-0+* We have not found a clean way to work around this bug on the source +* code level, so we do not allow these compilers (which are quite +* rare these days, have other bugs and are superceded by the 4.1.2 +* bugfix release anyway): +*/ +#define gcc41_inlining_bug \ + (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1) + +#if __GNUC__ >=4 && !gcc41_inlining_bug# include <linux/compiler-gcc4.h> I think this is wrong.
Quoted 5 lines
Just move the check into <
linux/compiler-gcc4.h>It makes no sense to do stuff that is specific to gcc4 in the general gcc header file. It seems you did this just in order to re-use a (bad) generic error case.
yeah. I first hacked the generic check then saw how ugly the end result was and moved it one level higher. Which was less ugly than where it came from and not much worse than the starting point (so it passed my filters) but still not clean enough (so it didnt pass your filters).
How about the patch below instead? It cleans up the generic check by splitting all the per-major-version checks out into gcc4 and gcc3.
(still untested)
Ingo
------------->
Quoted 1 line
From
bb951ce0794f0e5974b834eb14e974a0a2c119dbMon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Fri, 2 Jan 2009 12:46:22 +0100
Subject: [PATCH] kbuild: Disallow GCC 4.1.0 / 4.1.1
Impact: fix crashes that can trigger if built with GCC 4.1.0 or 4.1.1
GCC 4.1.0 and 4.1.1 has a bug that can miscompile __weak symbols, by inlining __weak functions into same-file call sites - breaking the kernel if the __weak symbol is overriden later on.
In the past we tried to work around this problem by artificially isolating call site and definition site - but these bugs tend to pop up regularly:
43a2563: sparseirq: move __weak symbols into separate compilation unit 13a0c3c: sparseirq: work around compiler optimizing away __weak functions
And Linus has extended Sparse to report same-file callsites for __weak symbols - which gave two dozen hits.
We have not found a clean way to work around this bug on the source code level (noinline and explicit barrier()s are ignored by GCC), so we do not allow these compilers (which are quite rare these days, have other bugs and are superceded by the 4.1.2 bugfix release anyway).
Kernel builds under gcc 410 or 411 will now fail with this error message:
Sorry, GCC 4.1.0/4.1.1 are too buggy to build the kernel - please upgrade to 4.1.2 or later versions.
--- include/linux/compiler-gcc3.h | 4 ++++ include/linux/compiler-gcc4.h | 14 ++++++++++++++ include/linux/compiler.h | 4 ++-- 3 files changed, 20 insertions(+), 2 deletions(-)
include/linux/compiler-gcc3.h +4 -0
@@ -2,6 +2,10 @@#error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead."#endif +#if __GNUC_MINOR__ <2 +# error Sorry, your compiler is too old - please upgrade it. +#endif +/* These definitions are for GCC v3.x. */ #include <linux/compiler-gcc.h>
include/linux/compiler-gcc4.h +14 -0
@@ -2,6 +2,20 @@#error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead."#endif +/* +* GCC 4.1.0 and 4.1.1 has a bug that can miscompile __weak symbols, +* by inlining __weak functions into same-file call sites - breaking the +* kernel if the __weak symbol is overriden later on. +* +* We have not found a clean way to work around this bug on the source +* code level, so we do not allow these compilers (which are quite +* rare these days, have other bugs and are superceded by the 4.1.2 +* bugfix release anyway): +*/ +#if __GNUC__ ==4 && __GNUC_MINOR__ ==1 && __GNUC_PATCHLEVEL__ <=1 +# error Sorry, GCC 4.1.0/4.1.1 are too buggy to build the kernel - please upgrade to 4.1.2 or later versions. +#endif +/* These definitions are for GCC v4.x. */ #include <linux/compiler-gcc.h>
include/linux/compiler.h +2 -2
@@ -38,10 +38,10 @@ extern void __chk_io_ptr(const volatile void __iomem *);#if __GNUC__ >=4 # include <linux/compiler-gcc4.h> -#elif __GNUC__ ==3 && __GNUC_MINOR__ >=2 +#elif __GNUC__ ==3 # include <linux/compiler-gcc3.h> #else -# error Sorry, your compiler is too old/not recognized. +# error Sorry, your compiler is too old or not recognized.#endif #define notrace __attribute__((no_instrument_function))
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Linus TorvaldsQuoted 7 lines · Linus Torvalds
Quoted 3 lines · Andrew Morton
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
Quoted 8 lines
If it really is just those releases, then yes, considering the number of cases we apparently have, and considering how ugly it is in some cases to move the weak function anywhere else, maybe banning those versions is the proper thing to do.
It probably won't hurt very many people - yeah, some people will be forced to upgrade, but I have this memory of early 4.1 having had other bugs anyway, so it's probably a good idea.
That would be _really_ nice to do IMHO: in many cases putting the __weak definition into same-file scope with a call site is a natural approach. I think that's how we ended up having so many instances of that bug. When you use __weak as a 'default implementation' for some function, then it's very natural to put it into the same file that also uses it.
It goes into separate, inactive scope only in a few special cases: such as when it's some library function that can be overriden by the architecture. But if it's some non-libray kernel code then the usage site is close to the definition site.
If you look at most of the __weak fixes they IMO actually turned clean code into less clean code: they detached some natural clustering of definition and callsite.
And __weak is very elegant IMO, it can avoid a lot of #ifdefs and can be used to self-document architecture interfaces - so it would be nice to make it always work, regardless of the callsite's scope.
Ingo
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
Quoted 14 lines · On Thu, 1 Jan 2009 15:24:01 +0100 Ingo Molnar <[email protected]> wrote:
Quoted 12 lines · Linus Torvalds
Quoted 3 lines · Andrew Morton
Adrian claimed that it was gcc-4.1.0 and 4.1.1 only. He proposed banning them: http://lkml.org/lkml/2008/8/5/444
If it really is just those releases, then yes, considering the number of cases we apparently have, and considering how ugly it is in some cases to move the weak function anywhere else, maybe banning those versions is the proper thing to do.
Quoted 5 lines
Quoted 3 lines
It probably won't hurt very many people - yeah, some people will be forced to upgrade, but I have this memory of early 4.1 having had other bugs anyway, so it's probably a good idea.
That would be _really_ nice to do IMHO
I wonder if we should do it in -stable too. Probably yes.
Helge Deller
maintainerRe: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Linus TorvaldsQuoted 15 lines · Linus Torvalds
Quoted 10 lines · Helge Deller
[PATCH 1/2]
module.c: fix module loading failure of large kernel modulesWhen creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
Differences of this patch to previous versions:
- added weak funtionarch_module_section_size()This doesn't work.
Quoted 8 lines
We've had this bug several times now, and one of them just very recently.
Some gcc versions will inline weak functions if they are in scope - even if there is a non-weak function somewhere else. So you MUST NOT have the weak definition in the same file (or indirectly called through some inline functions in a header file) as the call. Because if you do, then any user with the wrong version of gcc will get the weak function semantics, even if it was meant to be overridden by something else.
Ok, that might explain why I saw some strange things in the unwind tables after that I switched to using the weak function (hppa-crosscompiler, gcc-3.3.4).
Quoted 9 lines
kernel/module.c static int simplify_symbols(Elf_Shdr *sechdrs, · line 1583
Quoted 3 lines
kernel/module.c +3
-0+/* Additional bytes needed by arch in front of individual sections */ +unsigned int __attribute__ ((weak))arch_module_section_size ( +struct module *mod,unsigned int section)We don't write out that whole "
__attribute__" crud. We useunsigned in
__weakarch_module_section_size(struct module *mod, unsigned int section)instead.
Ok.
Quoted 1 line
But as mentioned, it needs to be in another compilation unit.
Understood.
Rusty, back to you for an advise on how to continue ;-) (I assume Rusty is just right now celebrating new-year)
Helge
James Bottomley
maintainerRe: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Linus TorvaldsQuoted 16 lines · Linus Torvalds
Quoted 11 lines · Helge Deller
[PATCH 1/2]
module.c: fix module loading failure of large kernel modulesWhen creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
Differences of this patch to previous versions:
- added weak funtionarch_module_section_size()This doesn't work.
Quoted 8 lines
We've had this bug several times now, and one of them just very recently.
Some gcc versions will inline weak functions if they are in scope - even if there is a non-weak function somewhere else. So you MUST NOT have the weak definition in the same file (or indirectly called through some inline functions in a header file) as the call. Because if you do, then any user with the wrong version of gcc will get the weak function semantics, even if it was meant to be overridden by something else.
Um, but we got told to use all these weak functions instead of the ARCH_HAS... defines. They certainly litter the x86 boot code. The standard pattern was to put the weak function in the file where it was used, which is what you're now saying will miscompile.
Which gcc versions are the problem? Because it's going to be a bit painful catching and killing all the problems ... it might be better just to patch the master kernel makefile to refuse to build with the offending gcc versions.
James
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Linus TorvaldsQuoted 11 lines · On Thursday 01 January 2009 03:59:36 Linus Torvalds wrote:
Quoted 9 lines · Helge Deller
[PATCH 1/2]
module.c: fix module loading failure of large kernel modulesWhen creating the final layout of a kernel module in memory, allow the module loader to reserve some additional memory in front of a given section. This is currently only needed for the parisc port which needs to put the stub entries there to fulfill the 17/22bit PCREL relocations with large kernel modules like xfs.
Quoted 8 lines
Quoted 2 lines
Differences of this patch to previous versions:
- added weak funtionarch_module_section_size()This doesn't work.
We've had this bug several times now, and one of them just very recently.
Some gcc versions will inline weak functions if they are in scope
Ah, someone hit this elsewhere and thought this was an arch-specific bug. Any chance we can just kill those compiler versions and move on with our lives? 4.1.3 definitely doesn't have the problem.
Quoted 1 line
We don't write out that whole "
__attribute__" crud.
I think what you mean is "I prefer __weak". Which is fine, and not trivially disprovable by grep.
It's a gratuitous kernelism, but it's an inoffensive one. Rusty.
Re: [PATCH] parisc: fix module loading failure of large kernel modules (take 4)
In reply to Linus TorvaldsQuoted 2 lines · Linus Torvalds
Some gcc versions will inline weak functions if they are in scope - even if there is a non-weak function somewhere else. So you MUST NOT have the weak definition in the same file (or indirectly called through some inline functions in a header file) as the call. Because if you do, then any user with the wrong version of gcc will get the weak function semantics, even if it was meant to be overridden by something else.
Yes. I think this behaviour is considered to be desperately broken by the gcc developers and has been fixed in all recent gccs. There are a couple of broken versions, and there have been patches floating around to just refuse to use them; otherwise __weak is effectively unusable. (Ah, I see Adrian has posted it again and everyone agrees with it.)
On the other hand, I have seen a couple of instances of "inline __weak" which is insane, but I don't know if gcc does anything crazy with it, or if its common enough to bother warning about.
J