1

The scheduler entry in Linux starts with executing schedule() which then calls the __schedule() function. It is defined as :

asmlinkage __visible void __sched schedule(void)
{
    struct task_struct *tsk = current;

    sched_submit_work(tsk);
    do {
        preempt_disable();
        __schedule(false);
        sched_preempt_enable_no_resched();
    } while (need_resched());
}

My question is - why is there a need to disable preemption in the scheduler code when no other task could possibly call the schedule() function and thus preemption should be automatically disabled until the next task is scheduled. Am I missing something basic here?

  • "... when no other task could possibly call the `schedule()` function" - Eh? Tasks are allowed to call `schedule()` whenever they want, and they actually do that in [many places](https://elixir.bootlin.com/linux/v5.7.8/C/ident/schedule). In any case, the function [__shedule()](https://elixir.bootlin.com/linux/v5.7.8/source/kernel/sched/core.c#L4001) calls `smp_processor_id()`, which in turn is allowed to be called only with disabled preemption. – Tsyvarev Jul 26 '20 at 11:48
  • If schedule() is currently executing, how could another task run on the same processor which may call schedule(), unless schedule() itself preempts to another task to run? – Lucifer Poltergeist Jul 26 '20 at 18:08
  • "how could another task run on the same processor which may call schedule(), unless schedule() itself preempts to another task to run?" - You have just answered your question by yourself: Without disabled preemption the current task could be preempted by some other one on a given CPU. – Tsyvarev Jul 26 '20 at 21:01

0 Answers0