Re: [Question] Some question about Ingo scheduler.

From: liyu
Date: Tue Oct 11 2005 - 02:51:54 EST


Steven Rostedt Wrote:

[added back the LKML since others might learn from this too]

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,
because of
we can not wake up it later, however, the process of task switch will
save information
of the task context to task_struct (also thread_info), why we cann't wake
up it?



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.

add_wait_queue(q, wait);
set_current_state(TASK_UNINTERRUPTIBLE);
if (!some_event)
schedule();
set_current_state(TASK_RUNNING);
remove_wait_queue(q, wait);


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
is preempted.

Does this make more sense?

-- Steve




Hi, Steve:

Thanks for so detailed explain.

It seem I am not understand what is sleep and wakeup truly.

What's your mean of "in runqueue"? I think you mean the
task_struct is in one priority array (active or expired)
of one queue. the schedule() only can process task in runqueue.
In deactivate_task(), it will reset task_struct->array to NULL,
After call it, we can not wake up that task.

However, I read try_to_wake_up(), and found it can handle that case
which task_struct->array is NULL, it will be call activate_task()
to insert task to one runqueue. and default_wake_function() will
call try_to_wake_up(), so we still can wake up it.

I am confused again. this quesion is more interesting and more.

Wait for reply.

Good luck.


--liyu





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