免费注册 查看新帖 |

Chinaunix

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

[内存管理] 关于缺页异常:缺页异常中是否会进行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

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
3 [报告]
发表于 2014-12-23 14:42 |只看该作者
看似可以的~,因为在进入vma的nopage/fault 流程进行IO操作前,就已经开中断了,此时其实是可以睡眠的。
__do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
...
        /*
         * It's safe to allow irq's after cr2 has been saved and the
         * vmalloc fault has been handled.
         *
         * User-mode registers count as a user access even for any
         * potential system fault or CPU buglet:
         */
        /*
         * 开中断,这种情况下(cr2已经保存,并且vmalloc fault已经处理过了),是安全的,可以缩短因缺页异常导致的关中断时长。
         */
        if (user_mode_vm(regs)) {
                local_irq_enable();
                error_code |= PF_USER;
        } else {
                if (regs->flags & X86_EFLAGS_IF)
                        local_irq_enable();
        }
...
        /*
         * 分配物理内存,缺页异常的正常处理主函数
         * 可能的情况有:1、请求调页/按需分配;2、COW;3、缺的页位于交换分区,
         * 需要换入。
         */
        fault = handle_mm_fault(mm, vma, address, flags);
...
}

论坛徽章:
0
4 [报告]
发表于 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中)执行?在这个独特的路径里,并不需要处理诸如软中断、内核抢占之类的东西,而且进入缺页异常后使用的是当前进程的内核栈(上下文保存在进程的内核栈中),因此只要异常处理代码中打开中断之后就可以被调度?

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
5 [报告]
发表于 2014-12-24 08:40 |只看该作者
首先,缺页异常的这个流程应该还是在中断上下文中~
其次,个人觉得并没有严格限制说中断上下文中不能睡眠(应该说不能在关中断时的中断上下文中睡眠),在开中断的情况下应该是可以睡眠的,此时中断照常,可以避免“紧急任务”饥饿,同时在开内核抢占的情况下,也能进行抢占,并且在因为IO睡眠时,在IO结束后该进程能被**(IO结束后的中断中),然后继续完成中断上下文的工作,进而恢复正常调度。
再次,这种情况本身应该是比较少的,对系统整体运行影响不大。
另外,缺页异常中使用的就是当前进程的内核栈(其实内核栈是所有进程公用的~),异常处理中打开中断后,如果开了抢占,能发生抢占,否则的话是不能正常调度的。

论坛徽章:
0
6 [报告]
发表于 2014-12-24 17:48 来自手机 |只看该作者

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

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

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

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

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

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

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

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
7 [报告]
发表于 2014-12-26 11:41 |只看该作者
NewThinker_wei 发表于 2014-12-24 17:48
中断上下文中好像不是开了中断就可以睡眠那么简单,我的理解是这样的:

从中断上下文中"栈"的位置来看 ...

不好意思,关于内核栈,之前确实说错了。内核栈是每个进程自有的,中断栈(如果配置为独立的话)是每个cpu一个,各进程共享。
但开中断后,如果再次发生中断,上下文应该是会先进行保存的,应该不存在不能嵌套的问题。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP