1 #ifndef LINUX_HARDIRQ_H 2 #define LINUX_HARDIRQ_H 3 4 #include <linux/preempt_mask.h> 5 #include <linux/lockdep.h> 6 #include <linux/ftrace_irq.h> 7 #include <linux/vtime.h> 8 9 10 #if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS) 11 extern void synchronize_irq(unsigned int irq); 12 #else 13 # define synchronize_irq(irq) barrier() 14 #endif 15 16 #if defined(CONFIG_TINY_RCU) 17 18 static inline void rcu_nmi_enter(void) 19 { 20 } 21 22 static inline void rcu_nmi_exit(void) 23 { 24 } 25 26 #else 27 extern void rcu_nmi_enter(void); 28 extern void rcu_nmi_exit(void); 29 #endif 30 31 /* 32 * It is safe to do non-atomic ops on ->hardirq_context, 33 * because NMI handlers may not preempt and the ops are 34 * always balanced, so the interrupted value of ->hardirq_context 35 * will always be restored. 36 */ 37 #define __irq_enter() \ 38 do { \ 39 account_irq_enter_time(current); \ 40 add_preempt_count(HARDIRQ_OFFSET); \ 41 trace_hardirq_enter(); \ 42 } while (0) 43 44 /* 45 * Enter irq context (on NO_HZ, update jiffies): 46 */ 47 extern void irq_enter(void); 48 49 /* 50 * Exit irq context without processing softirqs: 51 */ 52 #define __irq_exit() \ 53 do { \ 54 trace_hardirq_exit(); \ 55 account_irq_exit_time(current); \ 56 sub_preempt_count(HARDIRQ_OFFSET); \ 57 } while (0) 58 59 /* 60 * Exit irq context and process softirqs if needed: 61 */ 62 extern void irq_exit(void); 63 64 #define nmi_enter() \ 65 do { \ 66 lockdep_off(); \ 67 ftrace_nmi_enter(); \ 68 BUG_ON(in_nmi()); \ 69 add_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \ 70 rcu_nmi_enter(); \ 71 trace_hardirq_enter(); \ 72 } while (0) 73 74 #define nmi_exit() \ 75 do { \ 76 trace_hardirq_exit(); \ 77 rcu_nmi_exit(); \ 78 BUG_ON(!in_nmi()); \ 79 sub_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \ 80 ftrace_nmi_exit(); \ 81 lockdep_on(); \ 82 } while (0) 83 84 #endif /* LINUX_HARDIRQ_H */ 85