diff options
author | creator1creeper1 <creator1creeper1@airmail.cc> | 2022-01-12 16:23:48 +0100 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-15 22:16:00 +0200 |
commit | 3879e70447a9e3b0f6a8ae64ba1a575c2b5f5703 (patch) | |
tree | 2b6d7d0f41512ec7bea95262316c43f70fef7cdb | |
parent | d1f265e85176488055131465baac892a7e2ad4fc (diff) | |
download | serenity-3879e70447a9e3b0f6a8ae64ba1a575c2b5f5703.zip |
Kernel: Make AnonymousVMObject construction OOM-aware
This commit moves the allocation of the resources required for
AnonymousVMObject from its constructors to its factory functions.
We're making this change to expose the fallibility of the allocation.
-rw-r--r-- | Kernel/Memory/AnonymousVMObject.cpp | 41 | ||||
-rw-r--r-- | Kernel/Memory/AnonymousVMObject.h | 8 |
2 files changed, 28 insertions, 21 deletions
diff --git a/Kernel/Memory/AnonymousVMObject.cpp b/Kernel/Memory/AnonymousVMObject.cpp index 32fcfa91f1..ad3465e732 100644 --- a/Kernel/Memory/AnonymousVMObject.cpp +++ b/Kernel/Memory/AnonymousVMObject.cpp @@ -43,7 +43,8 @@ ErrorOr<NonnullRefPtr<VMObject>> AnonymousVMObject::try_clone() // one and this one, as well as the clone have sufficient resources // to cow all pages as needed auto new_shared_committed_cow_pages = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SharedCommittedCowPages(move(committed_pages)))); - auto clone = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(*this, *new_shared_committed_cow_pages))); + auto new_physical_pages = TRY(this->try_clone_physical_pages()); + auto clone = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(*this, *new_shared_committed_cow_pages, move(new_physical_pages)))); m_shared_committed_cow_pages = move(new_shared_committed_cow_pages); @@ -73,7 +74,9 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_with_siz committed_pages = TRY(MM.commit_user_physical_pages(ceil_div(size, static_cast<size_t>(PAGE_SIZE)))); } - return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(size, strategy, move(committed_pages))); + auto new_physical_pages = TRY(VMObject::try_create_physical_pages(size)); + + return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages), strategy, move(committed_pages))); } ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_physically_contiguous_with_size(size_t size) @@ -82,7 +85,9 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_physical if (contiguous_physical_pages.is_empty()) return ENOMEM; - return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(contiguous_physical_pages.span())); + auto new_physical_pages = TRY(FixedArray<RefPtr<PhysicalPage>>::try_create(contiguous_physical_pages.span())); + + return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages))); } ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_purgeable_with_size(size_t size, AllocationStrategy strategy) @@ -92,14 +97,17 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_purgeabl committed_pages = TRY(MM.commit_user_physical_pages(ceil_div(size, static_cast<size_t>(PAGE_SIZE)))); } - auto vmobject = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(size, strategy, move(committed_pages)))); + auto new_physical_pages = TRY(VMObject::try_create_physical_pages(size)); + + auto vmobject = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages), strategy, move(committed_pages)))); vmobject->m_purgeable = true; return vmobject; } ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_with_physical_pages(Span<NonnullRefPtr<PhysicalPage>> physical_pages) { - return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(physical_pages)); + auto new_physical_pages = TRY(FixedArray<RefPtr<PhysicalPage>>::try_create(physical_pages)); + return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages))); } ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_for_physical_range(PhysicalAddress paddr, size_t size) @@ -110,11 +118,13 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_for_phys return ENOMEM; } - return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(paddr, size)); + auto new_physical_pages = TRY(VMObject::try_create_physical_pages(size)); + + return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(paddr, move(new_physical_pages))); } -AnonymousVMObject::AnonymousVMObject(size_t size, AllocationStrategy strategy, Optional<CommittedPhysicalPageSet> committed_pages) - : VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size)) +AnonymousVMObject::AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages, AllocationStrategy strategy, Optional<CommittedPhysicalPageSet> committed_pages) + : VMObject(move(new_physical_pages)) , m_unused_committed_pages(move(committed_pages)) { if (strategy == AllocationStrategy::AllocateNow) { @@ -128,24 +138,21 @@ AnonymousVMObject::AnonymousVMObject(size_t size, AllocationStrategy strategy, O } } -AnonymousVMObject::AnonymousVMObject(PhysicalAddress paddr, size_t size) - : VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size)) +AnonymousVMObject::AnonymousVMObject(PhysicalAddress paddr, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages) + : VMObject(move(new_physical_pages)) { VERIFY(paddr.page_base() == paddr); for (size_t i = 0; i < page_count(); ++i) physical_pages()[i] = PhysicalPage::create(paddr.offset(i * PAGE_SIZE), MayReturnToFreeList::No); } -AnonymousVMObject::AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>> physical_pages) - : VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(physical_pages.size() * PAGE_SIZE)) +AnonymousVMObject::AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages) + : VMObject(move(new_physical_pages)) { - for (size_t i = 0; i < physical_pages.size(); ++i) { - m_physical_pages[i] = physical_pages[i]; - } } -AnonymousVMObject::AnonymousVMObject(AnonymousVMObject const& other, NonnullRefPtr<SharedCommittedCowPages> shared_committed_cow_pages) - : VMObject(other.must_clone_physical_pages_but_fixme_should_propagate_errors()) +AnonymousVMObject::AnonymousVMObject(AnonymousVMObject const& other, NonnullRefPtr<SharedCommittedCowPages> shared_committed_cow_pages, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages) + : VMObject(move(new_physical_pages)) , m_shared_committed_cow_pages(move(shared_committed_cow_pages)) , m_purgeable(other.m_purgeable) { diff --git a/Kernel/Memory/AnonymousVMObject.h b/Kernel/Memory/AnonymousVMObject.h index b85af11f3b..dead6cbef0 100644 --- a/Kernel/Memory/AnonymousVMObject.h +++ b/Kernel/Memory/AnonymousVMObject.h @@ -41,10 +41,10 @@ public: private: class SharedCommittedCowPages; - explicit AnonymousVMObject(size_t, AllocationStrategy, Optional<CommittedPhysicalPageSet>); - explicit AnonymousVMObject(PhysicalAddress, size_t); - explicit AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>>); - explicit AnonymousVMObject(AnonymousVMObject const&, NonnullRefPtr<SharedCommittedCowPages>); + explicit AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&&, AllocationStrategy, Optional<CommittedPhysicalPageSet>); + explicit AnonymousVMObject(PhysicalAddress, FixedArray<RefPtr<PhysicalPage>>&&); + explicit AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&&); + explicit AnonymousVMObject(AnonymousVMObject const&, NonnullRefPtr<SharedCommittedCowPages>, FixedArray<RefPtr<PhysicalPage>>&&); virtual StringView class_name() const override { return "AnonymousVMObject"sv; } |