Nathaniel Wesley Filardo fb776da909 WIP: BatchIt (#677)
* Rename dealloc_local_object_slower to _meta

Unlike its brethren, `dealloc_local_object` and
`dealloc_local_object_slow`, the `dealloc_local_object_slower` method
does not take a pointer to free space.  Make this slightly more apparent
by renaming it and adding some commentary to both definition and call
site.

* corealloc: get meta in dealloc_local_object

Make both _fast() and _slow() arms take the meta as an argument; _meta()
already did.

* Introduce RemoteMessage structure

Plumb its use around remoteallocator and remotecache

* NFC: Plumb metadata to remotecache dealloc

* Initial steps in batched remote messages

This prepares the recipient to process a batched message.

* Initial dealloc-side batching machinery

Exercise recipient machinery by having the senders collect adjacent frees to
the same slab into a batch.

* Match free batch keying to slab freelist keying

* freelist: add append_segment

* SlabMetadata: machinery for returning multiple objects

This might involve multiple (I think at most two, at the moment) transitions in
the slab lifecycle state machine.  Towards that end, return indicators to the
caller that the slow path must be taken and how many objects of the original
set have not yet been counted as returned.

* corealloc: operate ring-at-a-time on remote queues

* RemoteCache associative cache of rings

* RemoteCache: N-set caching

* Initial CHERI support for free rings

* Matt's fix for slow-path codegen

* Try: remotecache: don't store allocator IDs

We can, as Matt so kindly reminds me, go get them from the pagemap.  Since we
need this value only when closing a ring, the read from over there is probably
not very onerous.  (We could also get the slab pointer from an object in the
ring, but we need that whenever inserting into the cache, so it's probably more
sensible to store that locally?)

* Make BatchIt optional

Move ring set bits and associativity knobs to allocconfig and expose them via
CMake.  If associtivity is zero, use non-batched implementations of the
`RemoteMessage` and `RemoteDeallocCacheBatching` classes.

By default, kick BatchIt on when we have enough room in the minimum allocation
size to do it.  Exactly how much space is enough is a function of which
mitigations we have enabled and whether or not we are compiling with C++20.

This commit reverts the change to `MIN_ALLOC_SIZE` made in "Introduce
RemoteMessage structure" now that we have multiple types, and zies, of
remote messages to choose from.

* RemoteDeallocCacheBatching: store metas as address

There's no need for a full pointer here, it'd just make the structure larger on
CHERI.

* NFC: plumb entropy from LocalAlloc to BatchIt

* BatchIt random eviction

In order not to thwart `mitigations(random_preserve)` too much, if it's on in
combination with BatchIt, roll the dice every time we append to a batch to
decide if we should stochastically evict this batch.  By increasing the number
of batches, we allow the recipient allocator increased opportunity to randomly
stripe batches across the two `freelist::Builder` segments associated with each
slab.

---------

Co-authored-by: Nathaniel Wesley Filardo <nfilardo@microsoft.com>
Co-authored-by: Matthew Parkinson <mattpark@microsoft.com>
2024-09-23 19:18:09 +01:00
2024-09-10 10:07:28 -04:00
2023-04-19 17:06:55 +01:00
2024-09-23 19:18:09 +01:00
2020-02-06 09:09:32 +00:00
2019-04-30 09:46:10 +01:00
2021-11-17 16:02:47 +00:00
2024-09-23 19:18:09 +01:00
2019-01-09 06:05:57 -08:00
2023-07-17 15:09:36 +01:00
2020-02-28 09:03:41 +00:00
2019-05-23 15:13:47 +01:00

snmalloc

snmalloc is a high-performance allocator. snmalloc can be used directly in a project as a header-only C++ library, it can be LD_PRELOADed on Elf platforms (e.g. Linux, BSD), and there is a crate to use it from Rust.

Its key design features are:

  • Memory that is freed by the same thread that allocated it does not require any synchronising operations.
  • Freeing memory in a different thread to initially allocated it, does not take any locks and instead uses a novel message passing scheme to return the memory to the original allocator, where it is recycled. This enables 1000s of remote deallocations to be performed with only a single atomic operation enabling great scaling with core count.
  • The allocator uses large ranges of pages to reduce the amount of meta-data required.
  • The fast paths are highly optimised with just two branches on the fast path for malloc (On Linux compiled with Clang).
  • The platform dependencies are abstracted away to enable porting to other platforms.

snmalloc's design is particular well suited to the following two difficult scenarios that can be problematic for other allocators:

  • Allocations on one thread are freed by a different thread
  • Deallocations occur in large batches

Both of these can cause massive reductions in performance of other allocators, but do not for snmalloc.

The implementation of snmalloc has evolved significantly since the initial paper. The mechanism for returning memory to remote threads has remained, but most of the meta-data layout has changed. We recommend you read docs/security to find out about the current design, and if you want to dive into the code docs/AddressSpace.md provides a good overview of the allocation and deallocation paths.

snmalloc CI snmalloc CI for Morello

Hardening

There is a hardened version of snmalloc, it contains

  • Randomisation of the allocations' relative locations,
  • Most meta-data is stored separately from allocations, and is protected with guard pages,
  • All in-band meta-data is protected with a novel encoding that can detect corruption, and
  • Provides a memcpy that automatically checks the bounds relative to the underlying malloc.

A more comprehensive write up is in docs/security.

Further documentation

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Description
No description provided
Readme MIT 6.1 MiB
Languages
C++ 95.4%
CMake 3.6%
C 0.5%
Starlark 0.4%
Dockerfile 0.1%