Commit 43a256322ac1fc105c181b3cade3b9bfc0b63ca1

Authored by Yinghai Lu
Committed by Ingo Molnar
1 parent b2e2fe9962

sparseirq: move __weak symbols into separate compilation unit

GCC has a bug with __weak alias functions: if the functions are in
the same compilation unit as their call site, GCC can decide to
inline them - and thus rob the linker of the opportunity to override
the weak alias with the real thing.

So move all the IRQ handling related __weak symbols to kernel/irq/chip.c.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 5 changed files with 26 additions and 22 deletions Side-by-side Diff

include/linux/interrupt.h
... ... @@ -467,5 +467,11 @@
467 467  
468 468 int show_interrupts(struct seq_file *p, void *v);
469 469  
  470 +struct irq_desc;
  471 +
  472 +extern int early_irq_init(void);
  473 +extern int arch_early_irq_init(void);
  474 +extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
  475 +
470 476 #endif
... ... @@ -193,9 +193,6 @@
193 193 const char *name;
194 194 } ____cacheline_internodealigned_in_smp;
195 195  
196   -extern int early_irq_init(void);
197   -extern int arch_early_irq_init(void);
198   -extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
199 196 extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
200 197 struct irq_desc *desc, int cpu);
201 198 extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
... ... @@ -539,16 +539,6 @@
539 539 {
540 540 }
541 541  
542   -int __init __weak arch_early_irq_init(void)
543   -{
544   - return 0;
545   -}
546   -
547   -int __init __weak early_irq_init(void)
548   -{
549   - return arch_early_irq_init();
550   -}
551   -
552 542 asmlinkage void __init start_kernel(void)
553 543 {
554 544 char * command_line;
... ... @@ -261,15 +261,6 @@
261 261 }
262 262 EXPORT_SYMBOL(enable_irq);
263 263  
264   -/*
265   - * [ Not in kernel/irq/handle.c, so that GCC does not
266   - * inline the __weak alias: ]
267   - */
268   -int __weak arch_init_chip_data(struct irq_desc *desc, int cpu)
269   -{
270   - return 0;
271   -}
272   -
273 264 static int set_irq_wake_real(unsigned int irq, unsigned int on)
274 265 {
275 266 struct irq_desc *desc = irq_to_desc(irq);
... ... @@ -797,4 +797,24 @@
797 797 }
798 798 EXPORT_SYMBOL(on_each_cpu);
799 799 #endif
  800 +
  801 +/*
  802 + * [ These __weak aliases are kept in a separate compilation unit, so that
  803 + * GCC does not inline them incorrectly. ]
  804 + */
  805 +
  806 +int __init __weak early_irq_init(void)
  807 +{
  808 + return 0;
  809 +}
  810 +
  811 +int __init __weak arch_early_irq_init(void)
  812 +{
  813 + return 0;
  814 +}
  815 +
  816 +int __weak arch_init_chip_data(struct irq_desc *desc, int cpu)
  817 +{
  818 + return 0;
  819 +}