Re: Patch: linux-2.5.8-pre1/kernel/exit.c change caused BUG() at boot

Andrew Morton (akpm@zip.com.au)
Thu, 04 Apr 2002 14:38:11 -0800


Roger Larsson wrote:
>
> ...
> How about doing:
>
> asmlinkage void preempt_schedule(void)
> {
> unsigned long saved_state;
>
> if (unlikely(preempt_get_count()))
> return;
>
> preempt_disable(); /* or use an atomic operation */
> saved_state = current->state;
> current->state = TASK_RUNNING;
> preempt_enable_no_resched(); /* we are scheduling anyway... */
> schedule();

Interrupt occurs, puts this task in state TASK_RUNNING.

> current->state = saved_state;

whoops. We went back into TASK_UNINTERRUPTIBLE.

> }
>

We could fix this with changes to schedule(), but that's
not nice. Another approach would be:

preempt_schedule()
{
current->state2 = current->state;
current->state = TASK_RUNNING;
schedule();
current->state = current->state2;
}

and wake_up() would do:

tsk->state = TASK_RUNNING;
tsk->state2 = TASK_RUNNING;

With the appropriate locking, memory barriers and other
relevant goo I think this would work...

-
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/