-
Notifications
You must be signed in to change notification settings - Fork 883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to obtain aligned memory on RISC-V systems with an SV39 MMU #939
Comments
Ah, very interesting. Yes, that is definitely it. Hmm, the aligned hint is behind a If you find a way to detect the address space bits (RV39) at build time (or run time) let me know :-) |
It looks like the future on Linux is the RISC-V hardware probe interface that provides exactly what we need, In the meantime,
should do the trick. That works in 6.1.x and up, unless they change the format of |
I don't write much CMake, but this looks like a passable detection mechanism: diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcfe91d8..20b22c09 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -343,6 +343,16 @@ if(MINGW)
add_definitions(-D_WIN32_WINNT=0x600)
endif()
+# Check /proc/cpuinfo for an SV39 MMU and define a constant if one is
+# found. We will want to skip the aligned hinting in that case.
+if (EXISTS /proc/cpuinfo)
+ file(STRINGS /proc/cpuinfo mi_sv39_mmu REGEX "^mmu[ \t]+:[ \t]+sv39$")
+ if (mi_sv39_mmu)
+ MESSAGE( STATUS "SV39 MMU detected" )
+ list(APPEND mi_defines MI_SV39_MMU=1)
+ endif()
+endif()
+
# extra needed libraries
# we prefer -l<lib> test over `find_library` as sometimes core libraries But now I notice that an aligned allocation is still attempted (and then freed, usually) even when we don't have a hint. If static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** base, mi_stats_t* stats) {
...
// try first with a hint (this will be aligned directly on Win 10+ or BSD)
void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, is_large, is_zero, stats);
if (p == NULL) return NULL; But the implementation of the UNIX prim alloc, at least, is to try the hint that is not going to work because's it's If I undestand correctly this should already be happening on 32-bit systems, since it's the non-64-bit branch that I'm trying to hijack for my own purposes here. |
(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:I have verified this with a small program on a Milk-V Pioneer Box:
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.
The text was updated successfully, but these errors were encountered: