有两种情况调用调度程序代码 schedule() -
schedule()
当进程自愿调用 schedule() 时
定时器中断调用 schedule()
在案例2中,我认为 schedule() 在中断上下文中运行,但第一种情况呢?它是在调用它的进程的上下文中运行的吗?
还有更多场景调用 schedule() 吗?
schedule() 始终在进程上下文中运行 . 在第二种情况下,当它由定时器中断启动时,它位于从内核返回到被调用 schedule() 的中断进程的返回路径中 .
__schedule()是主调度函数 .
驱动调度程序并因此进入此功能的主要方法是:
在中断和用户空间返回路径上检查
TIF_NEED_RESCHED标志 . 例如,请参阅arch / x86 / entry_64.S . 为了驱动任务之间的抢占,调度程序在计时器中断处理程序scheduler_tick()中设置标志 .
唤醒并不会导致进入计划() . 他们将任务添加到运行队列中就是这样 . 现在,如果添加到运行队列的新任务抢占当前任务,则唤醒设置TIF_NEED_RESCHED并在最近的可能情况下调用schedule():
如果内核是可抢占的(CONFIG_PREEMPT = y):
在syscall或异常上下文中,在下一个最前面的preempt_enable()中 . (这可能是wake_up()的spin_unlock()!)在IRQ上下文中
,从中断处理程序返回到可抢占上下文
如果内核不可抢占(未设置CONFIG_PREEMPT),则在下一个:
cond_resched()调用
显式schedule()调用
从syscall或异常返回到用户空间
从中断处理程序返回到用户空间
http://lxr.free-electrons.com/source/kernel/sched/core.c#L2389
当进程调用 schedule() 时,它在基于中断的系统调用上下文中运行 . 在第二种情况下,硬件中断触发 schedule() 调用 . 在这两种情况下,它都作为中断运行 . AFAIK是调用 schedule() 的唯一次,因为大多数调度操作涉及修改要调度的事物的内核运行队列,尽管可以中断进程,但通常通过中断来告诉进程产生或进程产生本身 .
3 回答
schedule()
始终在进程上下文中运行 . 在第二种情况下,当它由定时器中断启动时,它位于从内核返回到被调用schedule()
的中断进程的返回路径中 .__schedule()是主调度函数 .
驱动调度程序并因此进入此功能的主要方法是:
在中断和用户空间返回路径上检查
TIF_NEED_RESCHED标志 . 例如,请参阅arch / x86 / entry_64.S . 为了驱动任务之间的抢占,调度程序在计时器中断处理程序scheduler_tick()中设置标志 .
唤醒并不会导致进入计划() . 他们将任务添加到运行队列中就是这样 . 现在,如果添加到运行队列的新任务抢占当前任务,则唤醒设置TIF_NEED_RESCHED并在最近的可能情况下调用schedule():
如果内核是可抢占的(CONFIG_PREEMPT = y):
在syscall或异常上下文中,在下一个最前面的preempt_enable()中 . (这可能是wake_up()的spin_unlock()!)
在IRQ上下文中
,从中断处理程序返回到可抢占上下文
如果内核不可抢占(未设置CONFIG_PREEMPT),则在下一个:
cond_resched()调用
显式schedule()调用
从syscall或异常返回到用户空间
从中断处理程序返回到用户空间
http://lxr.free-electrons.com/source/kernel/sched/core.c#L2389
当进程调用
schedule()
时,它在基于中断的系统调用上下文中运行 . 在第二种情况下,硬件中断触发schedule()
调用 . 在这两种情况下,它都作为中断运行 . AFAIK是调用schedule()
的唯一次,因为大多数调度操作涉及修改要调度的事物的内核运行队列,尽管可以中断进程,但通常通过中断来告诉进程产生或进程产生本身 .