diff options
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; |