从()内核的函数实际工作?

我试图理解Linux内核中的进度过程是如何工作的。 我的问题不是关于调度算法。 它关于函数schedule()switch_to()工作的。

我会尽力解释。 我看到了:

当进程用完时间片时,标志need_reschedscheduler_tick()设置。 内核检查标志,看到它已设置,并调用schedule() (与问题1相关)切换到新进程。 该标志是应该尽快调用调度的消息,因为另一个进程值得运行。 在返回到用户空间或从中断返回时,将检查need_resched标志。 如果已设置,则内核在继续之前调用调度程序。

研究内核源代码(linux-2.6.10 - “Linux内核开发第二版”所基于的版本),我还看到一些代码可以自动调用schedule()函数,让另一个进程有权跑。 我看到函数switch_to()是实际执行上下文切换的函数。 我研究了一些与架构相关的代码,试图了解switch_to()实际上在做什么。

这种行为引发了一些问题,我无法找到答案:

  • switch_to()完成时,当前正在运行的进程是什么? 调用schedule()的过程? 或者下一个过程,即被选中运行的过程?

  • schedule()被中断调用时,选择的进程在中断处理完成时(在某种RTE之后)开始运行? 或之前?

  • 如果schedule()函数不能从中断中调用,flag- need_resched是什么时候设置的?

  • 当定时器中断处理程序正在工作时,正在使用什么堆栈?

  • 我不知道我是否可以说清楚。 如果我不能,我希望我能在回答(或问题)后做到这一点。 我已经看了几个试图理解这个过程的来源。 我有这本书“Linux Kernel Development,sec ed”,我也在使用它。 我知道一些关于MIP和H8300架构,如果这有助于解释。


  • 在调用switch_to() ,内核堆栈切换到next命名的任务。 更改地址空间等在context_switch()处理。
  • schedule()不能在原子上下文中调用,包括来自中断(参见schedule_debug()的检查)。 如果需要重新调度,则设置TIF_NEED_RESCHED任务标志,在中断返回路径中检查该标志。
  • 见2。
  • 我相信,使用默认的8K堆栈,中断可以用当前正在执行的任何内核堆栈进行处理。 如果使用4K堆栈,我相信有一个单独的中断堆栈(自动加载感谢一些x86魔法),但我不完全确定这一点。
  • 为了更详细一点,这里有一个实际的例子:

  • 发生中断。 CPU切换到中断蹦床例程,将中断号推入堆栈,然后跳转到common_interrupt
  • common_interrupt调用do_IRQ,禁用抢占,然后处理IRQ
  • 在某个时候,决定切换任务。 这可能来自定时器中断或来自唤醒呼叫。 无论哪种情况,都会调用set_task_need_resched,并设置TIF_NEED_RESCHED任务标志。
  • 最终,CPU在原始中断中从do_IRQ返回,然后进入IRQ退出路径。 如果此IRQ是从内核中调用的,它会检查是否设置了TIF_NEED_RESCHED,如果是,则调用preempt_schedule_irq,它在执行schedule()时短暂启用中断。
  • 如果从用户空间调用IRQ,我们首先检查在返回之前是否有任何需要执行的操作。 如果是这样,我们去retint_careful,它检查两个待处理的重新schedule()如果需要的话直接调用schedule() )以及检查未决信号,然后返回retint_check另一轮,直到没有更重要的标志设置为止。
  • 最后,我们恢复GS并从中断处理程序返回。
  • 至于switch_to() ; switch_to() (在x86-32上)的作用是:

  • 当我们稍后返回到此任务时,保存EIP(指令指针)和ESP(堆栈指针)的当前值。
  • 切换current_task的值。 此时, current现在指向新的任务。
  • 切换到新堆栈,然后将由我们切换的任务保存的EIP推入堆栈。 之后,将使用此EIP作为退货地址执行退货; 这就是它如何跳转回以前称为switch_to()的旧代码
  • 调用__switch_to()。 此时, current指向新任务,并且我们处于新任务的堆栈中,但其他各种CPU状态尚未更新。 __switch_to()处理切换诸如FPU,段描述符,调试寄存器等的状态。
  • __switch_to()返回时,将switch_to()手动推入堆栈的返回地址返回,将执行放回到新任务中switch_to()之前的位置。 切换任务现在已完全恢复执行。
  • x86-64非常相似,但由于ABI不同,必须稍微进行更多的状态保存/恢复。

    链接地址: http://www.djcxy.com/p/84887.html

    上一篇: to() functions from linux kernel actually work?

    下一篇: I want to sleep while holding a mutex