Reputation: 2426
I've been reading http://www.linuxjournal.com/article/8144 and thinking about the following situation:
4253 /* Wait for kthread_stop */
4254 set_current_state(TASK_INTERRUPTIBLE);
4255 while (!kthread_should_stop()) {
4256 schedule();
4257 set_current_state(TASK_INTERRUPTIBLE);
4258 }
4259 set_current_state(TASK_RUNNING);
4260 return 0;
Now, what happens if kthread_stop was called right before line 4254 where we set the process to sleep, and right after that line we actually get preempted/scheduled and the process is also really sent to sleep?
In this case, the wake up call is received right before changing the state (so it does not affect us), and the normal operation of the operating system puts us to sleep before we actually check anything.
I imagine I'm missing something, probably one of the following two options: (1) The actual change of the state only happens when we call schedule(), or (2) There is no way for us to get scheduled out (either by preemption, interrupts, anything) after the set_current_state call and before the schedule() call.
Thanks for any assistance!
Upvotes: 4
Views: 3831
Reputation: 11
Here is a similar question & answer
http://fixunix.com/linux/7425-schedule_timeout-doubt-possible-infinite-sleep.html
quoting from the link,
[quote-]
If I understand it correctly, when a preemption occurs, the PREEMPT_ACTIVE bit gets added to the thread's preempt_count; this happens in preempt_schedule / preempt_schedule_irq. These then call schedule(), which checks for PREEMPT_ACTIVE being set in the count and if it's set, it doesn't call deactivate_task(), which leaves the thread on the active list. [-quote]
So if an interrupt or preemption happens, the thread will not be moved out of the run queue.
Upvotes: 1
Reputation: 36402
If kthread_stop
gets called before line 4254, kthread_should_stop()
will return true, and schedule()
will not be called.
In this specific case, the migration_thread
is scheduled with high priority with the SCHED_FIFO
policy (which has no time slices), and can only be preempted by another SCHED_FIFO
task with higher priority (see sched_setscheduler).
Upvotes: 1
Reputation: 129364
schedule() is the ONLY way that the Linux kernel will change context between threads.
As the code comments, this is for migrating between processors, so presumably isn't run very often (relatively speaking).
Upvotes: -1