diff options
Diffstat (limited to 'include/asm-generic/preempt.h')
-rw-r--r-- | include/asm-generic/preempt.h | 35 |
1 files changed, 11 insertions, 24 deletions
diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h index ddf2b420ac8f..1cd3f5d767a8 100644 --- a/include/asm-generic/preempt.h +++ b/include/asm-generic/preempt.h | |||
@@ -3,13 +3,11 @@ | |||
3 | 3 | ||
4 | #include <linux/thread_info.h> | 4 | #include <linux/thread_info.h> |
5 | 5 | ||
6 | /* | 6 | #define PREEMPT_ENABLED (0) |
7 | * We mask the PREEMPT_NEED_RESCHED bit so as not to confuse all current users | 7 | |
8 | * that think a non-zero value indicates we cannot preempt. | ||
9 | */ | ||
10 | static __always_inline int preempt_count(void) | 8 | static __always_inline int preempt_count(void) |
11 | { | 9 | { |
12 | return current_thread_info()->preempt_count & ~PREEMPT_NEED_RESCHED; | 10 | return current_thread_info()->preempt_count; |
13 | } | 11 | } |
14 | 12 | ||
15 | static __always_inline int *preempt_count_ptr(void) | 13 | static __always_inline int *preempt_count_ptr(void) |
@@ -17,11 +15,6 @@ static __always_inline int *preempt_count_ptr(void) | |||
17 | return ¤t_thread_info()->preempt_count; | 15 | return ¤t_thread_info()->preempt_count; |
18 | } | 16 | } |
19 | 17 | ||
20 | /* | ||
21 | * We now loose PREEMPT_NEED_RESCHED and cause an extra reschedule; however the | ||
22 | * alternative is loosing a reschedule. Better schedule too often -- also this | ||
23 | * should be a very rare operation. | ||
24 | */ | ||
25 | static __always_inline void preempt_count_set(int pc) | 18 | static __always_inline void preempt_count_set(int pc) |
26 | { | 19 | { |
27 | *preempt_count_ptr() = pc; | 20 | *preempt_count_ptr() = pc; |
@@ -41,28 +34,17 @@ static __always_inline void preempt_count_set(int pc) | |||
41 | task_thread_info(p)->preempt_count = PREEMPT_ENABLED; \ | 34 | task_thread_info(p)->preempt_count = PREEMPT_ENABLED; \ |
42 | } while (0) | 35 | } while (0) |
43 | 36 | ||
44 | /* | ||
45 | * We fold the NEED_RESCHED bit into the preempt count such that | ||
46 | * preempt_enable() can decrement and test for needing to reschedule with a | ||
47 | * single instruction. | ||
48 | * | ||
49 | * We invert the actual bit, so that when the decrement hits 0 we know we both | ||
50 | * need to resched (the bit is cleared) and can resched (no preempt count). | ||
51 | */ | ||
52 | |||
53 | static __always_inline void set_preempt_need_resched(void) | 37 | static __always_inline void set_preempt_need_resched(void) |
54 | { | 38 | { |
55 | *preempt_count_ptr() &= ~PREEMPT_NEED_RESCHED; | ||
56 | } | 39 | } |
57 | 40 | ||
58 | static __always_inline void clear_preempt_need_resched(void) | 41 | static __always_inline void clear_preempt_need_resched(void) |
59 | { | 42 | { |
60 | *preempt_count_ptr() |= PREEMPT_NEED_RESCHED; | ||
61 | } | 43 | } |
62 | 44 | ||
63 | static __always_inline bool test_preempt_need_resched(void) | 45 | static __always_inline bool test_preempt_need_resched(void) |
64 | { | 46 | { |
65 | return !(*preempt_count_ptr() & PREEMPT_NEED_RESCHED); | 47 | return false; |
66 | } | 48 | } |
67 | 49 | ||
68 | /* | 50 | /* |
@@ -81,7 +63,12 @@ static __always_inline void __preempt_count_sub(int val) | |||
81 | 63 | ||
82 | static __always_inline bool __preempt_count_dec_and_test(void) | 64 | static __always_inline bool __preempt_count_dec_and_test(void) |
83 | { | 65 | { |
84 | return !--*preempt_count_ptr(); | 66 | /* |
67 | * Because of load-store architectures cannot do per-cpu atomic | ||
68 | * operations; we cannot use PREEMPT_NEED_RESCHED because it might get | ||
69 | * lost. | ||
70 | */ | ||
71 | return !--*preempt_count_ptr() && tif_need_resched(); | ||
85 | } | 72 | } |
86 | 73 | ||
87 | /* | 74 | /* |
@@ -89,7 +76,7 @@ static __always_inline bool __preempt_count_dec_and_test(void) | |||
89 | */ | 76 | */ |
90 | static __always_inline bool should_resched(void) | 77 | static __always_inline bool should_resched(void) |
91 | { | 78 | { |
92 | return unlikely(!*preempt_count_ptr()); | 79 | return unlikely(!preempt_count() && tif_need_resched()); |
93 | } | 80 | } |
94 | 81 | ||
95 | #ifdef CONFIG_PREEMPT | 82 | #ifdef CONFIG_PREEMPT |