diff options
Diffstat (limited to 'include/linux/hardirq.h')
-rw-r--r-- | include/linux/hardirq.h | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 181006cc94a0..f83288347dda 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -4,6 +4,7 @@ | |||
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 <linux/lockdep.h> |
7 | #include <linux/ftrace_irq.h> | ||
7 | #include <asm/hardirq.h> | 8 | #include <asm/hardirq.h> |
8 | #include <asm/system.h> | 9 | #include <asm/system.h> |
9 | 10 | ||
@@ -118,13 +119,17 @@ static inline void account_system_vtime(struct task_struct *tsk) | |||
118 | } | 119 | } |
119 | #endif | 120 | #endif |
120 | 121 | ||
121 | #if defined(CONFIG_PREEMPT_RCU) && defined(CONFIG_NO_HZ) | 122 | #if defined(CONFIG_NO_HZ) && !defined(CONFIG_CLASSIC_RCU) |
122 | extern void rcu_irq_enter(void); | 123 | extern void rcu_irq_enter(void); |
123 | extern void rcu_irq_exit(void); | 124 | extern void rcu_irq_exit(void); |
125 | extern void rcu_nmi_enter(void); | ||
126 | extern void rcu_nmi_exit(void); | ||
124 | #else | 127 | #else |
125 | # define rcu_irq_enter() do { } while (0) | 128 | # define rcu_irq_enter() do { } while (0) |
126 | # define rcu_irq_exit() do { } while (0) | 129 | # define rcu_irq_exit() do { } while (0) |
127 | #endif /* CONFIG_PREEMPT_RCU */ | 130 | # define rcu_nmi_enter() do { } while (0) |
131 | # define rcu_nmi_exit() do { } while (0) | ||
132 | #endif /* #if defined(CONFIG_NO_HZ) && !defined(CONFIG_CLASSIC_RCU) */ | ||
128 | 133 | ||
129 | /* | 134 | /* |
130 | * It is safe to do non-atomic ops on ->hardirq_context, | 135 | * It is safe to do non-atomic ops on ->hardirq_context, |
@@ -134,7 +139,6 @@ extern void rcu_irq_exit(void); | |||
134 | */ | 139 | */ |
135 | #define __irq_enter() \ | 140 | #define __irq_enter() \ |
136 | do { \ | 141 | do { \ |
137 | rcu_irq_enter(); \ | ||
138 | account_system_vtime(current); \ | 142 | account_system_vtime(current); \ |
139 | add_preempt_count(HARDIRQ_OFFSET); \ | 143 | add_preempt_count(HARDIRQ_OFFSET); \ |
140 | trace_hardirq_enter(); \ | 144 | trace_hardirq_enter(); \ |
@@ -153,7 +157,6 @@ extern void irq_enter(void); | |||
153 | trace_hardirq_exit(); \ | 157 | trace_hardirq_exit(); \ |
154 | account_system_vtime(current); \ | 158 | account_system_vtime(current); \ |
155 | sub_preempt_count(HARDIRQ_OFFSET); \ | 159 | sub_preempt_count(HARDIRQ_OFFSET); \ |
156 | rcu_irq_exit(); \ | ||
157 | } while (0) | 160 | } while (0) |
158 | 161 | ||
159 | /* | 162 | /* |
@@ -161,7 +164,20 @@ extern void irq_enter(void); | |||
161 | */ | 164 | */ |
162 | extern void irq_exit(void); | 165 | extern void irq_exit(void); |
163 | 166 | ||
164 | #define nmi_enter() do { lockdep_off(); __irq_enter(); } while (0) | 167 | #define nmi_enter() \ |
165 | #define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) | 168 | do { \ |
169 | ftrace_nmi_enter(); \ | ||
170 | lockdep_off(); \ | ||
171 | rcu_nmi_enter(); \ | ||
172 | __irq_enter(); \ | ||
173 | } while (0) | ||
174 | |||
175 | #define nmi_exit() \ | ||
176 | do { \ | ||
177 | __irq_exit(); \ | ||
178 | rcu_nmi_exit(); \ | ||
179 | lockdep_on(); \ | ||
180 | ftrace_nmi_exit(); \ | ||
181 | } while (0) | ||
166 | 182 | ||
167 | #endif /* LINUX_HARDIRQ_H */ | 183 | #endif /* LINUX_HARDIRQ_H */ |