0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef _LINUX_TRACE_IRQFLAGS_H
0013 #define _LINUX_TRACE_IRQFLAGS_H
0014
0015 #include <linux/typecheck.h>
0016 #include <asm/irqflags.h>
0017 #include <asm/percpu.h>
0018
0019
0020 #ifdef CONFIG_PROVE_LOCKING
0021 extern void lockdep_softirqs_on(unsigned long ip);
0022 extern void lockdep_softirqs_off(unsigned long ip);
0023 extern void lockdep_hardirqs_on_prepare(void);
0024 extern void lockdep_hardirqs_on(unsigned long ip);
0025 extern void lockdep_hardirqs_off(unsigned long ip);
0026 #else
0027 static inline void lockdep_softirqs_on(unsigned long ip) { }
0028 static inline void lockdep_softirqs_off(unsigned long ip) { }
0029 static inline void lockdep_hardirqs_on_prepare(void) { }
0030 static inline void lockdep_hardirqs_on(unsigned long ip) { }
0031 static inline void lockdep_hardirqs_off(unsigned long ip) { }
0032 #endif
0033
0034 #ifdef CONFIG_TRACE_IRQFLAGS
0035
0036
0037 struct irqtrace_events {
0038 unsigned int irq_events;
0039 unsigned long hardirq_enable_ip;
0040 unsigned long hardirq_disable_ip;
0041 unsigned int hardirq_enable_event;
0042 unsigned int hardirq_disable_event;
0043 unsigned long softirq_disable_ip;
0044 unsigned long softirq_enable_ip;
0045 unsigned int softirq_disable_event;
0046 unsigned int softirq_enable_event;
0047 };
0048
0049 DECLARE_PER_CPU(int, hardirqs_enabled);
0050 DECLARE_PER_CPU(int, hardirq_context);
0051
0052 extern void trace_hardirqs_on_prepare(void);
0053 extern void trace_hardirqs_off_finish(void);
0054 extern void trace_hardirqs_on(void);
0055 extern void trace_hardirqs_off(void);
0056
0057 # define lockdep_hardirq_context() (raw_cpu_read(hardirq_context))
0058 # define lockdep_softirq_context(p) ((p)->softirq_context)
0059 # define lockdep_hardirqs_enabled() (this_cpu_read(hardirqs_enabled))
0060 # define lockdep_softirqs_enabled(p) ((p)->softirqs_enabled)
0061 # define lockdep_hardirq_enter() \
0062 do { \
0063 if (__this_cpu_inc_return(hardirq_context) == 1)\
0064 current->hardirq_threaded = 0; \
0065 } while (0)
0066 # define lockdep_hardirq_threaded() \
0067 do { \
0068 current->hardirq_threaded = 1; \
0069 } while (0)
0070 # define lockdep_hardirq_exit() \
0071 do { \
0072 __this_cpu_dec(hardirq_context); \
0073 } while (0)
0074
0075 # define lockdep_hrtimer_enter(__hrtimer) \
0076 ({ \
0077 bool __expires_hardirq = true; \
0078 \
0079 if (!__hrtimer->is_hard) { \
0080 current->irq_config = 1; \
0081 __expires_hardirq = false; \
0082 } \
0083 __expires_hardirq; \
0084 })
0085
0086 # define lockdep_hrtimer_exit(__expires_hardirq) \
0087 do { \
0088 if (!__expires_hardirq) \
0089 current->irq_config = 0; \
0090 } while (0)
0091
0092 # define lockdep_posixtimer_enter() \
0093 do { \
0094 current->irq_config = 1; \
0095 } while (0)
0096
0097 # define lockdep_posixtimer_exit() \
0098 do { \
0099 current->irq_config = 0; \
0100 } while (0)
0101
0102 # define lockdep_irq_work_enter(_flags) \
0103 do { \
0104 if (!((_flags) & IRQ_WORK_HARD_IRQ)) \
0105 current->irq_config = 1; \
0106 } while (0)
0107 # define lockdep_irq_work_exit(_flags) \
0108 do { \
0109 if (!((_flags) & IRQ_WORK_HARD_IRQ)) \
0110 current->irq_config = 0; \
0111 } while (0)
0112
0113 #else
0114 # define trace_hardirqs_on_prepare() do { } while (0)
0115 # define trace_hardirqs_off_finish() do { } while (0)
0116 # define trace_hardirqs_on() do { } while (0)
0117 # define trace_hardirqs_off() do { } while (0)
0118 # define lockdep_hardirq_context() 0
0119 # define lockdep_softirq_context(p) 0
0120 # define lockdep_hardirqs_enabled() 0
0121 # define lockdep_softirqs_enabled(p) 0
0122 # define lockdep_hardirq_enter() do { } while (0)
0123 # define lockdep_hardirq_threaded() do { } while (0)
0124 # define lockdep_hardirq_exit() do { } while (0)
0125 # define lockdep_softirq_enter() do { } while (0)
0126 # define lockdep_softirq_exit() do { } while (0)
0127 # define lockdep_hrtimer_enter(__hrtimer) false
0128 # define lockdep_hrtimer_exit(__context) do { } while (0)
0129 # define lockdep_posixtimer_enter() do { } while (0)
0130 # define lockdep_posixtimer_exit() do { } while (0)
0131 # define lockdep_irq_work_enter(__work) do { } while (0)
0132 # define lockdep_irq_work_exit(__work) do { } while (0)
0133 #endif
0134
0135 #if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_PREEMPT_RT)
0136 # define lockdep_softirq_enter() \
0137 do { \
0138 current->softirq_context++; \
0139 } while (0)
0140 # define lockdep_softirq_exit() \
0141 do { \
0142 current->softirq_context--; \
0143 } while (0)
0144
0145 #else
0146 # define lockdep_softirq_enter() do { } while (0)
0147 # define lockdep_softirq_exit() do { } while (0)
0148 #endif
0149
0150 #if defined(CONFIG_IRQSOFF_TRACER) || \
0151 defined(CONFIG_PREEMPT_TRACER)
0152 extern void stop_critical_timings(void);
0153 extern void start_critical_timings(void);
0154 #else
0155 # define stop_critical_timings() do { } while (0)
0156 # define start_critical_timings() do { } while (0)
0157 #endif
0158
0159 #ifdef CONFIG_DEBUG_IRQFLAGS
0160 extern void warn_bogus_irq_restore(void);
0161 #define raw_check_bogus_irq_restore() \
0162 do { \
0163 if (unlikely(!arch_irqs_disabled())) \
0164 warn_bogus_irq_restore(); \
0165 } while (0)
0166 #else
0167 #define raw_check_bogus_irq_restore() do { } while (0)
0168 #endif
0169
0170
0171
0172
0173 #define raw_local_irq_disable() arch_local_irq_disable()
0174 #define raw_local_irq_enable() arch_local_irq_enable()
0175 #define raw_local_irq_save(flags) \
0176 do { \
0177 typecheck(unsigned long, flags); \
0178 flags = arch_local_irq_save(); \
0179 } while (0)
0180 #define raw_local_irq_restore(flags) \
0181 do { \
0182 typecheck(unsigned long, flags); \
0183 raw_check_bogus_irq_restore(); \
0184 arch_local_irq_restore(flags); \
0185 } while (0)
0186 #define raw_local_save_flags(flags) \
0187 do { \
0188 typecheck(unsigned long, flags); \
0189 flags = arch_local_save_flags(); \
0190 } while (0)
0191 #define raw_irqs_disabled_flags(flags) \
0192 ({ \
0193 typecheck(unsigned long, flags); \
0194 arch_irqs_disabled_flags(flags); \
0195 })
0196 #define raw_irqs_disabled() (arch_irqs_disabled())
0197 #define raw_safe_halt() arch_safe_halt()
0198
0199
0200
0201
0202
0203 #ifdef CONFIG_TRACE_IRQFLAGS
0204
0205 #define local_irq_enable() \
0206 do { \
0207 trace_hardirqs_on(); \
0208 raw_local_irq_enable(); \
0209 } while (0)
0210
0211 #define local_irq_disable() \
0212 do { \
0213 bool was_disabled = raw_irqs_disabled();\
0214 raw_local_irq_disable(); \
0215 if (!was_disabled) \
0216 trace_hardirqs_off(); \
0217 } while (0)
0218
0219 #define local_irq_save(flags) \
0220 do { \
0221 raw_local_irq_save(flags); \
0222 if (!raw_irqs_disabled_flags(flags)) \
0223 trace_hardirqs_off(); \
0224 } while (0)
0225
0226 #define local_irq_restore(flags) \
0227 do { \
0228 if (!raw_irqs_disabled_flags(flags)) \
0229 trace_hardirqs_on(); \
0230 raw_local_irq_restore(flags); \
0231 } while (0)
0232
0233 #define safe_halt() \
0234 do { \
0235 trace_hardirqs_on(); \
0236 raw_safe_halt(); \
0237 } while (0)
0238
0239
0240 #else
0241
0242 #define local_irq_enable() do { raw_local_irq_enable(); } while (0)
0243 #define local_irq_disable() do { raw_local_irq_disable(); } while (0)
0244 #define local_irq_save(flags) do { raw_local_irq_save(flags); } while (0)
0245 #define local_irq_restore(flags) do { raw_local_irq_restore(flags); } while (0)
0246 #define safe_halt() do { raw_safe_halt(); } while (0)
0247
0248 #endif
0249
0250 #define local_save_flags(flags) raw_local_save_flags(flags)
0251
0252
0253
0254
0255
0256
0257 #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
0258 #define irqs_disabled() \
0259 ({ \
0260 unsigned long _flags; \
0261 raw_local_save_flags(_flags); \
0262 raw_irqs_disabled_flags(_flags); \
0263 })
0264 #else
0265 #define irqs_disabled() raw_irqs_disabled()
0266 #endif
0267
0268 #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
0269
0270 #endif