Chr*_*ris 7 c caching linux-kernel tlb
在linux内核中,我编写了类似于copy_page_range
(mm/memory.c)的代码,因此通过COW优化将内存从一个进程复制到另一个进程.目标和源地址可以抵消PAGE_SIZE
,COW仍然有效.但是,我注意到,在用户程序中,当我从相同的源地址复制到不同的目标地址时,TLB似乎没有被正确刷新.在高级别,我的用户级代码执行以下操作(我一次只复制一页,我的机器上的0x1000字节):
SRC = 0x20000000
page1
).page1
).page2
.此时,应存在两个单独的页面:SRC 0x20000000 page2
DST 0x30000000 page1
DST 0x30001000page2
我发现在第3步,当我在src 0x20000000中写入不同的内容时,不会生成页面错误.检查时,实际页面映射为:SRC 0x20000000 page1
DST 0x30000000 page1
DST 0x30001000page1
在我的代码中,如果我调用flush_tlb_page
并传递源地址,则用户代码将按预期使用正确的页面映射.所以我确信我没有正确维护TLB.在copy_page_range
,内核调用mmu_notifier_invalidate_range_start/end
之前和之后它改变页表.我正在做完全相同的事情,并进行了双重检查我确实传递了正确的struct_mm和地址mmu_notifier_invalidate_range_start/end
.这个功能不能处理冲洗tlb吗?
好了,从字面上我打完这个,我查了一下dup_mmap
,意识到的主要调用者copy_page_range
,dup_mmap
(核心/ fork.c),调用flush_tlb_mm
.我猜我应该打电话flush_cache_range
和flush_tlb_range
之前和之后我的内核代码.它是否正确?到底是mmu_notifier_invalidate_range_start/end
做什么的?
是的,如果您正在执行更改页表的操作,则需要确保根据需要使TLB无效.
mmu_notifier_invalidate_range_start/end
只是调用MMU通知程序挂钩; 这些挂钩只存在,以便在发生TLB失效时可以告知其他内核代码.设置MMU通知程序的唯一地方是
但几乎任何你调用MMU通知程序钩子的地方,如果内核还没有为你做这个,你也应该调用TLB击落功能.
归档时间: |
|
查看次数: |
2153 次 |
最近记录: |