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