Messages in this thread Patch in this message | | | Date | Thu, 9 Jul 2009 00:45:45 +0400 | From | Anton Vorontsov <> | Subject | [PATCH] sched: Make cond_resched*() available earlier |
| |
Using early netconsole and gianfar driver this error pops up:
netconsole: timeout waiting for carrier
It appears that net/core/netpoll.c:netpoll_setup() is using cond_resched() in a loop waiting for a carrier.
The thing is that cond_resched() is a no-op when system_state != SYSTEM_RUNNING, and so drivers/net/phy/phy.c's state_queue is never scheduled, therefore link detection doesn't work.
The system_state check exists to avoid very early calls to the scheduler. Though, using cond_resched() should be safe after scheduler is initialized, so instead of checking the system_state, we can test that the scheduler is running, therefore making cond_resched() and friends available much earlier (but not too much).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> ---
On Wed, Jul 08, 2009 at 02:58:46PM +0200, Peter Zijlstra wrote: [...] > > > > Hm. Speaking of cond_resched*() only, then it should be pretty > > > > safe to convert the SYSTEM_RUNNING checks to scheduler_running, > > > > no? scheduler_running is set after sched_init(). > > > > > > Hmm, that might work, I'd have to audit sched_init_smp() as it seems to > > > do way too much... > > > > sched_init_smp() is called from the kernel_thread(), so > > if the scheduler is not functional prior to kernel_thread(), > > you're in trouble anyway, no? The point is that a lot of > > code is calling schedule() prior to sched_init_smp() > > (e.g. msleep(), mutexes), and there are no issues. So > > should be no issues with cond_resched()? > > Yeah, it should be good, I just got paranoid looking at > sched_init_smp().
OK, thanks everyone for the reviews.
Here is an updated patch. As usual, tested on UP PowerPC, with and without SMP, PREEMPT and PREEMPT_VOLUNTARY.
kernel/sched.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/sched.c b/kernel/sched.c index 7c9098d..555360b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6561,7 +6561,7 @@ static void __cond_resched(void) int __sched _cond_resched(void) { if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) && - system_state == SYSTEM_RUNNING) { + scheduler_running) { __cond_resched(); return 1; } @@ -6579,7 +6579,7 @@ EXPORT_SYMBOL(_cond_resched); */ int cond_resched_lock(spinlock_t *lock) { - int resched = need_resched() && system_state == SYSTEM_RUNNING; + int resched = need_resched() && scheduler_running; int ret = 0; if (spin_needbreak(lock) || resched) { @@ -6599,7 +6599,7 @@ int __sched cond_resched_softirq(void) { BUG_ON(!in_softirq()); - if (need_resched() && system_state == SYSTEM_RUNNING) { + if (need_resched() && scheduler_running) { local_bh_enable(); __cond_resched(); local_bh_disable(); -- 1.6.3.3
| |