blob: dbeec4d4a3beafb0d6123944f108981879c3137e [file] [log] [blame]
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +02001#ifndef LINUX_PREEMPT_MASK_H
2#define LINUX_PREEMPT_MASK_H
3
4#include <linux/preempt.h>
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +02005
6/*
7 * We put the hardirq and softirq counter into the preemption
8 * counter. The bitmask has the following meaning:
9 *
10 * - bits 0-7 are the preemption count (max preemption depth: 256)
11 * - bits 8-15 are the softirq count (max # of softirqs: 256)
12 *
Thomas Gleixner54197e42013-09-17 18:53:05 +000013 * The hardirq count could in theory be the same as the number of
14 * interrupts in the system, but we run all interrupt handlers with
15 * interrupts disabled, so we cannot have nesting interrupts. Though
16 * there are a few palaeontologic drivers which reenable interrupts in
17 * the handler, so we need more than one bit here.
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +020018 *
Thomas Gleixner00d1a392013-09-17 18:53:09 +000019 * PREEMPT_MASK: 0x000000ff
20 * SOFTIRQ_MASK: 0x0000ff00
21 * HARDIRQ_MASK: 0x000f0000
22 * NMI_MASK: 0x00100000
23 * PREEMPT_ACTIVE: 0x00200000
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +020024 */
25#define PREEMPT_BITS 8
26#define SOFTIRQ_BITS 8
Thomas Gleixner54197e42013-09-17 18:53:05 +000027#define HARDIRQ_BITS 4
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +020028#define NMI_BITS 1
29
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +020030#define PREEMPT_SHIFT 0
31#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS)
32#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
33#define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS)
34
35#define __IRQ_MASK(x) ((1UL << (x))-1)
36
37#define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
38#define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
39#define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
40#define NMI_MASK (__IRQ_MASK(NMI_BITS) << NMI_SHIFT)
41
42#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
43#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
44#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
45#define NMI_OFFSET (1UL << NMI_SHIFT)
46
47#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET)
48
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +020049#define PREEMPT_ACTIVE_BITS 1
50#define PREEMPT_ACTIVE_SHIFT (NMI_SHIFT + NMI_BITS)
51#define PREEMPT_ACTIVE (__IRQ_MASK(PREEMPT_ACTIVE_BITS) << PREEMPT_ACTIVE_SHIFT)
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +020052
53#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
54#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
55#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \
56 | NMI_MASK))
57
58/*
59 * Are we doing bottom half or hardware interrupt processing?
60 * Are we in a softirq context? Interrupt context?
61 * in_softirq - Are we currently processing softirq or have bh disabled?
62 * in_serving_softirq - Are we currently processing softirq?
63 */
64#define in_irq() (hardirq_count())
65#define in_softirq() (softirq_count())
66#define in_interrupt() (irq_count())
67#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET)
68
69/*
70 * Are we in NMI context?
71 */
72#define in_nmi() (preempt_count() & NMI_MASK)
73
74#if defined(CONFIG_PREEMPT_COUNT)
75# define PREEMPT_CHECK_OFFSET 1
76#else
77# define PREEMPT_CHECK_OFFSET 0
78#endif
79
80/*
Peter Zijlstra9ea4c382013-11-19 16:13:38 +010081 * The preempt_count offset needed for things like:
82 *
83 * spin_lock_bh()
84 *
85 * Which need to disable both preemption (CONFIG_PREEMPT_COUNT) and
86 * softirqs, such that unlock sequences of:
87 *
88 * spin_unlock();
89 * local_bh_enable();
90 *
91 * Work as expected.
92 */
93#define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_CHECK_OFFSET)
94
95/*
Frederic Weisbecker2d4b8472013-07-29 20:29:43 +020096 * Are we running in atomic context? WARNING: this macro cannot
97 * always detect atomic context; in particular, it cannot know about
98 * held spinlocks in non-preemptible kernels. Thus it should not be
99 * used in the general case to determine whether sleeping is possible.
100 * Do not use in_atomic() in driver code.
101 */
102#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
103
104/*
105 * Check whether we were atomic before we did preempt_disable():
106 * (used by the scheduler, *after* releasing the kernel lock)
107 */
108#define in_atomic_preempt_off() \
109 ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
110
111#ifdef CONFIG_PREEMPT_COUNT
112# define preemptible() (preempt_count() == 0 && !irqs_disabled())
113#else
114# define preemptible() 0
115#endif
116
117#endif /* LINUX_PREEMPT_MASK_H */