Skip to content

Commit

Permalink
sparseirq: move __weak symbols into separate compilation unit
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
yhlu authored and Ingo Molnar committed Dec 29, 2008
1 parent b2e2fe9 commit 43a2563
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 22 deletions.
6 changes: 6 additions & 0 deletions include/linux/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,4 +467,10 @@ static inline void init_irq_proc(void)

int show_interrupts(struct seq_file *p, void *v);

struct irq_desc;

extern int early_irq_init(void);
extern int arch_early_irq_init(void);
extern int arch_init_chip_data(struct irq_desc *desc, int cpu);

#endif
3 changes: 0 additions & 3 deletions include/linux/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,6 @@ struct irq_desc {
const char *name;
} ____cacheline_internodealigned_in_smp;

extern int early_irq_init(void);
extern int arch_early_irq_init(void);
extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
struct irq_desc *desc, int cpu);
extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
Expand Down
10 changes: 0 additions & 10 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,16 +539,6 @@ void __init __weak thread_info_cache_init(void)
{
}

int __init __weak arch_early_irq_init(void)
{
return 0;
}

int __init __weak early_irq_init(void)
{
return arch_early_irq_init();
}

asmlinkage void __init start_kernel(void)
{
char * command_line;
Expand Down
9 changes: 0 additions & 9 deletions kernel/irq/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,6 @@ void enable_irq(unsigned int irq)
}
EXPORT_SYMBOL(enable_irq);

/*
* [ Not in kernel/irq/handle.c, so that GCC does not
* inline the __weak alias: ]
*/
int __weak arch_init_chip_data(struct irq_desc *desc, int cpu)
{
return 0;
}

static int set_irq_wake_real(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_to_desc(irq);
Expand Down
20 changes: 20 additions & 0 deletions kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,3 +797,23 @@ int on_each_cpu(void (*func) (void *info), void *info, int wait)
}
EXPORT_SYMBOL(on_each_cpu);
#endif

/*
* [ These __weak aliases are kept in a separate compilation unit, so that
* GCC does not inline them incorrectly. ]
*/

int __init __weak early_irq_init(void)
{
return 0;
}

int __init __weak arch_early_irq_init(void)
{
return 0;
}

int __weak arch_init_chip_data(struct irq_desc *desc, int cpu)
{
return 0;
}

0 comments on commit 43a2563

Please sign in to comment.