jh7110的MMU TLB是否缓存无效PTE?是否支持ASID?
ASID那个已经回答了,缓存无效PTE的话,标准是允许的,sifive的手册没有明确说明,但是我认为大意是不会的,而且标准也不推荐这样做。但是以防万一的话,OS确实是需要sfence.vma的。现在标准有个Svvptc扩展,有了这个之后就不用担心缓存无效PTE的问题了。如果真的要省略掉那些个sfence.vma的话,在u74上面应该是没问题的,不过我觉得还是正确性比较重要,性能应该不差这几个sfense.vma。
目前,开发过程中发现,缺页映射以后必须刷tlb才生效。你可以测试一下缺页映射,看看不刷tlb行不行。
确定修改的是non-leaf PTE吗?确定是否原来是non-valid, 然后修改之后是valid?
映射了leaf pte(sv39,最后一级页表的pte),确定原来的是无效的。修改完,不刷tlb,返回U模式,立马触发缺页异常;如果刷tlb就可以了。
首先排除一下是否只做了刷tlb的动作,因为sifive U74没有Svadu扩展,所以A/D 位也要软件维护。如果只设置V不设置A也是会缺页异常的。另外如果确认只是省略了tlb刷新的话,可以让它发生异常,然后在处理异常的时候再刷。
这个是sifive手册原文
For the special cases of increasing the permissions on a leaf PTE and changing an invalid PTE to a valid leaf, software may choose to execute the SFENCE.VMA lazily After modifying the PTE but before executing SFENCE.VMA, either the new or old permissions will be used. In the latter case, a page fault exception might occur, at which point software should execute SFENCE.VMA in accordance with the previous bullet point.
但如果每次都会异常的话,效率真的会很低。而且linux里面因为要避开CIP-1200这个bug,每个sfence.vma都强制刷掉整个tlb,确实开销很大。
before map_page vaddr:0x0000000000eb7000 pt[pt_index]=0x0000000000000000
after map_page vaddr:0x0000000000eb7000 pt[pt_index]=0x000000001109f8d7
before map_page vaddr:0x00000000016b6000 pt[pt_index]=0x0000000000000000
after map_page vaddr:0x00000000016b6000 pt[pt_index]=0x000000001109fcd7
测试了一下两个地址,映射的时候默认把D和A位设置1了,但是必须要刷tlb,不然不行。
这句话还是有点不太理解,感觉暗指invalid pte要会在tlb中缓存。
Linux里每次缺页以后全刷(四个核)吗?不支持基于地址的刷tlb吗?
我没有详细调试过,应该是非必要不刷新。而且每个核心的TLB是独立的,ASID也是独立的(标准现在写的比较清楚了)
If a hart employs an address translation cache, that cache must appear to be private to that hart. In particular, the meaning of an ASID is local to a hart; software may choose to use the same ASID to refer to different address spaces on different harts.
从jh7110的角度来说,有两个大问题 1.没有ASID,2.核心有CIP-1200这个bug ,导致每个flush 都是flush 掉整个TLB,参考:
https://lore.kernel.org/lkml/20240229232211.161961-8-samuel.holland@sifive.com/
如果再加上连invalid PTE都要flush ,那效率确实低。jh7110/u74比较卡很可能和这个有关系,之后有空真的要profile 一下