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 /kernel/sched.c | |
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>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 15 |
1 files changed, 11 insertions, 4 deletions
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; |