Skip to content

Commit 8ccd798

Browse files
authored
[release/10.0] Fix Linux madvise() advice values (#128605)
Backport of #126966 to release/10.0 ## Customer Impact - [x] Customer reported - [ ] Found internally `VirtualReset` in GC was combining `MADV_FREE` (8) and `MADV_DONTDUMP` (16) via bitwise OR and passing the result (24) to a single `madvise` call. `madvise` takes a single advice constant — not a bitmask — so this was either rejected as `EINVAL` (kernels < 5.18) or silently matched `MADV_DONTNEED_LOCKED` (kernels ≥ 5.18), a completely different operation. ## Regression - [x] Yes - introduced in .NET 9 by #95643 (an optimization to reduce syscall count). - [ ] No ## Testing CI tests, local testing using targeted repro app from the customer, GC tests ## Risk Low. It is a simple targeted fix that just makes two calls to `madvise` with correct arguments where we were making one call with a combination of those values that had no effect or was outright wrong.
1 parent cb36ff8 commit 8ccd798

1 file changed

Lines changed: 5 additions & 16 deletions

File tree

src/coreclr/gc/unix/gcenv.unix.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -741,31 +741,20 @@ bool GCToOSInterface::VirtualReset(void * address, size_t size, bool unlock)
741741
{
742742
int st = EINVAL;
743743

744-
#if defined(MADV_DONTDUMP) || defined(HAVE_MADV_FREE)
745-
746-
int madviseFlags = 0;
747-
748744
#ifdef MADV_DONTDUMP
749745
// Do not include reset memory in coredump.
750-
madviseFlags |= MADV_DONTDUMP;
746+
st = madvise(address, size, MADV_DONTDUMP);
751747
#endif
752748

753-
#ifdef HAVE_MADV_FREE
749+
#ifdef MADV_FREE
754750
// Tell the kernel that the application doesn't need the pages in the range.
755751
// Freeing the pages can be delayed until a memory pressure occurs.
756-
madviseFlags |= MADV_FREE;
757-
#endif
758-
759-
st = madvise(address, size, madviseFlags);
760-
761-
#endif //defined(MADV_DONTDUMP) || defined(HAVE_MADV_FREE)
762-
763-
#if defined(HAVE_POSIX_MADVISE) && !defined(MADV_DONTDUMP)
752+
st = madvise(address, size, MADV_FREE);
753+
#elif defined(HAVE_POSIX_MADVISE)
764754
// DONTNEED is the nearest posix equivalent of FREE.
765755
// Prefer FREE as, since glibc2.6 DONTNEED is a nop.
766756
st = posix_madvise(address, size, POSIX_MADV_DONTNEED);
767-
768-
#endif //defined(HAVE_POSIX_MADVISE) && !defined(MADV_DONTDUMP)
757+
#endif // MADV_FREE
769758

770759
return (st == 0);
771760
}

0 commit comments

Comments
 (0)