1#ifndef __ASM_PREEMPT_H
2#define __ASM_PREEMPT_H
3
4#include <asm/rmwcc.h>
5#include <asm/percpu.h>
6#include <linux/thread_info.h>
7
8DECLARE_PER_CPU(int, __preempt_count);
9
10
11
12
13
14#define PREEMPT_ENABLED (0 + PREEMPT_NEED_RESCHED)
15
16
17
18
19
20static __always_inline int preempt_count(void)
21{
22 return raw_cpu_read_4(__preempt_count) & ~PREEMPT_NEED_RESCHED;
23}
24
25static __always_inline void preempt_count_set(int pc)
26{
27 raw_cpu_write_4(__preempt_count, pc);
28}
29
30
31
32
33#define init_task_preempt_count(p) do { } while (0)
34
35#define init_idle_preempt_count(p, cpu) do { \
36 per_cpu(__preempt_count, (cpu)) = PREEMPT_ENABLED; \
37} while (0)
38
39
40
41
42
43
44
45
46
47
48static __always_inline void set_preempt_need_resched(void)
49{
50 raw_cpu_and_4(__preempt_count, ~PREEMPT_NEED_RESCHED);
51}
52
53static __always_inline void clear_preempt_need_resched(void)
54{
55 raw_cpu_or_4(__preempt_count, PREEMPT_NEED_RESCHED);
56}
57
58static __always_inline bool test_preempt_need_resched(void)
59{
60 return !(raw_cpu_read_4(__preempt_count) & PREEMPT_NEED_RESCHED);
61}
62
63
64
65
66
67static __always_inline void __preempt_count_add(int val)
68{
69 raw_cpu_add_4(__preempt_count, val);
70}
71
72static __always_inline void __preempt_count_sub(int val)
73{
74 raw_cpu_add_4(__preempt_count, -val);
75}
76
77
78
79
80
81
82static __always_inline bool __preempt_count_dec_and_test(void)
83{
84 GEN_UNARY_RMWcc("decl", __preempt_count, __percpu_arg(0), e);
85}
86
87
88
89
90static __always_inline bool should_resched(int preempt_offset)
91{
92 return unlikely(raw_cpu_read_4(__preempt_count) == preempt_offset);
93}
94
95#ifdef CONFIG_PREEMPT
96 extern asmlinkage void ___preempt_schedule(void);
97# define __preempt_schedule() \
98({ \
99 register void *__sp asm(_ASM_SP); \
100 asm volatile ("call ___preempt_schedule" : "+r"(__sp)); \
101})
102
103 extern asmlinkage void preempt_schedule(void);
104 extern asmlinkage void ___preempt_schedule_notrace(void);
105# define __preempt_schedule_notrace() \
106({ \
107 register void *__sp asm(_ASM_SP); \
108 asm volatile ("call ___preempt_schedule_notrace" : "+r"(__sp)); \
109})
110 extern asmlinkage void preempt_schedule_notrace(void);
111#endif
112
113#endif
114