diff --git a/[refs] b/[refs] index d340e7334b3f..e9bf83182633 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 92fe15a3d24fa53e7e961c549c488d0bb642d895 +refs/heads/master: e7b384043e27bed4f23b108481b99c518dd01a01 diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 2629c1711fd6..d5e37072ea54 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -4386,7 +4386,16 @@ asmlinkage long sys_sched_yield(void) return 0; } -static inline void __cond_resched(void) +static inline int __resched_legal(void) +{ + if (unlikely(preempt_count())) + return 0; + if (unlikely(system_state != SYSTEM_RUNNING)) + return 0; + return 1; +} + +static void __cond_resched(void) { #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP __might_sleep(__FILE__, __LINE__); @@ -4396,10 +4405,6 @@ static inline void __cond_resched(void) * PREEMPT_ACTIVE, which could trigger a second * cond_resched() call. */ - if (unlikely(preempt_count())) - return; - if (unlikely(system_state != SYSTEM_RUNNING)) - return; do { add_preempt_count(PREEMPT_ACTIVE); schedule(); @@ -4409,13 +4414,12 @@ static inline void __cond_resched(void) int __sched cond_resched(void) { - if (need_resched()) { + if (need_resched() && __resched_legal()) { __cond_resched(); return 1; } return 0; } - EXPORT_SYMBOL(cond_resched); /* @@ -4436,7 +4440,7 @@ int cond_resched_lock(spinlock_t *lock) ret = 1; spin_lock(lock); } - if (need_resched()) { + if (need_resched() && __resched_legal()) { _raw_spin_unlock(lock); preempt_enable_no_resched(); __cond_resched(); @@ -4445,14 +4449,13 @@ int cond_resched_lock(spinlock_t *lock) } return ret; } - EXPORT_SYMBOL(cond_resched_lock); int __sched cond_resched_softirq(void) { BUG_ON(!in_softirq()); - if (need_resched()) { + if (need_resched() && __resched_legal()) { __local_bh_enable(); __cond_resched(); local_bh_disable(); @@ -4460,10 +4463,8 @@ int __sched cond_resched_softirq(void) } return 0; } - EXPORT_SYMBOL(cond_resched_softirq); - /** * yield - yield the current processor to other threads. *