我想在linux内核中实现IPC。这个想法是:
生产者流程可以写入物理页面
消费者流程只能阅读此页面
在生产者进程修复此页面之前,消费者进程无法读取此页面(例如,设置
页面到FIXSTATE
)
我的实现是:当消费者进程读取此页面时,它将调用pagefualt。
页面错误处理程序将让使用者pte(页表项)指向物理页面,然后暂停使用者进程。当生产者进程将此页面设置为FIXSTATE
时,生产者将会
找到等待队列并唤醒消费者流程。
我的问题是:
根据我的研究,我无法在页面错误处理程序中调用schedule()
来暂停使用者进程,因为它处于中断上下文中。因此,我将使用者进程状态设置为TASK_UNINTERRUPTIBLE
,然后调用resched_task(current)
以指示当从pagefault处理程序返回时当前(使用者)进程需要重新计划。但resched_task
是kernel / sched.c中的静态函数,不能在此文件外调用。
是否有一些方法可以暂停/暂停当前进程(进程调用pagefault) 在页面错误处理程序?
提前感谢任何答案!
答案 0 :(得分:0)
我认为你的前提是错误的。我不了解每个细节,但我认为你应该不在页面错误处理程序的中断上下文中。由于您是通过异常进入内核模式的,因此在进入时将中断 屏蔽(禁用)。但是你刚刚来自用户模式(好吧,通常;有时页面错误也可以从内核模式发生,但在“任务上下文”中),所以你不会处于中断状态。实际上,如果你从中断处理程序中获得页面错误,我看不出它何时不构成内核错误。
普通页面错误(例如,如果您的进程由于写入时复制或扩展堆栈等而需要分配新页面)将最终调用handle_mm_fault。它首先要做的是将状态设置为TASK_RUNNING。然后它可以立即分配新页面,修复PTE等(满足页面错误)并返回到用户模式离开状态为TASK_RUNNING。或者它可以阻止进程,直到内存可用,在此过程中的某个地方,将调用schedule(),允许其他进程在被阻塞时运行。
听起来你想做同样的事情。所以,看看handle_mm_fault正在做什么。
(所有这一切,我不明白你为什么不简单地让消费过程进行系统调用“进入消费模式”,这可能会阻止生产者完成“修复”页面。性能差异似乎很小,几乎无法测量。事实上,驱动程序模型已经支持file_operations表入口点以促进此类事情。如果你朝这个方向发展,核心内核将处理PTE和其他此类细节你。看看file_operations => mmap和vm_operations_struct => fault)
答案 1 :(得分:0)
我还没有完全阅读你的问题。但我知道暂停进程的通用方法。
创建一个等待队列。从运行队列中删除该进程并添加到等待队列,等待某个事件。当你想要唤醒过程时,只需发送事件。