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 { ...@@ -16,7 +16,6 @@ namespace internal {
#if defined(__LP64__) #if defined(__LP64__)
uintptr_t PartitionAddressSpace::reserved_address_start_ = 0;
// Before PartitionAddressSpace::Init(), no allocation are allocated from a // Before PartitionAddressSpace::Init(), no allocation are allocated from a
// reserved address space. So initially make reserved_base_address_ to // reserved address space. So initially make reserved_base_address_ to
// be kReservedAddressSpaceOffsetMask. So PartitionAddressSpace::Contains() // be kReservedAddressSpaceOffsetMask. So PartitionAddressSpace::Contains()
...@@ -31,18 +30,11 @@ pool_handle PartitionAddressSpace::direct_map_pool_ = 0; ...@@ -31,18 +30,11 @@ pool_handle PartitionAddressSpace::direct_map_pool_ = 0;
pool_handle PartitionAddressSpace::normal_bucket_pool_ = 0; pool_handle PartitionAddressSpace::normal_bucket_pool_ = 0;
void PartitionAddressSpace::Init() { void PartitionAddressSpace::Init() {
PA_DCHECK(!reserved_address_start_); PA_DCHECK(kReservedAddressSpaceOffsetMask == reserved_base_address_);
reserved_address_start_ = reinterpret_cast<uintptr_t>(SystemAllocPages( reserved_base_address_ = reinterpret_cast<uintptr_t>(AllocPages(
nullptr, kReservedAddressSpaceSize, base::PageInaccessible, nullptr, kDesiredAddressSpaceSize, kReservedAddressSpaceAlignment,
PageTag::kPartitionAlloc, false)); base::PageInaccessible, PageTag::kPartitionAlloc, false));
PA_CHECK(reserved_address_start_); PA_CHECK(reserved_base_address_);
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(!(reserved_base_address_ & kReservedAddressSpaceOffsetMask)); PA_DCHECK(!(reserved_base_address_ & kReservedAddressSpaceOffsetMask));
uintptr_t current = reserved_base_address_; uintptr_t current = reserved_base_address_;
...@@ -57,15 +49,13 @@ void PartitionAddressSpace::Init() { ...@@ -57,15 +49,13 @@ void PartitionAddressSpace::Init() {
current, kNormalBucketPoolSize); current, kNormalBucketPoolSize);
PA_DCHECK(normal_bucket_pool_); PA_DCHECK(normal_bucket_pool_);
current += kNormalBucketPoolSize; current += kNormalBucketPoolSize;
PA_DCHECK(current <= reserved_address_end); PA_DCHECK(reserved_base_address_ + kDesiredAddressSpaceSize == current);
PA_DCHECK(current == reserved_base_address_ + kDesiredAddressSpaceSize);
} }
void PartitionAddressSpace::UninitForTesting() { void PartitionAddressSpace::UninitForTesting() {
PA_DCHECK(reserved_address_start_); PA_DCHECK(kReservedAddressSpaceOffsetMask != reserved_base_address_);
FreePages(reinterpret_cast<void*>(reserved_address_start_), FreePages(reinterpret_cast<void*>(reserved_base_address_),
kReservedAddressSpaceSize); kReservedAddressSpaceAlignment);
reserved_address_start_ = 0;
reserved_base_address_ = kReservedAddressSpaceOffsetMask; reserved_base_address_ = kReservedAddressSpaceOffsetMask;
direct_map_pool_ = 0; direct_map_pool_ = 0;
normal_bucket_pool_ = 0; normal_bucket_pool_ = 0;
......
...@@ -55,32 +55,21 @@ class BASE_EXPORT PartitionAddressSpace { ...@@ -55,32 +55,21 @@ class BASE_EXPORT PartitionAddressSpace {
private: private:
// Partition Alloc Address Space // Partition Alloc Address Space
// Reserves 64Gbytes address space for 1 direct map space(16G) and 1 normal // Reserves 32GiB address space for 1 direct map space(16GiB) and 1 normal
// bucket space(16G). The remaining 32G is for padding, so that we can // bucket space(16GiB).
// guarantee a 32G alignment somewhere within the reserved region. Address // TODO(bartekn): Look into devices with 39-bit address space that have 256GiB
// 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
// user-mode space. Libraries loaded at random addresses may stand in the way // 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 // +----------------+ reserved_base_address_(32GiB aligned)
// | (unused) |
// +----------------+ 32G-aligned reserved address: X
// | |
// | direct map | // | direct map |
// | space | // | space |
// | | // +----------------+ reserved_base_address_ + 16GiB
// +----------------+ X + 16G bytes
// | normal buckets | // | normal buckets |
// | space | // | space |
// +----------------+ X + 32G bytes // +----------------+ reserved_base_address_ + 32GiB
// | (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".
static constexpr size_t kGigaBytes = 1024 * 1024 * 1024; static constexpr size_t kGigaBytes = 1024 * 1024 * 1024;
static constexpr size_t kDirectMapPoolSize = 16 * kGigaBytes; static constexpr size_t kDirectMapPoolSize = 16 * kGigaBytes;
...@@ -90,16 +79,13 @@ class BASE_EXPORT PartitionAddressSpace { ...@@ -90,16 +79,13 @@ class BASE_EXPORT PartitionAddressSpace {
static constexpr uintptr_t kNormalBucketPoolBaseMask = static constexpr uintptr_t kNormalBucketPoolBaseMask =
~kNormalBucketPoolOffsetMask; ~kNormalBucketPoolOffsetMask;
// Reserves 32GB aligned address space. // Reserves 32GiB aligned address space.
// Alignment should be the smallest power of two greater than or equal to the // We align on 32GiB as well, and since it's a power of two we can check a
// desired size, so that we can check containment with a single bitmask // pointer with a single bitmask operation.
// operation.
static constexpr size_t kDesiredAddressSpaceSize = static constexpr size_t kDesiredAddressSpaceSize =
kDirectMapPoolSize + kNormalBucketPoolSize; kDirectMapPoolSize + kNormalBucketPoolSize;
static constexpr size_t kReservedAddressSpaceAlignment = static constexpr size_t kReservedAddressSpaceAlignment =
kDesiredAddressSpaceSize; kDesiredAddressSpaceSize;
static constexpr size_t kReservedAddressSpaceSize =
kReservedAddressSpaceAlignment * 2;
static constexpr uintptr_t kReservedAddressSpaceOffsetMask = static constexpr uintptr_t kReservedAddressSpaceOffsetMask =
static_cast<uintptr_t>(kReservedAddressSpaceAlignment) - 1; static_cast<uintptr_t>(kReservedAddressSpaceAlignment) - 1;
static constexpr uintptr_t kReservedAddressSpaceBaseMask = static constexpr uintptr_t kReservedAddressSpaceBaseMask =
...@@ -118,13 +104,8 @@ class BASE_EXPORT PartitionAddressSpace { ...@@ -118,13 +104,8 @@ class BASE_EXPORT PartitionAddressSpace {
"kReservedAddressSpaceAlignment should be the smallest power of " "kReservedAddressSpaceAlignment should be the smallest power of "
"two greater or equal to kDesiredAddressSpaceSize. So a half of " "two greater or equal to kDesiredAddressSpaceSize. So a half of "
"the alignment should be smaller than the desired size."); "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. // See the comment describing the address layout above.
static uintptr_t reserved_address_start_;
static uintptr_t reserved_base_address_; static uintptr_t reserved_base_address_;
static uintptr_t normal_bucket_pool_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