diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2009-07-16 09:44:29 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-07-18 09:51:42 -0400 |
commit | e4aafea2d4bde8b44d6500c4ee7195bbfc51269e (patch) | |
tree | bf0c9df18b9f63bb10da0096d81ba80712a71665 | |
parent | e09758fae8ccde97e026c704319eaa18d488dc86 (diff) |
sched: Add a preempt count base offset to __might_sleep()
Add a preempt count base offset to compare against the current
preempt level count. It prepares to pull up the might_sleep
check from cond_resched() to cond_resched_lock() and
cond_resched_bh().
For these two helpers, we need to respectively ensure that once
we'll unlock the given spinlock / reenable local softirqs, we
will reach a sleepable state.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
[ Move and rename preempt_count_equals() ]
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1247725694-6082-4-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | include/linux/kernel.h | 6 | ||||
-rw-r--r-- | kernel/sched.c | 15 |
2 files changed, 14 insertions, 7 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b804f694ae6a..2b5b1e0899a8 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -125,7 +125,7 @@ extern int _cond_resched(void); | |||
125 | #endif | 125 | #endif |
126 | 126 | ||
127 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 127 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP |
128 | void __might_sleep(char *file, int line); | 128 | void __might_sleep(char *file, int line, int preempt_offset); |
129 | /** | 129 | /** |
130 | * might_sleep - annotation for functions that can sleep | 130 | * might_sleep - annotation for functions that can sleep |
131 | * | 131 | * |
@@ -137,9 +137,9 @@ extern int _cond_resched(void); | |||
137 | * supposed to. | 137 | * supposed to. |
138 | */ | 138 | */ |
139 | # define might_sleep() \ | 139 | # define might_sleep() \ |
140 | do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0) | 140 | do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) |
141 | #else | 141 | #else |
142 | static inline void __might_sleep(char *file, int line) { } | 142 | static inline void __might_sleep(char *file, int line, int preempt_offset) { } |
143 | # define might_sleep() do { might_resched(); } while (0) | 143 | # define might_sleep() do { might_resched(); } while (0) |
144 | #endif | 144 | #endif |
145 | 145 | ||
diff --git a/kernel/sched.c b/kernel/sched.c index 370a6c31c5e1..3ff4d004bd95 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -6610,7 +6610,7 @@ static inline int should_resched(void) | |||
6610 | 6610 | ||
6611 | static void __cond_resched(void) | 6611 | static void __cond_resched(void) |
6612 | { | 6612 | { |
6613 | __might_sleep(__FILE__, __LINE__); | 6613 | __might_sleep(__FILE__, __LINE__, 0); |
6614 | 6614 | ||
6615 | add_preempt_count(PREEMPT_ACTIVE); | 6615 | add_preempt_count(PREEMPT_ACTIVE); |
6616 | schedule(); | 6616 | schedule(); |
@@ -9429,13 +9429,20 @@ void __init sched_init(void) | |||
9429 | } | 9429 | } |
9430 | 9430 | ||
9431 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 9431 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP |
9432 | void __might_sleep(char *file, int line) | 9432 | static inline int preempt_count_equals(int preempt_offset) |
9433 | { | ||
9434 | int nested = preempt_count() & ~PREEMPT_ACTIVE; | ||
9435 | |||
9436 | return (nested == PREEMPT_INATOMIC_BASE + preempt_offset); | ||
9437 | } | ||
9438 | |||
9439 | void __might_sleep(char *file, int line, int preempt_offset) | ||
9433 | { | 9440 | { |
9434 | #ifdef in_atomic | 9441 | #ifdef in_atomic |
9435 | static unsigned long prev_jiffy; /* ratelimiting */ | 9442 | static unsigned long prev_jiffy; /* ratelimiting */ |
9436 | 9443 | ||
9437 | if ((!in_atomic() && !irqs_disabled()) || | 9444 | if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || |
9438 | system_state != SYSTEM_RUNNING || oops_in_progress) | 9445 | system_state != SYSTEM_RUNNING || oops_in_progress) |
9439 | return; | 9446 | return; |
9440 | if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) | 9447 | if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) |
9441 | return; | 9448 | return; |