It is actually a useful, well-designed API. It's just a replacement for the legacy /dev/shm API. The unpin/pin features are quite useful too. You could easily set it up so that Chromium/Firefox would use it.
It just doesn't make sense that you can only do unpin/pin for ashmem.
Conversation
You should be able to just do that with regular anonymous memory. Android avoids implementing things downstream now though. They got all the mandatory kernel changes upstream and only have optional ones downstream. Many of those are quite useful though, like naming anon VMAs.
1
1
So /proc/PID/maps output on Android is a lot more useful because it's possible for everything making anonymous mappings to label the mappings. It's used by OS tooling to figure out what's using memory. It also cleverly uses page APIs to divide up the blame for shared memory.
1
1
For example, this is the GrapheneOS /proc/1/maps output on a debug build:
gist.github.com/thestinger/28c
The [anon:name] labelling is the downstream VMA naming feature. I find it useful enough that in a debug build of the OS hardened_malloc makes very good use of it.
2
i’m curious as to why you have 128KiB bins, at that point surely mmap is equally efficient, no?
1
It's optional to have slab allocation size classes above 16k. The size classes are defined here:
github.com/GrapheneOS/har
It's significantly faster than more direct use of mappings with all the optional security features off. Much less with them enabled, but it has advantages.
1
1
It needs to go up to 16k because the size classes only start incrementing by 4096 bytes after that point.
It has an isolated region for each size class with address space never reused between them. There's a fair bit of code allocating fixed-size 64k / 128k allocations, etc.
1
1
Normally, everything above 16k is guaranteed to have guard regions on both sides whether or not those extended slab allocation size classes are used. It only uses 1 slot for slabs above 16k and by default every other slab is skipped and left as a PROT_NONE guard region.
1
1
Large allocations above 16k/128k (depending on config) get randomly sized guard regions on both sides (mmap PROT_NONE, mprotect inner usable area to PROT_READ|PROT_WRITE) and get quarantined on free (overwritten with mmap MAP_FIXED PROT_NONE) with oldest in quarantine unmapped.
1
1
Current feeling is that the slab allocation security properties are better due to having a dedicated region per size class. The large allocations aren't only in the same overall mmap region outside the massive reserved area for slabs, but they're also mixed with dlopen libs, etc.
1
1
Hard to balance these things. If you turn off all optional security features (slab allocation quarantines, write after free check and zero-on-free in particular) hardened_malloc is quite fast other than intentional lack of thread cache. Always trying to figure out better balance.

