我想在linux内核中实现IPC。这个想法是:
生产者进程可以写入物理页
消费者进程只能读取此页面
在生产者进程修复此页面之前,消费者进程无法读取此页面(例如设置 页面到
FIXSTATE
)
我的实现是:当消费者进程读取此页面时,它将调用 pagefualt。
页面错误处理程序会让消费者pte(页表项)指向物理页面,然后挂起消费者进程。当生产者进程将此页面设置为FIXSTATE
时,生产者将
找到等待队列并唤醒消费者进程。
我的问题是:
根据我的研究,我无法在页面错误处理程序中调用 schedule()
来挂起消费者进程,因为它处于中断上下文中。因此,我将消费者进程状态设置为 TASK_UNINTERRUPTIBLE ,然后调用 resched_task(current) 来指示当前(消费者)进程在从页面错误处理程序返回时需要重新调度。但是resched_task
是kernel/sched.c中的静态函数,不能在该文件之外调用。
是否有某种方法可以挂起/ sleep 当前进程(进程调用页面错误) 在页面错误处理程序中?
提前感谢您的回答!
最佳答案
我认为你的前提是错误的。我不明白每个细节,但我认为您不应该处于页面错误处理程序的中断上下文中。由于您已通过异常进入内核模式,因此中断将在进入时被屏蔽(禁用)。但是您刚刚来自用户模式(好吧,通常;有时页面错误也可能从内核模式发生,但在“任务上下文”中),因此您不会处于中断状态。事实上,如果您从中断处理程序中收到页面错误,我看不出什么时候这不会构成内核错误。
普通的页面错误(例如,如果您的进程由于写时复制或扩展堆栈或其他原因需要分配新页面)最终将调用handle_mm_fault。它所做的第一件事是将状态设置为 TASK_RUNNING。然后它可以立即分配一个新页面,修复 PTE 等(满足页面错误)并返回到用户模式,将状态保留为 TASK_RUNNING。或者它可以阻塞进程直到内存可用,这会导致调用schedule(),从而允许其他进程在阻塞时运行。
听起来您基本上想做同样的事情。所以只要看看handle_mm_fault正在做什么。
(话虽如此,我不明白为什么你不简单地让消费进程进行系统调用“进入消费模式”,这可能会阻塞,直到生产者完成“修复”页面。性能差异似乎很小,几乎无法测量。事实上,驱动程序模型已经支持 file_operations 表入口点来促进此类事情。如果你朝这个方向走,核心内核将为你处理 PTE 和其他此类细节。请参阅 file_operations => mm ap 和 vm_operations_struct => 错误)
关于linux - 如何在Linux内核的页面错误处理程序中挂起进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26882220/