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

From: Roger Larsson (roger.larsson@norran.net)
Date: Thu Apr 04 2002 - 16:34:04 EST


On torsdagen den 4 april 2002 21.26, Robert Love wrote:
> On Thu, 2002-04-04 at 14:14, Linus Torvalds wrote:
> > The answer is that preempt_schedule() illegally sets
> >
> > current->state = TASK_RUNNING;
> >
> > without asking the process whether that's OK. The SMP code never does
> > anything like that.
>
> Well Ingo added that ;)
>
> We used to just set a flag in the preempt_count that marked the task as
> preempted and made sure on its next trip into schedule it ran again.
>

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();
        current->state = saved_state;
}

It is unlikely to get preemption between schedule() and the
setting since schedule it self checks - the window is small.
And when it hits if will correctly restore the correct value.

Note this code does not need to solve the FLAG problem.

         current->state |= FLAG
        * PREEMPT *
                current->state |= FLAG
                schedule()
                current->state &= ~FLAG
        schedule() with flag disabled

/RogerL

-- 
Roger Larsson
Skellefteċ
Sweden

- 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/



This archive was generated by hypermail 2b29 : Sun Apr 07 2002 - 22:00:15 EST