NetBSD 内存管理系统 UVM 浅析
2006-08-09 22:57:02 来源:WEB开发网如果合并不成, 我们就要创建新的表项, 代码在 nomerge 标记之后. 需要注意的是对 UVM_FLAG_COPYONW (COW) 的处理, 如果没有要求 UVM_FLAG_OVERLAY ( 创建一个映射覆盖 uobj 的 amap) 的话, 就会设其 etype 为 NEEDSCOPY, 这样 , 就是在第一次试图写的时候引起 fault, 由 vm_fault 处理这个 COW 的情况, 这是 uvm_map 对 COW 的支持, 而详细的处理过程将在下面的章节介绍.
uvm_unmap 的代码在 uvm_map_i.h, 它的主要工作是由 uvm_map.c 中的 uvm_map_remove 和 uvm_map_detach 完成.
uvm_map_remove()
这函数将解除参数 start 到 end 的映射. 这本是一个简单的任务, 只要将 start 到 end 之间的 vm_map_entry 清理出去就可以了. 但是如果 start 和 end 不是正好跟一个 vm_map_entry 对齐的时候, 我们就只好先把这个 vm_map_entry 分成两半, 在把其中的一半清理出去, 这由 UVM_MAP_CLIP_START 和 UVM_MAP_CLIP_END 完成, 它们包裹位于 uvm_map.c 中的 uvm_map_clip_start 和 uvm_map_clip_end, 有兴趣的读者可以自行阅读相关代码.
除此以外, 我们可以依次把范围内的 vm_map_entry 清出, 我们来看具体的处理过程.
XXX
uvm_map_detach()
uvm_unmap_remove 将清出 uvm_map 的表项做成链表返回, 再由 uvm_unmap_detach 解除引用关系. 这样做的原因是解除引用关系往往会引起写回文件等 I/O 操作, 花费很多时间, 而 uvm_umap_remove 工作时时要把整个 uvm_map 锁住的, 如果是在 remove 的同时做 detach 操作, 锁住 uvm_map 的时间就会很长, 影响效率.
函数本身很简单, 就是依次取消每个表项的 amap 和 uvm_obj 引用.
底层管理机构 (amap, anon, uobj, pager)
传统管理机构: uvm_obj
我们先来叙述经典的 4.4BSD vm_object 机制. vm_object 内存系统中的资源代表, 可以映射进地址空间使用. vm_object 向下连接着 pager --- 资源操作的接口, pager 又连接着真正的资源. 当访问内存产生 fault 的时候, 系统会通过 vm_object, 再通过 pager 到指定的资源处取得相关的数据来填充页面, 从用户的观点看就象是这个资源已经完全映射到内存中一样.
更多精彩
赞助商链接