Commit 67c69b53 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds

[PATCH] move irq_enter and irq_exit to common code

This code is the same for all architectures with the following invariants:

- arm gurantees irqs are disabled when calling irq_exit so it can call
  __do_softirq directly instead of do_softirq

- arm26 is totally broken for about half a year, I didn't care for it

- some architectures use softirq_pending(smp_processor_id()) instead of
  local_softirq_pending, but they always evaluate to the same

This patch moves the out of line irq_exit implementation from
kernel/irq/handle.c which depends on CONFIG_GENERIC_HARDIRQS to
kernel/softirq.c which is always compiled, tweaks it for the arm special
case and moves the irq_enter/irq_exit/nmi_enter/nmi_exit bits from
asm-*/hardirq.h to linux/hardirq.h
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 08ccfcc1
...@@ -60,21 +60,6 @@ __u8 isa_irq_to_vector_map[16] = { ...@@ -60,21 +60,6 @@ __u8 isa_irq_to_vector_map[16] = {
}; };
EXPORT_SYMBOL(isa_irq_to_vector_map); EXPORT_SYMBOL(isa_irq_to_vector_map);
static inline void
irq_enter (void)
{
preempt_count() += HARDIRQ_OFFSET;
}
static inline void
irq_exit (void)
{
preempt_count() -= IRQ_EXIT_OFFSET;
if (!in_interrupt() && local_softirq_pending())
do_softirq();
preempt_enable_no_resched();
}
int int
assign_irq_vector (int irq) assign_irq_vector (int irq)
{ {
......
...@@ -29,14 +29,4 @@ typedef struct { ...@@ -29,14 +29,4 @@ typedef struct {
#error HARDIRQ_BITS is too low! #error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && \
softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* _ALPHA_HARDIRQ_H */ #endif /* _ALPHA_HARDIRQ_H */
...@@ -27,16 +27,6 @@ typedef struct { ...@@ -27,16 +27,6 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
extern asmlinkage void __do_softirq(void);
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && local_softirq_pending()) \
__do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* __ASM_HARDIRQ_H */ #endif /* __ASM_HARDIRQ_H */
...@@ -28,13 +28,4 @@ typedef struct { ...@@ -28,13 +28,4 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* __ASM_HARDIRQ_H */ #endif /* __ASM_HARDIRQ_H */
...@@ -26,13 +26,4 @@ typedef struct { ...@@ -26,13 +26,4 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif #endif
...@@ -23,13 +23,4 @@ typedef struct { ...@@ -23,13 +23,4 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif #endif
...@@ -24,13 +24,4 @@ typedef struct { ...@@ -24,13 +24,4 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* __M68K_HARDIRQ_H */ #endif /* __M68K_HARDIRQ_H */
...@@ -38,13 +38,4 @@ typedef struct { ...@@ -38,13 +38,4 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* _PARISC_HARDIRQ_H */ #endif /* _PARISC_HARDIRQ_H */
...@@ -37,24 +37,10 @@ softirq_pending(unsigned int cpu) ...@@ -37,24 +37,10 @@ softirq_pending(unsigned int cpu)
} }
#define __ARCH_IRQ_STAT #define __ARCH_IRQ_STAT
#define __ARCH_HAS_DO_SOFTIRQ
#define HARDIRQ_BITS 8 #define HARDIRQ_BITS 8
extern void account_ticks(struct pt_regs *); extern void account_ticks(struct pt_regs *);
#define __ARCH_HAS_DO_SOFTIRQ
#define irq_enter() \
do { \
(preempt_count() += HARDIRQ_OFFSET); \
} while(0)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && local_softirq_pending()) \
/* Use the async. stack for softirq */ \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* __ASM_HARDIRQ_H */ #endif /* __ASM_HARDIRQ_H */
...@@ -23,16 +23,4 @@ typedef struct { ...@@ -23,16 +23,4 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define nmi_enter() (irq_enter())
#define nmi_exit() (preempt_count() -= HARDIRQ_OFFSET)
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* __ASM_SH_HARDIRQ_H */ #endif /* __ASM_SH_HARDIRQ_H */
...@@ -21,13 +21,4 @@ typedef struct { ...@@ -21,13 +21,4 @@ typedef struct {
#define HARDIRQ_BITS 8 #define HARDIRQ_BITS 8
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* __SPARC_HARDIRQ_H */ #endif /* __SPARC_HARDIRQ_H */
...@@ -20,13 +20,4 @@ typedef struct { ...@@ -20,13 +20,4 @@ typedef struct {
#define HARDIRQ_BITS 8 #define HARDIRQ_BITS 8
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* !(__SPARC64_HARDIRQ_H) */ #endif /* !(__SPARC64_HARDIRQ_H) */
...@@ -24,13 +24,4 @@ typedef struct { ...@@ -24,13 +24,4 @@ typedef struct {
# error HARDIRQ_BITS is too low! # error HARDIRQ_BITS is too low!
#endif #endif
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#endif /* __V850_HARDIRQ_H__ */ #endif /* __V850_HARDIRQ_H__ */
...@@ -77,12 +77,10 @@ extern void synchronize_irq(unsigned int irq); ...@@ -77,12 +77,10 @@ extern void synchronize_irq(unsigned int irq);
# define synchronize_irq(irq) barrier() # define synchronize_irq(irq) barrier()
#endif #endif
#ifdef CONFIG_GENERIC_HARDIRQS
#define nmi_enter() (preempt_count() += HARDIRQ_OFFSET) #define nmi_enter() (preempt_count() += HARDIRQ_OFFSET)
#define nmi_exit() (preempt_count() -= HARDIRQ_OFFSET) #define nmi_exit() (preempt_count() -= HARDIRQ_OFFSET)
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
extern void irq_exit(void); extern void irq_exit(void);
#endif
#endif /* LINUX_HARDIRQ_H */ #endif /* LINUX_HARDIRQ_H */
...@@ -72,17 +72,6 @@ irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) ...@@ -72,17 +72,6 @@ irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
return IRQ_NONE; return IRQ_NONE;
} }
/*
* Exit an interrupt context. Process softirqs if needed and possible:
*/
void irq_exit(void)
{
preempt_count() -= IRQ_EXIT_OFFSET;
if (!in_interrupt() && local_softirq_pending())
do_softirq();
preempt_enable_no_resched();
}
/* /*
* Have got an event to handle: * Have got an event to handle:
*/ */
......
...@@ -152,6 +152,23 @@ void local_bh_enable(void) ...@@ -152,6 +152,23 @@ void local_bh_enable(void)
} }
EXPORT_SYMBOL(local_bh_enable); EXPORT_SYMBOL(local_bh_enable);
#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
# define invoke_softirq() __do_softirq()
#else
# define invoke_softirq() do_softirq()
#endif
/*
* Exit an interrupt context. Process softirqs if needed and possible:
*/
void irq_exit(void)
{
preempt_count() -= IRQ_EXIT_OFFSET;
if (!in_interrupt() && local_softirq_pending())
invoke_softirq();
preempt_enable_no_resched();
}
/* /*
* This function must run with irqs disabled! * This function must run with irqs disabled!
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment