blob: 810d7e386f20205d25fae601b3e0436dd3288dfd [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 *
20 * PREEMPT_MASK: 0x000000ff
21 * SOFTIRQ_MASK: 0x0000ff00
Thomas Gleixner54197e42013-09-17 18:53:05 +000022 * HARDIRQ_MASK: 0x000f0000
23 * NMI_MASK: 0x00100000
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
49#ifndef PREEMPT_ACTIVE
50#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)
53#endif
54
55#if PREEMPT_ACTIVE < (1 << (NMI_SHIFT + NMI_BITS))
56#error PREEMPT_ACTIVE is too low!
57#endif
58
59#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
60#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
61#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \
62 | NMI_MASK))
63
64/*
65 * Are we doing bottom half or hardware interrupt processing?
66 * Are we in a softirq context? Interrupt context?
67 * in_softirq - Are we currently processing softirq or have bh disabled?
68 * in_serving_softirq - Are we currently processing softirq?
69 */
70#define in_irq() (hardirq_count())
71#define in_softirq() (softirq_count())
72#define in_interrupt() (irq_count())
73#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET)
74
75/*
76 * Are we in NMI context?
77 */
78#define in_nmi() (preempt_count() & NMI_MASK)
79
80#if defined(CONFIG_PREEMPT_COUNT)
81# define PREEMPT_CHECK_OFFSET 1
82#else
83# define PREEMPT_CHECK_OFFSET 0
84#endif
85
86/*
87 * Are we running in atomic context? WARNING: this macro cannot
88 * always detect atomic context; in particular, it cannot know about
89 * held spinlocks in non-preemptible kernels. Thus it should not be
90 * used in the general case to determine whether sleeping is possible.
91 * Do not use in_atomic() in driver code.
92 */
93#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
94
95/*
96 * Check whether we were atomic before we did preempt_disable():
97 * (used by the scheduler, *after* releasing the kernel lock)
98 */
99#define in_atomic_preempt_off() \
100 ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
101
102#ifdef CONFIG_PREEMPT_COUNT
103# define preemptible() (preempt_count() == 0 && !irqs_disabled())
104#else
105# define preemptible() 0
106#endif
107
108#endif /* LINUX_PREEMPT_MASK_H */