Reputation: 4517
Do I need to call set_current_state()
before calling schedule()
to schedule the next process from the run queue?
I have seen lot of code where the kernel thread function is using set_current_state()
to set the state to TASK_RUNNING
or TASK_UNINTERRUPTIBLE
.
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
....
schedule();
.....
}
__set_current_state(TASK_RUNNING);
Is it necessary to call set_current_state()
with TASK_INTERRUPTIBLE
before calling schedule()
?
In this example code, what is the use of setting the state to TASK_RUNNING
after it comes out of the kthread_should_stop()
loop?
Upvotes: 2
Views: 2550
Reputation: 239041
Yes, you must call set_current_state()
before calling schedule()
, because otherwise the scheduler will not remove the task from the run queue (if you just want to potentially allow other tasks to run without going to sleep, you should be calling cond_resched()
instead).
The task state you set depends on whether you want to be woken up by signals or not:
TASK_UNINTERRUPTIBLE
is not woken by signals;TASK_KILLABLE
is only woken by deadly signals;TASK_INTERRUPTIBLE
is woken by any signal.Additionally, TASK_IDLE
is like TASK_UNINTERRUPTIBLE
but does not contribute to load average.
The reason that code is setting the state back to TASK_RUNNING
is because the kthread_should_stop()
might have returned true on the first iteration of the while()
loop, so schedule()
was never called (you do not need to set the task state back to TASK_RUNNING
after returning from schedule()
).
Normally, you will be waiting on a waitqueue, in which case you do not need to directly set the task state - instead, you can use the waitqueue helpers in a pattern like:
DEFINE_WAIT(wait);
prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
schedule();
finish_wait(waitqueue, &wait);
Upvotes: 6