[added back the LKML since others might learn from this too]Hi, Steve:
On Tue, 11 Oct 2005, liyu wrote:
For first question, I have a few confused yet.
As Steven said, if PREEMPT_ACTIVE is set, we cann't preempt current task,
we can not wake up it later, however, the process of task switch will
of the task context to task_struct (also thread_info), why we cann't wake
First let me corrent that statement. I said that if PREEMPT_ACTIVE is
set, we can't take the task off the run queue. I didn't say we can't
preempt that task, since that _is_ what is about to happen.
OK I worded it wrong. I shouldn't say we "can't" wake it up. What I
should have said is that we may not know to wake it up. You are right,
all the information is there to wake it up but the case might happen where
we just don't know to do it.
Here's some common code to look at.
This above code isn't directly from the kernel but the logic of it is all
over the place. So the task is going to wait for some event, and when
that event happens, it will wake up all the tasks that are on the wait
queue. Now what happens if the event happened before the
set_current_state(TASK_UNINTERRUPTIBLE)? Normally that would be OK
because of the check to see if some_event happened, and if it did then
don't call schedule.
Now back to that PREEMPT_ACTIVE check. If the above case happens, and then
the task is preempted before it set itself back to TASK_RUNNING, without
the PREEMPT_ACTIVE check in schedule, the process would be removed from
the task run queue. That means it is no longer in the queue to be
scheduled. But the event already happened that would have woken it back
up. So this task would forever stay in the TASK_UNINTERRUPTIBLE state and
never wake up. The PREEMPT_ACTIVE check is to allow the task to stay on
the run queue until it gets to a point that itself calls schedule. As the
above logic might allow (if the event has not happened yet).
So what determines what can be scheduled, is the fact that the task is on
the run queue, _not_ whether or not the task is in the TASK_RUNNING state.
At least with preemption enabled. Not being in TASK_RUNNING will take the
task off the run queue when that task calls schedule itself, not when it
Does this make more sense?