* Sanity check on parameters to large buddy.

* Check commit occurs at page granularity

* Alter PAGE_SIZE usage

Using PAGE_SIZE as the minimum size of the CHUNK means that if this is
configured to 2MiB, then there is a gap between
MAX_SMALL_SIZECLASS_SIZE, and MIN_CHUNK_SIZE, and thus
we can't represent certain sizes,
This commit is contained in:
Matthew Parkinson 2022-05-31 13:59:42 +01:00 коммит произвёл GitHub
Родитель 03c9da6aa4
Коммит 53d9fd2abe
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 53 добавлений и 6 удалений

Просмотреть файл

@ -40,6 +40,12 @@ namespace snmalloc
LogRange<2>,
GlobalRange<>>;
static constexpr size_t page_size_bits =
bits::next_pow2_bits_const(PAL::page_size);
static constexpr size_t max_page_chunk_size_bits =
bits::max(page_size_bits, MIN_CHUNK_BITS);
// Central source of object-range, does not pass back to GlobalR as
// that would allow flows from Objects to Meta-data, and thus UAF
// would be able to corrupt meta-data.
@ -61,16 +67,31 @@ namespace snmalloc
GlobalR,
SubRange<PAL, SubRangeRatioBits>, // Use SubRange to introduce guard
// pages.
LargeBuddyRange<GlobalCacheSizeBits, bits::BITS - 1, Pagemap>,
LargeBuddyRange<
GlobalCacheSizeBits,
bits::BITS - 1,
Pagemap,
page_size_bits>,
CommitRange<PAL>,
// In case of huge pages, we don't want to give each thread its own huge
// page, so commit in the global range.
LargeBuddyRange<
max_page_chunk_size_bits,
max_page_chunk_size_bits,
Pagemap,
page_size_bits>,
LogRange<4>,
GlobalRange<>,
CommitRange<PAL>,
StatsRange<>>;
// Local caching of object range
using ObjectRange = Pipe<
CentralObjectRange,
LargeBuddyRange<LocalCacheSizeBits, LocalCacheSizeBits, Pagemap>,
LargeBuddyRange<
LocalCacheSizeBits,
LocalCacheSizeBits,
Pagemap,
page_size_bits>,
LogRange<5>>;
// Local caching of meta-data range

Просмотреть файл

@ -41,11 +41,18 @@ namespace snmalloc
using Stats = Pipe<GlobalR, CommitRange<PAL>, StatsRange<>>;
private:
static constexpr size_t page_size_bits =
bits::next_pow2_bits_const(PAL::page_size);
// Source for object allocations and metadata
// Use buddy allocators to cache locally.
using ObjectRange = Pipe<
Stats,
LargeBuddyRange<LocalCacheSizeBits, LocalCacheSizeBits, Pagemap>,
LargeBuddyRange<
LocalCacheSizeBits,
LocalCacheSizeBits,
Pagemap,
page_size_bits>,
SmallBuddyRange<>>;
public:

Просмотреть файл

@ -25,6 +25,11 @@ namespace snmalloc
capptr::Chunk<void> alloc_range(size_t size)
{
SNMALLOC_ASSERT_MSG(
(size % PAL::page_size) == 0,
"size ({}) must be a multiple of page size ({})",
size,
PAL::page_size);
auto range = parent.alloc_range(size);
if (range != nullptr)
PAL::template notify_using<NoZero>(range.unsafe_ptr(), size);
@ -33,6 +38,11 @@ namespace snmalloc
void dealloc_range(capptr::Chunk<void> base, size_t size)
{
SNMALLOC_ASSERT_MSG(
(size % PAL::page_size) == 0,
"size ({}) must be a multiple of page size ({})",
size,
PAL::page_size);
PAL::notify_not_using(base.unsafe_ptr(), size);
parent.dealloc_range(base, size);
}

Просмотреть файл

@ -193,6 +193,12 @@ namespace snmalloc
{
using ContainsParent<ParentRange>::parent;
static_assert(
REFILL_SIZE_BITS <= MAX_SIZE_BITS, "REFILL_SIZE_BITS > MAX_SIZE_BITS");
static_assert(
MIN_REFILL_SIZE_BITS <= REFILL_SIZE_BITS,
"MIN_REFILL_SIZE_BITS > REFILL_SIZE_BITS");
/**
* Maximum size of a refill
*/

Просмотреть файл

@ -26,8 +26,7 @@ namespace snmalloc
static constexpr size_t MIN_ALLOC_BITS = bits::ctz_const(MIN_ALLOC_SIZE);
// Minimum slab size.
static constexpr size_t MIN_CHUNK_BITS = bits::max(
static_cast<size_t>(14), bits::next_pow2_bits_const(OS_PAGE_SIZE));
static constexpr size_t MIN_CHUNK_BITS = static_cast<size_t>(14);
static constexpr size_t MIN_CHUNK_SIZE = bits::one_at_bit(MIN_CHUNK_BITS);
// Minimum number of objects on a slab
@ -42,6 +41,10 @@ namespace snmalloc
static constexpr size_t MAX_SMALL_SIZECLASS_SIZE =
bits::one_at_bit(MAX_SMALL_SIZECLASS_BITS);
static_assert(
MAX_SMALL_SIZECLASS_SIZE >= MIN_CHUNK_SIZE,
"Large sizes need to be representable by as a multiple of MIN_CHUNK_SIZE");
// Number of slots for remote deallocation.
static constexpr size_t REMOTE_SLOT_BITS = 8;
static constexpr size_t REMOTE_SLOTS = 1 << REMOTE_SLOT_BITS;