Skip to content

Unable to obtain aligned memory on RISC-V systems with an SV39 MMU #939

@orlitzky

Description

@orlitzky

(moved from the comments on #640)

RISC-V has several different memory layouts:

https://www.kernel.org/doc/html/latest/arch/riscv/vm-layout.html

With the SV39 layout, the user-addressable range ends at 256GiB, but when mimalloc tries to obtain an aligned chunk, it does so at 2TiB. As a result, the mmap() can fail to return an aligned chunk, and usually will. When that happens, a warning is raised, and mimalloc falls back to overallocation:

mimalloc: unable to directly request hinted aligned OS memory (error: 2 (0x02), size: 0x2000000 bytes, alignment: 0x2000000, hint address: 0x050ADE000000)
mimalloc: warning: unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x2000000 bytes, address: 0x003F81800000, alignment: 0x2000000, commit: 1)

I have verified this with a small program on a Milk-V Pioneer Box:

$ ./a.out 
mmaping 1GiB at 0x40000000 (1 GiB)... YES (0x40000000)
mmaping 1GiB at 0x80000000 (2 GiB)... YES (0x80000000)
...
mmaping 1GiB at 0x3f40000000 (253 GiB)... YES (0x3f40000000)
mmaping 1GiB at 0x3f80000000 (254 GiB)... NO (File exists)
mmaping 1GiB at 0x3fc0000000 (255 GiB)... NO (File exists)
mmaping 1GiB at 0x4000000000 (256 GiB)... NO (Out of memory)
mmaping 1GiB at 0x4040000000 (257 GiB)... NO (Out of memory)
mmaping 1GiB at 0x4080000000 (258 GiB)... NO (Out of memory)
mmaping 1GiB at 0x40c0000000 (259 GiB)... NO (Out of memory)
mmaping 1GiB at 0x4100000000 (260 GiB)... NO (Out of memory)
mmaping 1GiB at 0x4140000000 (261 GiB)... NO (Out of memory)
mmaping 1GiB at 0x4180000000 (262 GiB)... NO (Out of memory)
mmaping 1GiB at 0x41c0000000 (263 GiB)... NO (Out of memory)
mmaping 1GiB at 0x4200000000 (264 GiB)... NO (Out of memory)

The fallback still works, but we waste a lot of time trying to obtain aligned memory when we know it will fail with high probability. These machines are still rare, but probably not for long. Maybe there's a way to work around this? I've had some luck using the top 128GiB of my space for mmap, but I don't know how reliable that will be in general. If nothing else, I think it would be better to just overallocate on these machines?

And finally, is there a reliable way to detect the SV39 layout? A build flag would be an easy first step, but detecting it automatically would be nicer for end users. I have one of these and didn't know about the memory layout problem until now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions