免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2518 | 回复: 3
打印 上一主题 下一主题

[内存管理] 关于缺页异常:缺页异常中是否会进行IO操作(读文件或交换区中的内容到物理页面中) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-12-22 23:41 |显示全部楼层 |倒序浏览
缺页异常中可能需要读取文件或交换区到主存中,不会引起睡眠吗?在中断上下文睡眠是不允许的


mmap系统调用可以将文件内容映射到用户空间,但当用户调用mmap时内核并不会马上将用户请求的文件内容读取到物理页中,而是直到用户访问映射空间引发缺页异常时内核才将需要的内容读入物理页中。 VMA(vm_area_struct) 的 nopage/fault 函数是在缺页异常中被调用,如果VMA的nopage/fault 函数需要读取磁盘文件,就会有文件IO操作(意味着会睡眠),但如果 nopage/fault 可以睡眠,它还怎么运行在缺页异常(中断上下文)中呢?所以感觉在nopage/fault 函数中肯定不能读文件,那文件中的内容又是怎么进入到内存中的呢?

我疑惑的是,如果缺页异常中确实需要IO操作了,内核是怎么做的?跟了一下缺页异常的代码,有些复杂,目前还没头绪。难道是当需要IO操作时就先将当前进程挂起,然后再启动一个内核线程,当缺页异常退出后再由这个内核线程完成被推后的 IO 操作并**被挂起的进程?(只是猜测,在内核源码中还没找到有这样的代码)

哪位前辈能给些指点

论坛徽章:
0
2 [报告]
发表于 2014-12-22 23:47 |显示全部楼层
huan(唤)xing(醒)两个字竟然被屏蔽了……

Screenshot from 2014-12-22 23:46:41.png (11.43 KB, 下载次数: 38)

Screenshot from 2014-12-22 23:46:41.png

论坛徽章:
0
3 [报告]
发表于 2014-12-24 00:24 |显示全部楼层
回复 3# humjb_1983

你好 humjb_1983,多谢你的解答!!:wink:

缺页异常中在调用handle_mm_fault函数前会开中断这一点我之前也看到了,但我当时想的是:中断被打开只是为了不丢失新的硬件中断,并不能代表当前的上下文就不再是中断上下文了吧?比如软中断softirq里面也会开中断,但软中断依然属于中断上下文,不能在软中断里睡眠。
而且,整个do_page_fault函数应该是在一个中断处理程序中被调用吧?在asm_do_irq()函数中,是先根据中断号执行被注册到该中断线上的中断处理函数,再在irq_exit()中遍历软中断,然后才算退出了中断上下文。这不就意味着,do_page_fault的整个过程其实都属于中断上下文?

难道说缺页异常作为一种特殊的中断,并不在通用的中断执行路径里(asm_do_irq中)执行?在这个独特的路径里,并不需要处理诸如软中断、内核抢占之类的东西,而且进入缺页异常后使用的是当前进程的内核栈(上下文保存在进程的内核栈中),因此只要异常处理代码中打开中断之后就可以被调度?

论坛徽章:
0
4 [报告]
发表于 2014-12-24 17:48 来自手机 |显示全部楼层

中断上下文中好像不是开了中断就可以睡眠那么简单,我的理解是这样的:

从中断上下文中"栈"的位置来看,内核有两种实现方式,第一种是直接使用被中断进程的内核栈,另一种是使用专门的中断栈,这种情况下每个cpu都有一个自己的中断栈,由所有该cpu上产生的中断共用。

如果是使用被中断进程的内核栈,那在中断处理函数中current宏依然有效,且指向被中断的进程。这时在ISR中(开中断后)睡眠的话,ISR的上下文,包括局部变量、返回地址等都保存在被中断进程的内核栈中,中断会暂时占用该进程的进程描述符,这样系统的调度程序以后仍然可以根据被中断进程的进程描述符将尚未完成的ISR调度回来。这样看来,似乎ISR中开了中断就可以睡眠,但这其实会引发一系列问题:无辜的被中断进程也许并不需要睡眠,但却被中断强制睡眠了,甚至被强制睡眠的可能是一个实时进程,而且在中断可嵌套的平台上,一个ISR的睡眠还意味着被它打断的其他低优先级中断ISR会一块儿进入睡眠,所以即使在使用进程内核栈的情况下,在中断中睡眠也有很多弊端。

而如果中断上下文中使用的是专门的中断栈(它不与任一个进程关联),那在ISR中current宏就变成无效了,这种情况下ISR的上下文就无法保存到有效的进程描述符中,这时一旦在ISR中睡眠了,那这个ISR就永远无法再被调度执行。

所以不论哪种情况,我感觉应该都不允许中断上下文中睡眠的。

{顺便说句,你后面提到"内核栈是所有进程共有的",应该是每个进程都有自己的内核栈吧?}

不过话说回来,对于中断上下文使用进程内核栈的情况,被缺页异常打断的进程本身就是有问题的进程(它不是"无辜"的),所以就可以毫不客气地在中断上下文中将它强制睡眠了?呵呵,这倒似乎行的通,但不知道内核开发者们是不是这么干的。有点混乱了

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP