Commit 4a5b3512 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Commit Bot

Free unused regions from partition address space.

Bug: 1086388
Change-Id: If3ebac4df104b607d3fd68588263f4ea19a63edc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2237501
Commit-Queue: Takashi Sakamoto <tasak@google.com>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarBartek Nowierski <bartekn@chromium.org>
Reviewed-by: default avatarBenoit L <lizeb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#779809}
parent 9b0a8845
......@@ -16,7 +16,6 @@ namespace internal {
#if defined(__LP64__)
uintptr_t PartitionAddressSpace::reserved_address_start_ = 0;
// Before PartitionAddressSpace::Init(), no allocation are allocated from a
// reserved address space. So initially make reserved_base_address_ to
// be kReservedAddressSpaceOffsetMask. So PartitionAddressSpace::Contains()
......@@ -31,18 +30,11 @@ pool_handle PartitionAddressSpace::direct_map_pool_ = 0;
pool_handle PartitionAddressSpace::normal_bucket_pool_ = 0;
void PartitionAddressSpace::Init() {
PA_DCHECK(!reserved_address_start_);
reserved_address_start_ = reinterpret_cast<uintptr_t>(SystemAllocPages(
nullptr, kReservedAddressSpaceSize, base::PageInaccessible,
PageTag::kPartitionAlloc, false));
PA_CHECK(reserved_address_start_);
const uintptr_t reserved_address_end =
reserved_address_start_ + kReservedAddressSpaceSize;
reserved_base_address_ =
bits::Align(reserved_address_start_, kReservedAddressSpaceAlignment);
PA_DCHECK(reserved_base_address_ >= reserved_address_start_);
PA_DCHECK(kReservedAddressSpaceOffsetMask == reserved_base_address_);
reserved_base_address_ = reinterpret_cast<uintptr_t>(AllocPages(
nullptr, kDesiredAddressSpaceSize, kReservedAddressSpaceAlignment,
base::PageInaccessible, PageTag::kPartitionAlloc, false));
PA_CHECK(reserved_base_address_);
PA_DCHECK(!(reserved_base_address_ & kReservedAddressSpaceOffsetMask));
uintptr_t current = reserved_base_address_;
......@@ -57,15 +49,13 @@ void PartitionAddressSpace::Init() {
current, kNormalBucketPoolSize);
PA_DCHECK(normal_bucket_pool_);
current += kNormalBucketPoolSize;
PA_DCHECK(current <= reserved_address_end);
PA_DCHECK(current == reserved_base_address_ + kDesiredAddressSpaceSize);
PA_DCHECK(reserved_base_address_ + kDesiredAddressSpaceSize == current);
}
void PartitionAddressSpace::UninitForTesting() {
PA_DCHECK(reserved_address_start_);
FreePages(reinterpret_cast<void*>(reserved_address_start_),
kReservedAddressSpaceSize);
reserved_address_start_ = 0;
PA_DCHECK(kReservedAddressSpaceOffsetMask != reserved_base_address_);
FreePages(reinterpret_cast<void*>(reserved_base_address_),
kReservedAddressSpaceAlignment);
reserved_base_address_ = kReservedAddressSpaceOffsetMask;
direct_map_pool_ = 0;
normal_bucket_pool_ = 0;
......
......@@ -55,32 +55,21 @@ class BASE_EXPORT PartitionAddressSpace {
private:
// Partition Alloc Address Space
// Reserves 64Gbytes address space for 1 direct map space(16G) and 1 normal
// bucket space(16G). The remaining 32G is for padding, so that we can
// guarantee a 32G alignment somewhere within the reserved region. Address
// space is cheap and abundant on 64-bit systems.
// TODO(tasak): Telease unused address space.
// TODO(bartekn): Look into devices with 39-bit address space that have 256G
// Reserves 32GiB address space for 1 direct map space(16GiB) and 1 normal
// bucket space(16GiB).
// TODO(bartekn): Look into devices with 39-bit address space that have 256GiB
// user-mode space. Libraries loaded at random addresses may stand in the way
// of reserving a contiguous 64G region.
// of reserving a contiguous 64GiB region. (even though we're requesting only
// 32GiB, AllocPages may under the covers reserve 64GiB to satisfy the
// alignment requirements)
//
// +----------------+ reserved address start
// | (unused) |
// +----------------+ 32G-aligned reserved address: X
// | |
// +----------------+ reserved_base_address_(32GiB aligned)
// | direct map |
// | space |
// | |
// +----------------+ X + 16G bytes
// +----------------+ reserved_base_address_ + 16GiB
// | normal buckets |
// | space |
// +----------------+ X + 32G bytes
// | (unused) |
// +----------------+ reserved address end
//
// The static member variables:
// - reserved_address_starts_ points the "reserved address start" address, and
// - reserved_base_address_ points the "32G-aligned reserved address: X".
// +----------------+ reserved_base_address_ + 32GiB
static constexpr size_t kGigaBytes = 1024 * 1024 * 1024;
static constexpr size_t kDirectMapPoolSize = 16 * kGigaBytes;
......@@ -90,16 +79,13 @@ class BASE_EXPORT PartitionAddressSpace {
static constexpr uintptr_t kNormalBucketPoolBaseMask =
~kNormalBucketPoolOffsetMask;
// Reserves 32GB aligned address space.
// Alignment should be the smallest power of two greater than or equal to the
// desired size, so that we can check containment with a single bitmask
// operation.
// Reserves 32GiB aligned address space.
// We align on 32GiB as well, and since it's a power of two we can check a
// pointer with a single bitmask operation.
static constexpr size_t kDesiredAddressSpaceSize =
kDirectMapPoolSize + kNormalBucketPoolSize;
static constexpr size_t kReservedAddressSpaceAlignment =
kDesiredAddressSpaceSize;
static constexpr size_t kReservedAddressSpaceSize =
kReservedAddressSpaceAlignment * 2;
static constexpr uintptr_t kReservedAddressSpaceOffsetMask =
static_cast<uintptr_t>(kReservedAddressSpaceAlignment) - 1;
static constexpr uintptr_t kReservedAddressSpaceBaseMask =
......@@ -118,13 +104,8 @@ class BASE_EXPORT PartitionAddressSpace {
"kReservedAddressSpaceAlignment should be the smallest power of "
"two greater or equal to kDesiredAddressSpaceSize. So a half of "
"the alignment should be smaller than the desired size.");
static_assert(PartitionAddressSpace::kReservedAddressSpaceSize >
PartitionAddressSpace::kReservedAddressSpaceAlignment,
"kReservedAddressSpaceSize should be larger than "
"kReservedAddressSpaceAlignment.");
// See the comment describing the address layout above.
static uintptr_t reserved_address_start_;
static uintptr_t reserved_base_address_;
static uintptr_t normal_bucket_pool_base_address_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment