[Git][ghc/ghc][master] 2 commits: rts/posix: Enforce iteration limit on heap reservation logic

Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ff1650c9 by Ben Gamari at 2025-10-08T08:38:07-04:00 rts/posix: Enforce iteration limit on heap reservation logic Previously we could loop indefinitely when attempting to get an address space reservation for our heap. Limit the logic to 8 iterations to ensure we instead issue a reasonable error message. Addresses #26151. - - - - - 01844557 by Ben Gamari at 2025-10-08T08:38:07-04:00 rts/posix: Hold on to low reservations when reserving heap Previously when the OS gave us an address space reservation in low memory we would immediately release it and try again. However, on some platforms this meant that we would get the same allocation again in the next iteration (since mmap's `hint` argument is just that, a hint). Instead we now hold on to low reservations until we have found a suitable heap reservation. Fixes #26151. - - - - - 1 changed file: - rts/posix/OSMem.c Changes: ===================================== rts/posix/OSMem.c ===================================== @@ -585,8 +585,14 @@ void *osReserveHeapMemory(void *startAddressPtr, W_ *len) } #endif + const int MAX_ATTEMPTS = 256; + void *bad_allocs[MAX_ATTEMPTS]; + size_t bad_alloc_lens[MAX_ATTEMPTS]; + memset(bad_allocs, 0, sizeof(void*) * MAX_ATTEMPTS); + memset(bad_alloc_lens, 0, sizeof(size_t) * MAX_ATTEMPTS); + attempt = 0; - while (1) { + while (attempt < MAX_ATTEMPTS) { *len &= ~MBLOCK_MASK; if (*len < MBLOCK_SIZE) { @@ -611,18 +617,35 @@ void *osReserveHeapMemory(void *startAddressPtr, W_ *len) } else if ((W_)at >= minimumAddress) { // Success! We were given a block of memory starting above the 8 GB // mark, which is what we were looking for. - break; } else { // We got addressing space but it wasn't above the 8GB mark. - // Try again. - if (munmap(at, *len) < 0) { - sysErrorBelch("unable to release reserved heap"); + // Free any portion *above* 8GB and hang on to the rest to increase + // the likelihood that we get a suitable allocation next iteration. + uintptr_t end = (W_) at + *len; + bad_allocs[attempt] = at; + if (end > minimumAddress) { + if (munmap((void *) minimumAddress, end - minimumAddress) < 0) { + sysErrorBelch("unable to release high portion of low memory reservation"); + } + bad_alloc_lens[attempt] = minimumAddress - (W_) at; + } else { + bad_alloc_lens[attempt] = *len; } } attempt++; } + for (int i=0; i < MAX_ATTEMPTS; i++) { + if (bad_allocs[i] != NULL && munmap(bad_allocs[i], bad_alloc_lens[i]) < 0) { + sysErrorBelch("unable to release reserved heap"); + } + } + + if (at == NULL) { + sysErrorBelch("failed to reserve heap memory"); + } + return at; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7adfed2e011290abc8f20ce8202614... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7adfed2e011290abc8f20ce8202614... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Marge Bot (@marge-bot)