Linux 中 RISC-V 的 mmap 的问题
Yangyu Chen目前RISC-V Linux的mmap出现了一个和x86/arm都不一样的行为,我提交了一个patch希望得到一些Linux Kernel开发者声援,比较希望得到关注尽快合并进6.8 Kernel,否则可能随着sv48/sv57的机器越来越普及,rv的软件移植会带来一些灾难问题,也会影响一些内存需求较大的软件在RISC-V平台上的使用。
之前在linux v6.6的时候有人交了一个patch希望把rv上的mmap默认返回47bit以内的虚拟地址空间,因为一些JIT翻译的应用可能使用虚拟地址指针的高位用于flag的存储,以确保这些指针可以被原子地修改,而很长的时间x86上虚拟地址空间一直都只有47bit,所以很多软件一直存在这个assumption。
这个出发点非常好,目前的linux kernel在x86的五级页表和arm的57/52bit虚拟地址空间上也是这么做的。
然而之前这个patch夹带了一个私货,就是把mmap时的hint地址当做了分配的虚拟地址的上界,导致用户态软件原先把hint address当做kernel应该在某个地址创建映射的规则被打破,与mmap的manpage描述也不符,且我在邮件列表里参与了大量讨论发现这个是作者有意为之。而x86和arm上的行为则是看hint address是否超过了47/48bit,若是,则开启更大的地址空间,否则只分配在47/48bit内。
这样做法的导致软件按照manpage里所述的mmap规则无法在没有MAP_FIXED情况下在sv57创建映射,而如果软件还未probe机器是否支持sv57时,如果按照这样的设计,在不支持的机器上都需要mmap syscall两次才能走到fallback path,且如果软件有指定某个虚拟地址才能达到最佳性能的需求时,目前这个特殊的hint address做法会导致这样的软件永远走fallback path导致性能损失。
更糟糕的是,原patch作者标题写的限制到sv48(47bit userspace),kernel document也写的sv48,但代码却是写的限制到sv39,但现在sv48的机器已经越来越多了。且之前的patch在没有任何reviewed by的情况下就被maintainer合并了,我认为这个行为有一些草率。
还有一个很重要的移除这个特殊hint address的reason是,目前的行为是如果hint address >= BIT(47)使用sv48,而不是>= BIT(38),即sv39无法放的时候使用sv48,这样的行为导致用户态应用必须知道这个ISA的页表有几种类型才能选择出最合适的映射地址,但我认为这不是userspace应该考虑的事情,毕竟软件可以被交叉编译到任何平台,不应该强求软件开发者知道这个平台有多少级页表,分别有多少位的地址空间。
邮件列表里已经留下了大量的吵架记录,大家可以搜索我的邮箱cyy@cyyself.name查看整个thread。但目前只有两个人吵架,我比较希望这个事情得到关注,尽量提供一些其他观点,无论在我这面还是在我的对立面,讨论一下userspace应该如何处理这样的情况,否则我认为目前这样和其他ISA完全不同的行为会带来很严重的软件适配灾难。
https://lore.kernel.org/linux-riscv/tencent_B2D0435BC011135736262764B511994F4805@qq.com/