diff options
Diffstat (limited to 'include/linux/hardirq.h')
| -rw-r--r-- | include/linux/hardirq.h | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 114ae583cca9..50d8b5744cf6 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/preempt.h> | 4 | #include <linux/preempt.h> |
| 5 | #include <linux/smp_lock.h> | 5 | #include <linux/smp_lock.h> |
| 6 | #include <linux/lockdep.h> | ||
| 6 | #include <asm/hardirq.h> | 7 | #include <asm/hardirq.h> |
| 7 | #include <asm/system.h> | 8 | #include <asm/system.h> |
| 8 | 9 | ||
| @@ -86,9 +87,6 @@ extern void synchronize_irq(unsigned int irq); | |||
| 86 | # define synchronize_irq(irq) barrier() | 87 | # define synchronize_irq(irq) barrier() |
| 87 | #endif | 88 | #endif |
| 88 | 89 | ||
| 89 | #define nmi_enter() irq_enter() | ||
| 90 | #define nmi_exit() sub_preempt_count(HARDIRQ_OFFSET) | ||
| 91 | |||
| 92 | struct task_struct; | 90 | struct task_struct; |
| 93 | 91 | ||
| 94 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 92 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING |
| @@ -97,12 +95,35 @@ static inline void account_system_vtime(struct task_struct *tsk) | |||
| 97 | } | 95 | } |
| 98 | #endif | 96 | #endif |
| 99 | 97 | ||
| 98 | /* | ||
| 99 | * It is safe to do non-atomic ops on ->hardirq_context, | ||
| 100 | * because NMI handlers may not preempt and the ops are | ||
| 101 | * always balanced, so the interrupted value of ->hardirq_context | ||
| 102 | * will always be restored. | ||
| 103 | */ | ||
| 100 | #define irq_enter() \ | 104 | #define irq_enter() \ |
| 101 | do { \ | 105 | do { \ |
| 102 | account_system_vtime(current); \ | 106 | account_system_vtime(current); \ |
| 103 | add_preempt_count(HARDIRQ_OFFSET); \ | 107 | add_preempt_count(HARDIRQ_OFFSET); \ |
| 108 | trace_hardirq_enter(); \ | ||
| 109 | } while (0) | ||
| 110 | |||
| 111 | /* | ||
| 112 | * Exit irq context without processing softirqs: | ||
| 113 | */ | ||
| 114 | #define __irq_exit() \ | ||
| 115 | do { \ | ||
| 116 | trace_hardirq_exit(); \ | ||
| 117 | account_system_vtime(current); \ | ||
| 118 | sub_preempt_count(HARDIRQ_OFFSET); \ | ||
| 104 | } while (0) | 119 | } while (0) |
| 105 | 120 | ||
| 121 | /* | ||
| 122 | * Exit irq context and process softirqs if needed: | ||
| 123 | */ | ||
| 106 | extern void irq_exit(void); | 124 | extern void irq_exit(void); |
| 107 | 125 | ||
| 126 | #define nmi_enter() do { lockdep_off(); irq_enter(); } while (0) | ||
| 127 | #define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) | ||
| 128 | |||
| 108 | #endif /* LINUX_HARDIRQ_H */ | 129 | #endif /* LINUX_HARDIRQ_H */ |
