Messages in this thread | | | Date | Thu, 04 Apr 2002 14:38:11 -0800 | From | Andrew Morton <> | Subject | Re: Patch: linux-2.5.8-pre1/kernel/exit.c change caused BUG() at boot time |
| |
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/
| |