diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/hardirq.h | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index f83288347dda..f3cf86e1465b 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -61,6 +61,12 @@ | |||
61 | #error PREEMPT_ACTIVE is too low! | 61 | #error PREEMPT_ACTIVE is too low! |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | #define NMI_OFFSET (PREEMPT_ACTIVE << 1) | ||
65 | |||
66 | #if NMI_OFFSET >= 0x80000000 | ||
67 | #error PREEMPT_ACTIVE too high! | ||
68 | #endif | ||
69 | |||
64 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) | 70 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) |
65 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) | 71 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) |
66 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) | 72 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) |
@@ -73,6 +79,11 @@ | |||
73 | #define in_softirq() (softirq_count()) | 79 | #define in_softirq() (softirq_count()) |
74 | #define in_interrupt() (irq_count()) | 80 | #define in_interrupt() (irq_count()) |
75 | 81 | ||
82 | /* | ||
83 | * Are we in NMI context? | ||
84 | */ | ||
85 | #define in_nmi() (preempt_count() & NMI_OFFSET) | ||
86 | |||
76 | #if defined(CONFIG_PREEMPT) | 87 | #if defined(CONFIG_PREEMPT) |
77 | # define PREEMPT_INATOMIC_BASE kernel_locked() | 88 | # define PREEMPT_INATOMIC_BASE kernel_locked() |
78 | # define PREEMPT_CHECK_OFFSET 1 | 89 | # define PREEMPT_CHECK_OFFSET 1 |
@@ -167,6 +178,8 @@ extern void irq_exit(void); | |||
167 | #define nmi_enter() \ | 178 | #define nmi_enter() \ |
168 | do { \ | 179 | do { \ |
169 | ftrace_nmi_enter(); \ | 180 | ftrace_nmi_enter(); \ |
181 | BUG_ON(in_nmi()); \ | ||
182 | add_preempt_count(NMI_OFFSET); \ | ||
170 | lockdep_off(); \ | 183 | lockdep_off(); \ |
171 | rcu_nmi_enter(); \ | 184 | rcu_nmi_enter(); \ |
172 | __irq_enter(); \ | 185 | __irq_enter(); \ |
@@ -177,6 +190,8 @@ extern void irq_exit(void); | |||
177 | __irq_exit(); \ | 190 | __irq_exit(); \ |
178 | rcu_nmi_exit(); \ | 191 | rcu_nmi_exit(); \ |
179 | lockdep_on(); \ | 192 | lockdep_on(); \ |
193 | BUG_ON(!in_nmi()); \ | ||
194 | sub_preempt_count(NMI_OFFSET); \ | ||
180 | ftrace_nmi_exit(); \ | 195 | ftrace_nmi_exit(); \ |
181 | } while (0) | 196 | } while (0) |
182 | 197 | ||