This is an archive of the discontinued LLVM Phabricator instance.

[scudo] Pass MapPlatformData to all map/unmap calls
Needs RevisionPublic

Authored by ddcc on Jul 7 2022, 1:24 PM.

Details

Summary

This modifies all remaining map/unmap calls in scudo so that MapPlatformData is always passed.

Diff Detail

Event Timeline

ddcc created this revision.Jul 7 2022, 1:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 7 2022, 1:24 PM
ddcc requested review of this revision.Jul 7 2022, 1:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 7 2022, 1:24 PM
Herald added a subscriber: Restricted Project. · View Herald Transcript
ddcc added a comment.Jul 7 2022, 1:26 PM

Not sure if this approach is correct since we're not using the primary32.h allocator at all except during testing, but I'm sending it along to get some feedback and in case it's useful.

cryptoad added inline comments.Jul 7 2022, 2:02 PM
compiler-rt/lib/scudo/standalone/primary32.h
518

You might want to be careful with an array of NumRegions elements as this can become real large real fast.
On Linux for now this isn't a problem as the MapPlatformData is empty, and Fuchsia doesn't support the 32-bit primary.
But this is risky in terms of memory footprint.

ddcc added inline comments.Jul 7 2022, 5:47 PM
compiler-rt/lib/scudo/standalone/primary32.h
518

Yeah, it does look to be a lot of overhead. I'm not using primary32.h at all except in testing, but my platform does require MapPlatformData be passed into all memory mapping system calls. I could just disable primary32.h in testing, but then building that header file would just be broken.

cryptoad added inline comments.Jul 8 2022, 10:14 AM
compiler-rt/lib/scudo/standalone/primary32.h
518

A side point: I might be wrong but I think StashMapData redundant as the map data of stashed region could be stored in the overall RegionMapData.

Can you judge from your tests/compilation if the sizes of the binaries change at all?

ddcc added inline comments.Jul 8 2022, 3:29 PM
compiler-rt/lib/scudo/standalone/primary32.h
518

I don't have an exact binary size change because we combine multiple tests into a single (64-bit) binary, but we define MapPlatformData to be uintptr_t[2], and for TestConfig1 from primary_test.cpp that uses SizeClassAllocator32, it seems to have a RegionSize of 0x40000. So RegionSize * sizeof(MapPlatformData) gives at least 4194304 bytes.

I'm not super familiar with this code, but when I implemented this originally, it wasn't immediately obvious. unmapTestOnly first unmaps everything in the RegionsStash, so I'd need the corresponding PlatformMapData object for each entry. From reading allocateRegionSlow and allocateRegion, it seems like entries in the stash should always be duplicate of an entry in StashMapData, since if allocateRegionSlow succeeds in placing a new entry in RegionsStash, it should always be able to pass it up to allocateRegion, which adds it to PossibleRegions? But is it possible to race between unmapTestOnly and allocateRegion/allocateRegionSlow? The former never seems to take RegionsStashMutex, so I don't know exactly what the mutex covers.

vitalybuka requested changes to this revision.Dec 7 2022, 1:44 PM

Is this still relevant?

This revision now requires changes to proceed.Dec 7 2022, 1:44 PM
ddcc added a comment.Dec 9 2022, 5:34 PM

Yes, we need the MapPlatformData structure to always be allocated, though we only run the primary32.h allocator in tests and not in practice, so there shouldn't be much impact.