x86/entry: Clarify irq_{enter,exit}_rcu()
[linux-block.git] / include / linux / irqflags.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
de30a2b3
IM
2/*
3 * include/linux/irqflags.h
4 *
5 * IRQ flags tracing: follow the state of the hardirq and softirq flags and
6 * provide callbacks for transitions between ON and OFF states.
7 *
8 * This file gets included from lowlevel asm headers too, to provide
9 * wrapped versions of the local_irq_*() APIs, based on the
10 * raw_local_irq_*() macros from the lowlevel headers.
11 */
12#ifndef _LINUX_TRACE_IRQFLAGS_H
13#define _LINUX_TRACE_IRQFLAGS_H
14
3f307891 15#include <linux/typecheck.h>
df9ee292 16#include <asm/irqflags.h>
3f307891 17
0d38453c 18/* Currently lockdep_softirqs_on/off is used only by lockdep */
c3bc8fd6 19#ifdef CONFIG_PROVE_LOCKING
0d38453c
PZ
20 extern void lockdep_softirqs_on(unsigned long ip);
21 extern void lockdep_softirqs_off(unsigned long ip);
c86e9b98 22 extern void lockdep_hardirqs_on_prepare(unsigned long ip);
bff1b208
SRV
23 extern void lockdep_hardirqs_on(unsigned long ip);
24 extern void lockdep_hardirqs_off(unsigned long ip);
c3bc8fd6 25#else
0d38453c
PZ
26 static inline void lockdep_softirqs_on(unsigned long ip) { }
27 static inline void lockdep_softirqs_off(unsigned long ip) { }
c86e9b98 28 static inline void lockdep_hardirqs_on_prepare(unsigned long ip) { }
bff1b208
SRV
29 static inline void lockdep_hardirqs_on(unsigned long ip) { }
30 static inline void lockdep_hardirqs_off(unsigned long ip) { }
c3bc8fd6
JFG
31#endif
32
33#ifdef CONFIG_TRACE_IRQFLAGS
0995a5df
TG
34 extern void trace_hardirqs_on_prepare(void);
35 extern void trace_hardirqs_off_prepare(void);
81d68a96
SR
36 extern void trace_hardirqs_on(void);
37 extern void trace_hardirqs_off(void);
ef996916
PZ
38# define lockdep_hardirq_context(p) ((p)->hardirq_context)
39# define lockdep_softirq_context(p) ((p)->softirq_context)
40# define lockdep_hardirqs_enabled(p) ((p)->hardirqs_enabled)
41# define lockdep_softirqs_enabled(p) ((p)->softirqs_enabled)
2502ec37 42# define lockdep_hardirq_enter() \
b09be676 43do { \
de8f5e4f
PZ
44 if (!current->hardirq_context++) \
45 current->hardirq_threaded = 0; \
46} while (0)
d5f744f9 47# define lockdep_hardirq_threaded() \
de8f5e4f
PZ
48do { \
49 current->hardirq_threaded = 1; \
b09be676 50} while (0)
2502ec37 51# define lockdep_hardirq_exit() \
b09be676
BP
52do { \
53 current->hardirq_context--; \
b09be676
BP
54} while (0)
55# define lockdep_softirq_enter() \
56do { \
57 current->softirq_context++; \
b09be676
BP
58} while (0)
59# define lockdep_softirq_exit() \
60do { \
61 current->softirq_context--; \
b09be676 62} while (0)
40db1739
SAS
63
64# define lockdep_hrtimer_enter(__hrtimer) \
73d20564
SAS
65({ \
66 bool __expires_hardirq = true; \
67 \
68 if (!__hrtimer->is_hard) { \
69 current->irq_config = 1; \
70 __expires_hardirq = false; \
71 } \
72 __expires_hardirq; \
73})
40db1739 74
73d20564
SAS
75# define lockdep_hrtimer_exit(__expires_hardirq) \
76 do { \
77 if (!__expires_hardirq) \
40db1739 78 current->irq_config = 0; \
73d20564 79 } while (0)
40db1739 80
d53f2b62
SAS
81# define lockdep_posixtimer_enter() \
82 do { \
83 current->irq_config = 1; \
84 } while (0)
85
86# define lockdep_posixtimer_exit() \
87 do { \
88 current->irq_config = 0; \
89 } while (0)
90
49915ac3
SAS
91# define lockdep_irq_work_enter(__work) \
92 do { \
93 if (!(atomic_read(&__work->flags) & IRQ_WORK_HARD_IRQ))\
94 current->irq_config = 1; \
95 } while (0)
96# define lockdep_irq_work_exit(__work) \
97 do { \
98 if (!(atomic_read(&__work->flags) & IRQ_WORK_HARD_IRQ))\
99 current->irq_config = 0; \
100 } while (0)
101
de30a2b3 102#else
0995a5df
TG
103# define trace_hardirqs_on_prepare() do { } while (0)
104# define trace_hardirqs_off_prepare() do { } while (0)
de30a2b3
IM
105# define trace_hardirqs_on() do { } while (0)
106# define trace_hardirqs_off() do { } while (0)
ef996916
PZ
107# define lockdep_hardirq_context(p) 0
108# define lockdep_softirq_context(p) 0
109# define lockdep_hardirqs_enabled(p) 0
110# define lockdep_softirqs_enabled(p) 0
2502ec37 111# define lockdep_hardirq_enter() do { } while (0)
d5f744f9 112# define lockdep_hardirq_threaded() do { } while (0)
2502ec37 113# define lockdep_hardirq_exit() do { } while (0)
d820ac4c
IM
114# define lockdep_softirq_enter() do { } while (0)
115# define lockdep_softirq_exit() do { } while (0)
73d20564
SAS
116# define lockdep_hrtimer_enter(__hrtimer) false
117# define lockdep_hrtimer_exit(__context) do { } while (0)
d53f2b62
SAS
118# define lockdep_posixtimer_enter() do { } while (0)
119# define lockdep_posixtimer_exit() do { } while (0)
49915ac3
SAS
120# define lockdep_irq_work_enter(__work) do { } while (0)
121# define lockdep_irq_work_exit(__work) do { } while (0)
de30a2b3
IM
122#endif
123
6cd8a4bb
SR
124#if defined(CONFIG_IRQSOFF_TRACER) || \
125 defined(CONFIG_PREEMPT_TRACER)
81d68a96
SR
126 extern void stop_critical_timings(void);
127 extern void start_critical_timings(void);
128#else
129# define stop_critical_timings() do { } while (0)
130# define start_critical_timings() do { } while (0)
131#endif
132
df9ee292
DH
133/*
134 * Wrap the arch provided IRQ routines to provide appropriate checks.
135 */
136#define raw_local_irq_disable() arch_local_irq_disable()
137#define raw_local_irq_enable() arch_local_irq_enable()
138#define raw_local_irq_save(flags) \
139 do { \
140 typecheck(unsigned long, flags); \
141 flags = arch_local_irq_save(); \
142 } while (0)
143#define raw_local_irq_restore(flags) \
144 do { \
145 typecheck(unsigned long, flags); \
146 arch_local_irq_restore(flags); \
147 } while (0)
148#define raw_local_save_flags(flags) \
149 do { \
150 typecheck(unsigned long, flags); \
151 flags = arch_local_save_flags(); \
152 } while (0)
153#define raw_irqs_disabled_flags(flags) \
154 ({ \
155 typecheck(unsigned long, flags); \
156 arch_irqs_disabled_flags(flags); \
157 })
158#define raw_irqs_disabled() (arch_irqs_disabled())
159#define raw_safe_halt() arch_safe_halt()
de30a2b3 160
df9ee292
DH
161/*
162 * The local_irq_*() APIs are equal to the raw_local_irq*()
163 * if !TRACE_IRQFLAGS.
164 */
db2dcb4f 165#ifdef CONFIG_TRACE_IRQFLAGS
de30a2b3
IM
166#define local_irq_enable() \
167 do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)
168#define local_irq_disable() \
169 do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)
3f307891
SR
170#define local_irq_save(flags) \
171 do { \
3f307891
SR
172 raw_local_irq_save(flags); \
173 trace_hardirqs_off(); \
174 } while (0)
de30a2b3 175
3f307891
SR
176
177#define local_irq_restore(flags) \
178 do { \
3f307891
SR
179 if (raw_irqs_disabled_flags(flags)) { \
180 raw_local_irq_restore(flags); \
181 trace_hardirqs_off(); \
182 } else { \
183 trace_hardirqs_on(); \
184 raw_local_irq_restore(flags); \
185 } \
de30a2b3 186 } while (0)
df9ee292
DH
187
188#define safe_halt() \
189 do { \
190 trace_hardirqs_on(); \
191 raw_safe_halt(); \
3f307891 192 } while (0)
de30a2b3 193
de30a2b3 194
db2dcb4f 195#else /* !CONFIG_TRACE_IRQFLAGS */
df9ee292
DH
196
197#define local_irq_enable() do { raw_local_irq_enable(); } while (0)
198#define local_irq_disable() do { raw_local_irq_disable(); } while (0)
199#define local_irq_save(flags) \
200 do { \
201 raw_local_irq_save(flags); \
202 } while (0)
203#define local_irq_restore(flags) do { raw_local_irq_restore(flags); } while (0)
df9ee292
DH
204#define safe_halt() do { raw_safe_halt(); } while (0)
205
db2dcb4f
JB
206#endif /* CONFIG_TRACE_IRQFLAGS */
207
208#define local_save_flags(flags) raw_local_save_flags(flags)
209
210/*
211 * Some architectures don't define arch_irqs_disabled(), so even if either
212 * definition would be fine we need to use different ones for the time being
213 * to avoid build issues.
214 */
215#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
216#define irqs_disabled() \
217 ({ \
218 unsigned long _flags; \
219 raw_local_save_flags(_flags); \
220 raw_irqs_disabled_flags(_flags); \
221 })
222#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */
223#define irqs_disabled() raw_irqs_disabled()
40b1f4e5 224#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */
de30a2b3 225
db2dcb4f
JB
226#define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
227
de30a2b3 228#endif