免费注册 查看新帖 |

Chinaunix

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

[内核模块] 内核页面去写保护函数 un_wp_page() [复制链接]

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:57:09C
日期:2016-10-25 16:17:59
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-08-12 12:03 |只看该作者 |倒序浏览
代码版本:linux-0.11


void un_wp_page(unsigned long * table_entry)
{
        unsigned long old_page,new_page;

        old_page = 0xfffff000 & *table_entry;   /*取二级页表表项的高20位,也就是物理内存的内存页首地址*/

        /*这里 MAP_NR(old_page) 是计算物理内存在高于1M的内存的内存页数(那1M是给内核使用的)
      mem_map[]记录的是高于1M(1M是256个内存页)的内存页的使用情况
         */
        if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) {   /*页面只被引用1次,也就是没有被共享*/
                *table_entry |= 2;   /*设置该页属性为可读写,即去写保护*/
                invalidate();        /*刷新也变化高速缓存*/
                return;
        }
        if (!(new_page=get_free_page()))
                oom();
        if (old_page >= LOW_MEM)
                mem_map[MAP_NR(old_page)]--;
        *table_entry = new_page | 7;       /*将新申请的物理页面的页起始地址填写到当前任务页表项中,并设置属性*/
        invalidate();                      /*刷新也变化高速缓存*/
        copy_page(old_page,new_page);      /*拷贝旧页内存中的数据到新页内存中*/
}       

对红色字体中为什么那么做不明白。
old_page指向的内存页面的引用次数为1时,为什么要去写保护???这个页面引用计数如果要是是其他任务引用了该物理页面而计的数,此时这里把写保护属性去掉,是不是就又问题??? 求指导!

论坛徽章:
1
拜羊年徽章
日期:2015-03-03 16:15:43
2 [报告]
发表于 2012-08-12 12:17 |只看该作者
回复 1# shaohui973

这里的注释说的很清楚
mem_map[]里放的是页面被引用次数。
mem_map[MAP_NR(old_page)]==1表示,对应的old_page只被引用了一次, 因而不存在共享  

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:57:09C
日期:2016-10-25 16:17:59
3 [报告]
发表于 2012-08-12 13:48 |只看该作者
回复 2# linuxfellow

这里的注释是我自己写的。比如说,我调了sys_read()函数,这函数也跑进这里来,这样的,这个oldpage就是读缓冲区,在这个函数之前是没有对这块内存引用计数加1的。那么这里内存的引用计数为1,说明了有其他任务对其引用了,如果这里去掉了写保护,那么这块内存的内容就有可能被当前的系统调用所写,那我之前引用了这块内存的任务从这里取到的数据不就不对了吗?


   

论坛徽章:
1
拜羊年徽章
日期:2015-03-03 16:15:43
4 [报告]
发表于 2012-08-12 22:15 |只看该作者
回复 3# shaohui973
这里的写保护是为Copy on Write机制设置的。一页page刚产生时,只有虚拟地址没有物理内存,写保护就会被设置。如果有进程试图写这一页时,就会发生page fault中断;page fault中断有机制区分"good" or "bad"page fault中断。坏的page fault中断就不会取消保护, 好的page fault中断就会调用这个函数取消写保护。你担心的问题不会发生。你可以到page fault中断看看如何区分"good" or "bad"page fault中断。

   

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:57:09C
日期:2016-10-25 16:17:59
5 [报告]
发表于 2012-08-29 09:42 |只看该作者
回复 4# linuxfellow


    你这个不对吧,一页刚产生时没有物理内存这没问题,这时候被设置的是页存在标识,会被设置为页不存在P=0;

在系统初始化的内存初始化过程中,1M之后的内存页的引用计数是被设置为0的;

在这里,我要引用这页内存时,发现该页内存的引用计数不是0,也就是说已经有人在引用这块内存了,这里它马上就去写保护,这怎么可以?

论坛徽章:
1
拜羊年徽章
日期:2015-03-03 16:15:43
6 [报告]
发表于 2012-09-04 11:06 |只看该作者
v0.11里, mem_map数组,该数组是一个字节型数组,用来标记内存页面使用的情况,未使用时为0,使用一次相应页自动加1. 在main().c时调用mem_init()对此初始化。
mem_map[]=1,该页只被使用了一次, 没有页面共享,所以可以安全的取消写保护。
如果mem_map[]》1, 就存在共享,只能把mem_map[]--,不能取消写保护。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP