在Linux中,为什么要为每个进程保留不同的内核栈?
为什么不只保留一个栈供内核使用呢?
在Linux中,为什么要为每个进程保留不同的内核栈?
为什么不只保留一个栈供内核使用呢?
write()
等操作期间被抢占,并且另一个任务进行调度。内核栈是正在为每个进程执行的内核工作上下文的快照。thread_info
或某种机制从汇编器中获取进程信息。这至少需要一页分配。通过将内核模式栈放置在相同位置,可以使用简单的掩码从汇编器中获取thread_info
。因此,我们已经需要每个进程的变量和分配。为什么不将其用作存储内核上下文的堆栈,并允许在系统调用期间进行抢占呢?write
,抢占的效率可以得到证明。如果write()
是写入磁盘或网络,则需要一段时间才能完成。将5k到8k的缓冲区写入磁盘或网络将需要许多CPU周期才能完成(如果同步),并且用户进程将阻塞直到完成。在驱动程序中,这种传输可以使用DMA完成。在此期间,较低优先级的进程可以拥有CPU,并允许内核为每个进程保留不同的栈,以便在系统调用时进行抢占。这些堆栈几乎没有成本,因为内核已经需要为进程状态进行簿记,并且两者都保存在4k或8k页面中。为什么不只为内核保留一个堆栈?
这样,每次只有一个进程/线程能够进入内核。
基本上,每个线程都有自己的堆栈,在用户空间和内核边界之间切换并不会改变这个事实。内核也有自己的内核线程(不属于任何用户空间进程),它们都有自己的堆栈。