Commit Graph

498 Commits

Author SHA1 Message Date
Nathaniel Filardo
cbab7a3455 NFC: pointer_offset* functions always return void*
This requires that the caller perform the cast on the output rather than the
input, which is a little closer to the truth.  Shuffle some casts into the right
position.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
f295a3f191 alloc: de-static external_pointer
Like alloc_size, this will require amplification internally.

This patch also restores performance to the status quo ante; Clang can once
again see enough to generate the same code as it did before de-static-ing
alloc_size.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
1042fc908a alloc: de-static alloc_size
We're going to need to amplify the pointer and that's going to require access
to our AddressSpaceManager, which we only get non-statically through our
LargeAlloc.

This patch unto itself makes the world slower, perhaps because Clang can't see
the certainty of aliasing of the static and non-static paths to the same
structure.  However, when we also de-static external_pointer, that goes away and
things return to the status quo ante.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
c9588655b0 NFC: alloc_size s/size/chunkmap_slab_kind/
While here, SNMALLOC_ASSERT() that large allocs end up with sensible slab kind
values.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
08344cfa94 NFC: external_pointer s/size/chunkmap_slab_kind/
While here, SNMALLOC_ASSERT() that large allocs end up with sensible slab kind
values.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
4f6cf8cb40 NFC: make Slab, Mediumslab interfaces static
Going forward, this gives us explicit pointers with which to carry bounds
annotations.  Otherwise, assuming AuthPtr overloads operator->, a OOP-style call
like

    AuthPtr<Slab, Bounds> slab;
    slab->foo()

will create a `Slab* this` within the body of `Slab::foo`, leaving it unable to
see or propagate the Bounds annotation.  If it invokes callees that expect
`AuthPtr` arguments, it will therefore have to fabricate new `Bounds` unsafely.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
49fefc3f83 NFC: introduce SlabNext type for intra-small-slab free pointers
Mostly cosmetic, but eliminates some void*-s and makes intention clearer.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
db0ca64ff3 NFC: Add an AAL Concept, too
While here, pull out some constants to their own header.  Eventually we'll
want to match on AalFeatures in the AAL Concept.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
a6d18f842a NFC: Mark AAL methods noexcept 2021-03-16 09:29:19 +00:00
Nathaniel Filardo
263e9562c0 NFC: Feed Pagemap its primitive allocator as template arg
This will let us use Pagemaps further down the dependency stack (specifically,
we're going to want a Pagemap inside the AddressSpaceManager) by letting us
manually tie the knot rather than rely on GlobalVirtual and
default_memory_provider() being defined by the time we want a Pagemap.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
83b72722cf NFC: Split InvalidPointer out of ds/dllist.h
This lets us use Pagemaps without requiring dllists in scope
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
addd98e6db NFC: Introduce Purpose parameter for PageMap wrappers
Presently, GlobalPagemap and ExternalPagemap discriminate only by type.  If it
ever happened that multiple PageMap consumers instantiated the same type using
these wrapper, they'd be conflated in the symbol table.  Therefore, add an
optional Purpose parameter that will be expanded into the symbols (but serves no
other purpose).
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
6250428c3d NFC: Further disentangle chunkmap and pagemap
- Make GlobalPagemapTemplate and ExternalGlobalPagemap generic in the type of
  the pagemap they're encapsulating.

  We're going to want to use these for other kinds of pagemaps in the near
  future.

- Rename snmalloc_pagemap_global_get to snmalloc_chunkmap_global_get.

- Rename GlobalPagemap to GlobalChunkmap.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
8da12f5af8 NFC: tests: size_t and uintptr_t are not interchangable 2021-03-16 09:29:19 +00:00
Nathaniel Filardo
960733099b POSIX PAL: reset errno on failing mmap()s for zeroing
We try, if the region to be zeroed is sufficiently aligned, to use mmap to swap
out pages for zeros.
2021-03-16 09:29:19 +00:00
Matthew Parkinson
59edf294d0 Move link out of object space.
The link object was previously stored in a disused object.  This is
good for reducing meta-data, but if we want to reduce the meta-data
corruption potential, then this is not a good design choice.

This commit moves it into the Metaslab.
2021-03-15 13:28:03 +00:00
Matthew Parkinson
e7dce55f19 Move is_start_of_object into Metaslab. 2021-03-15 13:28:03 +00:00
Matthew Parkinson
1d12e34b9f Fix for Mac OS X 10.14
The dllist was able to call delete during a destructor if a template
flag was set.  This flag is never set in snmalloc, and was included
to enable reuse in another project.  This was triggering an error on
older mac builds.

This PR calls a templated function when the DLList is destructed.  Hence
other projects can specify the `delete` behaviour if required.
2021-03-09 15:07:21 +00:00
David Carlier
35346e72c3 Making pal_noalloc self reliant and not depending on inclusion order anymore. 2021-03-03 18:07:40 +00:00
ryancinsight
7b8cac7931 Add to rust surface standard C style API (#290)
The existing snmalloc Rust surface only exposes the calls required by the Rust global allocator.
As Rust knows the size of objects it provides those to the allocator, which snmalloc takes advantage of.

This PR, exposes the standard C API for allocation as well with the prefix `sn_`, so that unsafe code can potentially take advantage of using the same allocator.
2021-03-03 09:58:17 +00:00
Matthew Parkinson
a554703151 Update slowalloc.h 2021-03-03 09:02:02 +00:00
David Carlier
a1fc509a65 pal bsd aligned build fix due to the -Wconversion flag, it is expected
an integer.
2021-03-02 09:13:25 +00:00
Nathaniel Wesley Filardo
e1ba7cd592 Systematize validity checks on dealloc paths (#285)
Replace the generic check_size() calls with per-{small,medium,large} code paths,
which follow the progression...

* _unchecked: no validation has been performed; check the chunkmap and move
  to...

* _checked_chunkmap: the chunkmap indicates that this is the correct slab-type,
  and so we have reason to believe that our supposed Allocslab pointers are of
  the correct types.  Use those pointers to read the sizeclass and move to...

* _checked_sizeclass: additionally, the Allocslab metadata confirms that our
  sizeclass matches the expected value.  Check that we are at the start of an
  object and move to...

* _start: we now believe we have a pointer to the start of a live object.  On
  a sufficiently capable architecture, we will eventually atomically check that
  our pointer is not (scheduled to be) revoked (and/or not reversioned).  If
  this test passes, our prior pointer arithmetic and loads are justified
  (assuming correctness of the quarantine/revocation/reuse) machinery.

The size-less dealloc(void*) path by necessity reads the chunkmap and sizeclass
data itself and so there's no reason to re-validate; as such, it jumps directly
to the _okcmsc point.  Similarly, we assume that remote queues are full of
already validated objects, and so the remote handling paths continue to jump
further along even than the _start methods.
2021-03-02 09:11:33 +00:00
Nathaniel Filardo
6259457790 Add -Wconversion to clang builds
MSVC has strong opinions on implicit conversions as used in CI, while Clang both
locally and in CI has weaker opinions.  In an effort to avoid subsequent
roundtrips through CI, make clang more strict.  Adding -Wconversion definitely
increases the strength of clang's opinions, apparently to include frowning on
some that even MSVC considers OK, so go make explicit the current implicit
behavior.
2021-03-01 20:18:01 +00:00
Matthew Parkinson
8840b386bc Make LowMemoryNotification object allocated (#281)
* Make LowMemoryNotification object allocated

This makes a separate allocation for the callback object.  This makes
it easier for different callbacks to be used.

* Add reserve_with_leftover to address_space

The address_space now supports reserving for non-power of 2 allocations
and the space that is used for rounding up is retained by the
address_space.  This means that we can more tightly pack the allocators
internal objects.
2021-02-23 14:51:44 +00:00
David CARLIER
c082a331e2 POSIX_COMMIT_CHECKS adding for apple. (#284)
* POSIX_COMMIT_CHECKS adding for apple Intel
2021-02-23 14:51:02 +00:00
Matthew Parkinson
70e5f9653d Fix BSD usage of POSIX_COMMIT_CHECKS 2021-02-19 15:34:11 +00:00
David CARLIER
ee470c535e Second batch for Mac M1 (mainly) changes proposal to make the whole
work more realibly, in both mono and multi thread contexts.
2021-02-11 20:10:05 +00:00
Matthew Parkinson
e3b3596e32 Remove an undefined behaviour
The initialisation had an awkward sequence that used undefined
behaviour. This fixes this.
2021-02-09 20:17:27 +00:00
Nathaniel Filardo
023290664d NFC: Front "deallocating start of an object" tests
Confirm that the client has given dealloc() a start-of-object pointer before
that pointer propagates very far (esp., before it enters the remote queues).

As these tests are not free, structure the code so that future interfaces can
skip over them if there's reason to be sure we're at the start of an object.
(On CHERI, for example, one could imagine using sealed pointers.)

For architectures with SSM/MTE, immediately after this test we can update the
memory granule to guard against double-frees; leave TODOs in place.
2021-02-09 19:15:40 +00:00
David CARLIER
0a868484db Mac M1 fix (#278)
The actual code works fine on the usual mac Intel however, some failures
occurs with some unit tests on the ARM h/w when zero'ing page ranges.
2021-02-09 14:38:54 +00:00
Matthew Parkinson
a3660c4069 Update to use a more efficient power of 2 check. (#274) 2021-01-27 11:58:41 +00:00
David Chisnall
db3580a9d8 Small tweaks to make the sandbox mode happy.
Allow replacing the type of GlobalVirtual at compile time.
Make that type a friend of Pool so that it can allocate things.
2021-01-13 17:10:13 +00:00
David Chisnall
c33f355736 Fix the sandbox use case and add a test. (#269)
Summary of changes:

- Add a new PAL that doesn't allocate memory, which can be used with a
  memory provider that is pre-initialised with a range of memory.
- Add a `NoAllocation` PAL property so that the methods on a PAL that 
  doesn't support dynamically reserving address space will never be
  called and therefore don't need to be implemented.
- Slightly refactor the memory provider class so that it has a narrower
  interface with LargeAlloc and is easier to proxy.
- Allow the address space manager and the memory provider to be
  initialised with a range of memory.

This may eventually also remove the need for (or, at least, simplify)
the Open Enclave PAL.

This commit also ends up with a few other cleanups:

 - The `malloc_useable_size` CMake test that checks whether the
   parameter is const qualified was failing on FreeBSD where this
   function is declared in `malloc_np.h` but where including
   `malloc.h` raises an error.  This should now be more robust.
 - The BSD aligned PAL inherited from the BSD PAL, which does not
   expose aligned allocation. This meant that it exposed both the
   aligned and non-aligned allocation interfaces and so happily
   accepted incorrect `constexpr` if blocks that expected one or 
   the other but accidentally required both to exist. The unaligned
   function is now deleted so the same failures that appear in CI should
   appear locally for anyone using this PAL.
2021-01-11 14:06:51 +00:00
David Chisnall
4837c82489 Fix external pagemap usage. (#221)
At some point in the refactoring, these were broken.
2021-01-08 13:21:37 +00:00
David CARLIER
2dd63606af Sparc support proposal. (#264)
* Sparc support proposal.

* Tweaks from feedback.
Shift to integer/pointers cast like other archs.
Assembly reworks.
Note apparently reading the register once is sufficient to provoke
a pause in the cpu adding a clobber tough.
2021-01-05 16:28:22 +00:00
Nathaniel Filardo
975a2bd6db handle_dealloc_remote: restructure to avoid amplification when routing
When forwarding a Remote message, we can now operate entirely with local state:
access to our RemoteCache and the message itself.
2020-12-21 14:12:02 +00:00
Nathaniel Filardo
bf742cef84 handle_dealloc_remote{,_slow}: use Remote's sizeclass information
This removes a bunch of pointer math (which would need amplification) to find
and read the sizeclass from slab headers.
2020-12-21 14:12:02 +00:00
Nathaniel Filardo
7c04a9dad6 Remote: store the sizeclass, too
Squeeze some bits out of allocator IDs so that we can land the sizeclass in
each Remote object.  The intent is that, on StrictProvenance architectures like
CHERI, we will be able to route Remote messages through RemoteCache-s without
needing to amplify back to read the sizeclass metadata field out of the slab
headers.
2020-12-21 14:12:02 +00:00
Nathaniel Filardo
e9ed219fd8 ChunkMap: limit flat pagemap size
Presently, our flat pagemap can be configured to take...

                   32-bit AS    48-bit AS
USE_SMALL_CHUNKS     16 KiB        1 GiB
default               4 KiB      256 MiB
USE_LARGE_CHUNKS    256   B       16 MiB

At 1 GiB, we're already past the 512 MiB threshold imposed when
src/test/func/memory/memory.cc, when configured to TEST_LIMITED, probes the
effect of rlimit.

Instead, restrict flat pagemaps to at most 256 MiB of AS by default (override
by defining SNMALLOC_MAX_FLATPAGEMAP_SIZE), which forces the USE_SMALL_CHUNKS &
48-bit AS configuration to use the tree-based version.

While here, rename USE_FLATPAGEMAP to CHUNKMAP_USE_FLATPAGEMAP.
2020-12-16 15:57:19 +00:00
Nathaniel Filardo
c1d5f48797 Clarify ChunkMapSuperslabKind values 2020-12-16 15:57:19 +00:00
Nathaniel Filardo
b8b5f30513 mediumslab: limit header to min of page or slab
This had not been observed as an issue prior to
923705e514 because CMakeLists.txt had, until
then, been using EQUAL, not STREQUAL, to test for oe (and to then enable
USE_SMALL_CHUNKS).  This test would fail, and so the default SLAB_SIZE was
used.  Absent this min operation, the use of a whole page on a 64KiB page
causes a crash when using the largest medium size class, as, ultimately, size
classes are not based on page sizes, and so committing a whole page to the
header leaves too little room for that class.

See also 3d3b048776.
2020-12-16 15:57:19 +00:00
David Carlier
3e7ea1a85f Fix ARM 32 bits build, prfm is a 64 bits instruction. 2020-12-02 16:39:55 +00:00
Matthew Parkinson
3ca29d6f50 Make POSIX COMMIT CHECKS mode fill memory
This simulates the pages being switched off with unexpected content, and
thus, when turned on we don't assume they have been unchanged.
2020-11-10 09:57:38 +00:00
Matthew Parkinson
01b282a5f3 Bug fix for using failing to initialise meta-data
If the Superslab meta-data is larger than an OS page, then the
subsequent pages could be decommited. This removes the skipped
initialisation in that case.
2020-11-10 09:57:38 +00:00
David Carlier
8990c34911 pass through Haiku build fix.
Haiku has a malloc_usable_size api but via the posix layer.
2020-10-16 15:57:12 +01:00
David Carlier
49b9856ed0 DragonFly support (userland).
- Close to OpenBSD as there is no malloc*size api nor arbritrary
 alignment support.
- Like FreeBSD, MAP_NORESERVE never had been implemented even tough
 still present in the header but not mentioned in the man page,
FreeBSD has reserved the value for another later usage seems
 DragonFly has just out of sync header.
2020-10-05 10:44:30 +01:00
Matthew Parkinson
923705e514 Natural alignment for USE_MALLOC (#248)
* Add concept of natural alignment to tests.

snmalloc naturally aligns blocks very heavily, so that
the largest power-of-two in the rounded size is the alignment.
This checks that in the test, and provides a method for
finding the natural alignment of a block.

* Improve USE_MALLOC to provide alignment

snmalloc provides a lot of alginment guarantees. This ensures that when
we pass through to the system allocator we still get those alignment
guarantees.

The commit also fixes the tests to work with USE_MALLOC, and builds a
set of unit tests for ctest to check behaviour.
2020-09-28 10:08:19 +01:00
Matthew Parkinson
f89f78ad46 Fix bug in pagemap when index has many levels
The pagemap was double incrementing the index level.  This did not
exhibit in any use case of the pagemap as it only used 0 or 1 level of
intermediate index for all current use cases.

This commit fixes the bug, and adds a test that uses the pagemap in a
different configuration that has multiple levels of intermediate index
node.
2020-09-24 11:10:30 +01:00
Matthew Parkinson
d3ecd66f73 Add constexpr annotation to align_up/down. 2020-09-11 14:08:01 +01:00