免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: chenrvmldd
打印 上一主题 下一主题

也谈谈这四年来对内核的研究 [复制链接]

论坛徽章:
0
81 [报告]
发表于 2011-07-05 19:46 |只看该作者
回复 69# linewer


    回答:linewer兄弟的问题
这个兄弟提出的这个问题:其实当时我也困惑过,这个问题问的不错,证明Linewer兄弟认真的思考过了地址映射的过程,下面我大概的描述一下用户态进程页表映射的过程和内核页表映射的过程,你看明白这个我详细对于你问的这个问题就可以迎刃而解了!
用户态进程的页表的映射:众所周知:linux中是采用的写时复制机制,当发生访问一个文件内容,这个内容还没有被载入到实际的物理内存时,就会发生缺页异常,缺页异常的主要任务就是建立当前用户进程和某段物理地址(物理地址是通过Buddy分配的)之间的映射关系,如果这个时候buddy分配失败会启动kswapd进程(这个过程就太长了,不讲了,以后再讲),在这个过程中内核只负责为缺页分配了用户态进程所需要的实际物理内存,然后去填用户进程的页表!
下面关于内核页表的映射,在缺页的过程中,并没有发生先将物理内存映射到内核页表再将物理内存映射到用户进程的页表,对于内核页表的映射我只讲一部分,因为全讲所花的篇目比较长,还是留在以后的问题中再阐述!就来讲讲正常情况下内核页表的映射:对于内存小于896M以下的物理内存都是和内核页表一一映射,也就说物理内存的0-896M和内核的线性地址的:3G-3G+896M是一一对应的,在内核页表初始化的时候就已经映射好了,以后就不需要再去映射了,那就解释了为什么内核中访问内存的时候不会存在缺页的情况,这样做的目的是什么了?为什么不能像用户态那样了?我的理解如下:
第一:在内核态能越少做事情就越少做事情,这样可以提高系统的响应和吞吐!
第二:内核中没有必要延迟分配,因为内核申请的内存都是紧急的!
也许有的地方讲的不是是很慎密,毕竟好久没有接触这块的内容了,代码细节的方面都忘了差不多了!不知道Linewer兄弟能不能理解我所讲的,你的问题弄懂了没有?

论坛徽章:
0
82 [报告]
发表于 2011-07-05 20:14 |只看该作者
我自己来回答自己的三个问题:
第一个小问:记得在学操作系统的时候,老师曾经提过进程上下文切换,说进程上下文切换比较耗时,在这点上线程要比进程有优势,那么进程的上下文是什么了?切换的时候都做了些什么?我相信这个对于看过内核代码的兄弟都比较容易,那好,我们知道在进程切换的时候:在古老的Linux中采用的方法和现代版本的Linux中采用的是不同办法?这两个办法有什么差别了?为什么新版本的内核采用现在的切换机制?其实,这个问题我想考察大家对Linux各种版本之间的关系,因为Linux内核不停的再优化,为什么会这么优化基于什么样的考虑?这个可以从内核不停的修改这方面可以看得出,这样也可以为我们去优化内核提供思路
关于进程上下文是什么,简单的说一下:那就是一些寄存器!具体的不讲了!稍微看一下代码就OK了,着重讲解进程的切换!
其实,当时我在看0.11版本的内核时,发现进程上下文的切换是这样做的:
通过一个jmp语句直接跳到下一个进程中去执行了,这也就是我们所说的通过硬件完成自动的切换!这样带来一个问题,那就是浪费时间,有没有更好的办法了?
后来的Linux的版本提出了软件切换,也一直延续到现在的内核版本:关于具体的切换代码,我就不贴出来了,切换的过程主要是通过; switch_to这个函数完成的,那么问题又来了,为什么软件切换的速度要比硬件切换的速度要来得快了?这貌似和我们平时理解的有点不太一样,因为我们都觉得让硬件做一般比硬件快,这个到现在我也不是特别的理解,后来看到Linux内核情景分析上提到过,但是讲的也不是很详细,后来想通过intel的手册去找到答案,最后也是无果而终!
我的理解和猜测应该是这样:对于硬切换虽然是通过一个Jmp操作,但是在JMP之后有很多隐含要执行的指令,这些指令要比软切换执行的指令要多!如果其他兄弟有更好的看法可以提出来!从这一段小小的代码就可以发现,Linux内核的设计是多么的慎密,其实还有很多细节可以体现出Linux设计的博大精深!比如:我记得以前看到过的*(unsigned long*)&jiffies++!
其实,发现看内核代码对我们程序员有太多太多的好处:我觉得最重要的两点:
1.        提高我们自身的编码能力
2.        提高我们优化程序的能力
3.        给我们解决问题提供一些不可估量的思路,其实我在做嵌入这块,有的时候会无形当中参考了内核的一些方面的设计的思想

论坛徽章:
0
83 [报告]
发表于 2011-07-05 21:36 |只看该作者
来跟着学学

论坛徽章:
0
84 [报告]
发表于 2011-07-05 22:41 |只看该作者
我自己来回答自己的三个问题:
第一个小问:记得在学操作系统的时候,老师曾经提过进程上下文切换,说进程 ...
chenrvmldd 发表于 2011-07-05 20:14


这种进程切换方式的改变,按ULK的解释来说,最重要的原因来源于安全性的检查,至于效率,两者是差不多的——我自己没有去实际测试过谁快谁慢,事实上,也没有用过那么老版本的内核。

论坛徽章:
0
85 [报告]
发表于 2011-07-05 22:49 |只看该作者
回复 81# chenrvmldd
多谢chenrvmldd兄的解答!写的很详细,看明白了
上午在公司看到nettom兄的回复,然后走读下kernel中do_fault_page函数的实现,加深了下体会(以前只知道它大概干啥的,没仔细研究过),在公司没法回复帖子,在手机上回复发了几次没成功最后成了空回复:(

"第一:在内核态能越少做事情就越少做事情,这样可以提高系统的响应和吞吐!
第二:内核中没有必要延迟分配,因为内核申请的内存都是紧急的!"   
说下个人理解:内核算是OS中优先级最高的部分,如果其申请内存,那应该是有正当理由的,没道理去延迟;而用户态进程一般都不是那么的紧急,利用请求调页和写时复制等技术来尽可能的推迟,毕竟内存资源有限,好钢用在刀刃上,呵呵,可能不太恰当

看内核代码一直有种 "明白--->迷惑--->又明白--->又迷惑的--->...."的感觉,学习时做些笔记或者代码中注释下比较好

对于chenrvmldd说的内核版本变化,自己喜欢看下每个版本的ChangeLog,会有些说明的...

论坛徽章:
0
86 [报告]
发表于 2011-07-06 10:18 |只看该作者
本帖最后由 futex 于 2011-07-06 11:18 编辑

回复 69# linewer


    你是说进程使用mmap来map一个文件到用户地址空间,然后用内存地址的方式来访问文件内容的情况吧?我来回答一下这个问题:
  1:进程调用mmap时,除非设定VM_LOCKED标志,否则只是为进程分配一个要map文件长度的vm_area_struct结构,表示这段进程虚拟地址空间已被占用,同时调用要map的文件的f_op->mmap()操作,我们知道,设备也可以作为一个文件打开并执行mmap动作(如果设备驱动允许的话),对于这类文件的f_op->mmap操作由设备驱动自己实现。这里以普通文件为例(ext2文件系统),f_op->mmap将vma->vm_ops设置为generic_file_vm_ops, 该ops中指定了fault函数为filemap_fault,到此整个mmap过程结束,可以看到,没有任何page被分配,没有任何页目录和页表被修改,仅仅是分配了一个虚拟地址空间。
  2:当用户访问该地址空间时,mmu发现页表上没有该地址的映射,于是发生一个page fault,在这个page fault的过程中发现这个地址在当前进程已分配的虚拟地址空间中(找到了该地址所在的vm_area_struct结构),由于找到的vm_area_struct对象中的vm_ops被指定,并且该ops中的fault函数被指定,因此可以确定此虚拟地址空间是被map到一个文件中。之后就是调用vm_ops中的fault函数(这是一个函数指针,具体指向filemap_fault函数),该函数分配新的page, 读入page fault处的文件内容到page中并将该page放入到文件的page cache中。在fault函数返回后再在页表中增加指向该page的页表项,至此,大功告成,说的简单但过程比较复杂。
  3:如果mmap是指定了VM_LOCKED标志呢?mmap过程主动调用handle_mm_fault函数来模拟上述page fault过程,分配page, 把所有已map的文件内容读入page中,再在页表中增加指向这些page的表项。
  4:结论:mmap根据mmap的方式不同,分别使用COW方式和map时分配加载文件内容并建立页表项的方式来处理。一般情况下不指定VM_LOCKED而采用COW方式,除非有特别的需要(需要立即加载文件并建立页表映射)。
  5:哈哈,俺的回答解决了你的问题吗?还是答非所问?

论坛徽章:
0
87 [报告]
发表于 2011-07-06 11:11 |只看该作者
对于第四点,表示很赞同...

论坛徽章:
0
88 [报告]
发表于 2011-07-06 13:13 |只看该作者
回复 84# 独孤九贱


    事实上从源码来看,也没有做什么安全性的检查?能不能详细一点解释一下了?

论坛徽章:
0
89 [报告]
发表于 2011-07-06 13:14 |只看该作者
回复 85# linewer


    看内核代码一直有种 "明白--->迷惑--->又明白--->又迷惑的--->...."的感觉,学习时做些笔记或者代码中注释下比较好
你说的这种感觉相信大家都会有过的,确实是这样的

论坛徽章:
0
90 [报告]
发表于 2011-07-06 16:32 |只看该作者
我来mark一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP