4

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!

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
rmn
  • 2,386
  • 1
  • 14
  • 21

3 Answers3

1

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).

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
  • 1
    the question is what happens if we get rescheduled (due to normally consuming our time slice, or because an interrupt has occurred) after line 4254 and before line 4255 – rmn Dec 21 '12 at 10:39
  • @rmn: Just added extra detail, though the gist is, the thread doesn't have time slices. Interrupts aren't really relevant, as there wouldn't be a reason to reschedule. – Hasturkun Dec 21 '12 at 10:47
  • Even if a reschedule happens, when that is done, we get back to this code and continue as before. Nothing particularly special happens due to it. Is there some particular concern you have about this particular code, or are you just trying to understant scheduling of threads and such in general? Bearing in mind that this is the 2.6 kernel, and I haven't looked at the corresponding code in 3.7.1 kernel that is what I've been working on at work [nowhere near the scheduling parts tho'] – Mats Petersson Dec 21 '12 at 18:36
  • 1
    when a thread's state is set to task_interruptible, it is no longer task_running and it will not be rescheduled. So I'm afraid you guys might be missing my point.. – rmn Dec 21 '12 at 20:26
1

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.

-1

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).

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • 1
    I'm not sure you're right -- what about interrupts and preemption (after your time slice is up) ? – rmn Dec 21 '12 at 10:15