move irq_enter and irq_exit to common code
PATCH 1/1 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
arch/ia64/kernel/irq_ia64.c +0 -15
@@ -60,21 +60,6 @@ };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 assign_irq_vector (int irq) {
include/asm-alpha/hardirq.h +0 -10
@@ -29,14 +29,4 @@#error HARDIRQ_BITS is too low!#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 */
include/asm-arm/hardirq.h +1 -11
@@ -27,16 +27,6 @@# error HARDIRQ_BITS is too low!#endif -#define irq_enter () (preempt_count() += HARDIRQ_OFFSET) - -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) +#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1#endif /* __ASM_HARDIRQ_H */
include/asm-arm26/hardirq.h +0 -13
@@ -26,17 +26,4 @@# error HARDIRQ_BITS is too low!#endif -#define irq_enter () (preempt_count() += HARDIRQ_OFFSET) - -#ifndef CONFIG_SMP -#define irq_exit () \ - do { \ - preempt_count() -= HARDIRQ_OFFSET; \ - if (!in_interrupt() && softirq_pending(smp_processor_id())) \ - __asm__("bl%? __do_softirq": : : "lr");/* out of line */ \ -preempt_enable_no_resched (); \ - } while (0) - -#endif -#endif /* __ASM_HARDIRQ_H */
include/asm-cris/hardirq.h +0 -9
@@ -28,13 +28,4 @@# error HARDIRQ_BITS is too low!#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 */
include/asm-h8300/hardirq.h +0 -9
@@ -26,13 +26,4 @@# error HARDIRQ_BITS is too low!#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
include/asm-m32r/hardirq.h +0 -12
@@ -28,16 +28,4 @@# error HARDIRQ_BITS is too low!#endif -#define irq_enter () (preempt_count() += HARDIRQ_OFFSET) -#define nmi_enter () (irq_enter()) -#define nmi_exit () (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 */
include/asm-m68k/hardirq.h +0 -9
@@ -23,13 +23,4 @@# error HARDIRQ_BITS is too low!#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
include/asm-m68knommu/hardirq.h +0 -9
@@ -24,13 +24,4 @@# error HARDIRQ_BITS is too low!#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 */
include/asm-mips/hardirq.h +0 -9
@@ -31,13 +31,4 @@# error HARDIRQ_BITS is too low!#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 */
include/asm-parisc/hardirq.h +0 -9
@@ -38,13 +38,4 @@# error HARDIRQ_BITS is too low!#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 */
include/asm-s390/hardirq.h +1 -15
@@ -37,24 +37,10 @@ }#define __ARCH_IRQ_STAT +#define __ARCH_HAS_DO_SOFTIRQ#define HARDIRQ_BITS 8extern 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 */
include/asm-sh/hardirq.h +0 -12
@@ -23,16 +23,4 @@# error HARDIRQ_BITS is too low!#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 */
include/asm-sparc/hardirq.h +0 -9
@@ -21,13 +21,4 @@#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 */
include/asm-sparc64/hardirq.h +0 -9
@@ -20,13 +20,4 @@#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) */
include/asm-v850/hardirq.h +0 -9
@@ -24,13 +24,4 @@# error HARDIRQ_BITS is too low!#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__ */
===== include/linux/hardirq.h 1.5 vs edited =====
include/linux/hardirq.h +0 -2
@@ -77,12 +77,10 @@# define synchronize_irq (irq) barrier()#endif -#ifdef CONFIG_GENERIC_HARDIRQS #define nmi_enter () (preempt_count() += HARDIRQ_OFFSET)#define nmi_exit () (preempt_count() -= HARDIRQ_OFFSET)#define irq_enter () (preempt_count() += HARDIRQ_OFFSET)extern void irq_exit (void ); -#endif #endif /* LINUX_HARDIRQ_H */
===== kernel/softirq.c 1.60 vs edited =====
kernel/softirq.c +17 -0
@@ -152,6 +152,23 @@ }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! */
===== kernel/irq/handle.c 1.3 vs edited =====
kernel/irq/handle.c +0 -11
@@ -73,17 +73,6 @@ }/* -* 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: */ fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,