diff options
-rw-r--r-- | include/linux/sched.h | 5 | ||||
-rw-r--r-- | kernel/sched.c | 14 |
2 files changed, 13 insertions, 6 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 2a99f1c15cf8..16a982e389fb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -501,8 +501,11 @@ struct task_cputime { | |||
501 | /* | 501 | /* |
502 | * Disable preemption until the scheduler is running. | 502 | * Disable preemption until the scheduler is running. |
503 | * Reset by start_kernel()->sched_init()->init_idle(). | 503 | * Reset by start_kernel()->sched_init()->init_idle(). |
504 | * | ||
505 | * We include PREEMPT_ACTIVE to avoid cond_resched() from working | ||
506 | * before the scheduler is active -- see should_resched(). | ||
504 | */ | 507 | */ |
505 | #define INIT_PREEMPT_COUNT (1) | 508 | #define INIT_PREEMPT_COUNT (1 + PREEMPT_ACTIVE) |
506 | 509 | ||
507 | /** | 510 | /** |
508 | * struct thread_group_cputimer - thread group interval timer counts | 511 | * struct thread_group_cputimer - thread group interval timer counts |
diff --git a/kernel/sched.c b/kernel/sched.c index 7c9098d186e6..01f55ada3598 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -6541,6 +6541,11 @@ SYSCALL_DEFINE0(sched_yield) | |||
6541 | return 0; | 6541 | return 0; |
6542 | } | 6542 | } |
6543 | 6543 | ||
6544 | static inline int should_resched(void) | ||
6545 | { | ||
6546 | return need_resched() && !(preempt_count() & PREEMPT_ACTIVE); | ||
6547 | } | ||
6548 | |||
6544 | static void __cond_resched(void) | 6549 | static void __cond_resched(void) |
6545 | { | 6550 | { |
6546 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 6551 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP |
@@ -6560,8 +6565,7 @@ static void __cond_resched(void) | |||
6560 | 6565 | ||
6561 | int __sched _cond_resched(void) | 6566 | int __sched _cond_resched(void) |
6562 | { | 6567 | { |
6563 | if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) && | 6568 | if (should_resched()) { |
6564 | system_state == SYSTEM_RUNNING) { | ||
6565 | __cond_resched(); | 6569 | __cond_resched(); |
6566 | return 1; | 6570 | return 1; |
6567 | } | 6571 | } |
@@ -6579,12 +6583,12 @@ EXPORT_SYMBOL(_cond_resched); | |||
6579 | */ | 6583 | */ |
6580 | int cond_resched_lock(spinlock_t *lock) | 6584 | int cond_resched_lock(spinlock_t *lock) |
6581 | { | 6585 | { |
6582 | int resched = need_resched() && system_state == SYSTEM_RUNNING; | 6586 | int resched = should_resched(); |
6583 | int ret = 0; | 6587 | int ret = 0; |
6584 | 6588 | ||
6585 | if (spin_needbreak(lock) || resched) { | 6589 | if (spin_needbreak(lock) || resched) { |
6586 | spin_unlock(lock); | 6590 | spin_unlock(lock); |
6587 | if (resched && need_resched()) | 6591 | if (resched) |
6588 | __cond_resched(); | 6592 | __cond_resched(); |
6589 | else | 6593 | else |
6590 | cpu_relax(); | 6594 | cpu_relax(); |
@@ -6599,7 +6603,7 @@ int __sched cond_resched_softirq(void) | |||
6599 | { | 6603 | { |
6600 | BUG_ON(!in_softirq()); | 6604 | BUG_ON(!in_softirq()); |
6601 | 6605 | ||
6602 | if (need_resched() && system_state == SYSTEM_RUNNING) { | 6606 | if (should_resched()) { |
6603 | local_bh_enable(); | 6607 | local_bh_enable(); |
6604 | __cond_resched(); | 6608 | __cond_resched(); |
6605 | local_bh_disable(); | 6609 | local_bh_disable(); |