高端内存:永久映射方式
时间:2010-11-21
来源:互联网
pkmap_count 保留了一个数组:当对应的表项为0是,说明相应的页表项还没有用于映射,当为1时,说明相应的页表项也没有用于映射,但是不能使用,因为其对应的TLB表项还没有刷新。当大于1时,则说明已经用于某个内核成分的映射,这里我觉得有个问题,因为数组每个项的初值为0.,当第一次使用该项对应的页表项被用于映射时,kmap使得数组该项值加1,变为1,此时分明是有内核成分在使用该页表项,但是根据开始的论述,此时该页表项没有用于映射!怎么可能呢?
作者: diandianlianyi 发布时间: 2010-11-21
在map_new_virtual( ) 里找到空项之后将相应数组元素值设为一,返回到kmap_high()时又将其值加1,所以有一个人使用数组相应元素值为2.
这样安排大概是为了优化对TLB的使用,即尽量延迟删除页映射(及相应TLB项).
复制代码
if ( !vaddr)只会在第一次映射该page frame时进去.一旦进去了,map_new_virtual会将其在pkmap_count中的对应项设为1,并将映射关系写进hashtable.返回又将对应数组项加1.所以有一个人使用,pkmap_count里的对应值就为2.
如果第二次又有人映射这个page frame,由于page_address可以在hashtable找到映射关系,vaddr是有效值,不会进入if ,pkmap_count里对应项值再加1.
删除映射的时候,仅仅将pkmap_count里对应项值减一.假设只有一个人使用之,本来可以马上解除映射并flush tlb,但这里尽量延迟做这件事.pkmap_count里为1的项都是这种情况.这时,映射依然有效,hashtable中依然有其映射记录,tlb中依然有其映射缓存.映射其它page frame时会跳过这些地址.这样做就是期待同样的page frame再一次被映射,由于hashtable中的记录未被删除,同样的page frame再度被映射时还是会跳过那个if (虽然从逻辑上来看映射已经被解除了),tlb中的项还可以继续用,这就达到了优化作用.
但不可能一直这样等待,总会发生虚拟地址用完的情况,这时就放弃等待,扫描整个pkmap_count,把其中值为1的项置0,删除hasntable中的记录,flush对应的tlb项,此时才算是真正解除了映射.所以,形式上解除映射的kunmap_high还有一个任务是看有没有进程在等待使用虚拟地址,有的话就将其唤醒.当然它们还是会先从pkmap_count中值为0的项开始找起,但最终会发现无可用项,于是调用flush_all_zero_pkmaps( )清除那些pkmap_count值为1的项.
这样安排大概是为了优化对TLB的使用,即尽量延迟删除页映射(及相应TLB项).
- void * kmap_high(struct page * page)
- {
- unsigned long vaddr;
- spin_lock(&kmap_lock);
- vaddr = (unsigned long) page_address(page);
- if (!vaddr)
- vaddr = map_new_virtual(page);
- pkmap_count[(vaddr-PKMAP_BASE) >> PAGE_SHIFT]++;
- spin_unlock(&kmap_lock);
- return (void *) vaddr;
- }
如果第二次又有人映射这个page frame,由于page_address可以在hashtable找到映射关系,vaddr是有效值,不会进入if ,pkmap_count里对应项值再加1.
删除映射的时候,仅仅将pkmap_count里对应项值减一.假设只有一个人使用之,本来可以马上解除映射并flush tlb,但这里尽量延迟做这件事.pkmap_count里为1的项都是这种情况.这时,映射依然有效,hashtable中依然有其映射记录,tlb中依然有其映射缓存.映射其它page frame时会跳过这些地址.这样做就是期待同样的page frame再一次被映射,由于hashtable中的记录未被删除,同样的page frame再度被映射时还是会跳过那个if (虽然从逻辑上来看映射已经被解除了),tlb中的项还可以继续用,这就达到了优化作用.
但不可能一直这样等待,总会发生虚拟地址用完的情况,这时就放弃等待,扫描整个pkmap_count,把其中值为1的项置0,删除hasntable中的记录,flush对应的tlb项,此时才算是真正解除了映射.所以,形式上解除映射的kunmap_high还有一个任务是看有没有进程在等待使用虚拟地址,有的话就将其唤醒.当然它们还是会先从pkmap_count中值为0的项开始找起,但最终会发现无可用项,于是调用flush_all_zero_pkmaps( )清除那些pkmap_count值为1的项.
作者: tempname2 发布时间: 2010-11-21
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28