diff options
author | creator1creeper1 <creator1creeper1@airmail.cc> | 2022-01-11 18:05:47 +0100 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-15 22:16:00 +0200 |
commit | d1f265e85176488055131465baac892a7e2ad4fc (patch) | |
tree | 491ede6e68e38e35e0c820e57a5b579a79931e32 /Kernel | |
parent | 64778f9e69bbdc40f62ba10e78c635147de31014 (diff) | |
download | serenity-d1f265e85176488055131465baac892a7e2ad4fc.zip |
Kernel: Make VMOBject construction OOM-aware
This commit moves the allocation of the resources required for VMObject
from its constructors to the constructors of its child classes.
We're making this change to give the child classes the chance to expose
the fallibility of the allocation.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Memory/AnonymousVMObject.cpp | 8 | ||||
-rw-r--r-- | Kernel/Memory/InodeVMObject.cpp | 4 | ||||
-rw-r--r-- | Kernel/Memory/VMObject.cpp | 24 | ||||
-rw-r--r-- | Kernel/Memory/VMObject.h | 7 |
4 files changed, 30 insertions, 13 deletions
diff --git a/Kernel/Memory/AnonymousVMObject.cpp b/Kernel/Memory/AnonymousVMObject.cpp index 4511c8760e..32fcfa91f1 100644 --- a/Kernel/Memory/AnonymousVMObject.cpp +++ b/Kernel/Memory/AnonymousVMObject.cpp @@ -114,7 +114,7 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_for_phys } AnonymousVMObject::AnonymousVMObject(size_t size, AllocationStrategy strategy, Optional<CommittedPhysicalPageSet> committed_pages) - : VMObject(size) + : VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size)) , m_unused_committed_pages(move(committed_pages)) { if (strategy == AllocationStrategy::AllocateNow) { @@ -129,7 +129,7 @@ AnonymousVMObject::AnonymousVMObject(size_t size, AllocationStrategy strategy, O } AnonymousVMObject::AnonymousVMObject(PhysicalAddress paddr, size_t size) - : VMObject(size) + : VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size)) { VERIFY(paddr.page_base() == paddr); for (size_t i = 0; i < page_count(); ++i) @@ -137,7 +137,7 @@ AnonymousVMObject::AnonymousVMObject(PhysicalAddress paddr, size_t size) } AnonymousVMObject::AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>> physical_pages) - : VMObject(physical_pages.size() * PAGE_SIZE) + : VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(physical_pages.size() * PAGE_SIZE)) { for (size_t i = 0; i < physical_pages.size(); ++i) { m_physical_pages[i] = physical_pages[i]; @@ -145,7 +145,7 @@ AnonymousVMObject::AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>> physical_ } AnonymousVMObject::AnonymousVMObject(AnonymousVMObject const& other, NonnullRefPtr<SharedCommittedCowPages> shared_committed_cow_pages) - : VMObject(other) + : VMObject(other.must_clone_physical_pages_but_fixme_should_propagate_errors()) , m_shared_committed_cow_pages(move(shared_committed_cow_pages)) , m_purgeable(other.m_purgeable) { diff --git a/Kernel/Memory/InodeVMObject.cpp b/Kernel/Memory/InodeVMObject.cpp index 0435fc9522..23e13af719 100644 --- a/Kernel/Memory/InodeVMObject.cpp +++ b/Kernel/Memory/InodeVMObject.cpp @@ -10,14 +10,14 @@ namespace Kernel::Memory { InodeVMObject::InodeVMObject(Inode& inode, size_t size) - : VMObject(size) + : VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size)) , m_inode(inode) , m_dirty_pages(page_count(), false) { } InodeVMObject::InodeVMObject(InodeVMObject const& other) - : VMObject(other) + : VMObject(other.must_clone_physical_pages_but_fixme_should_propagate_errors()) , m_inode(other.m_inode) , m_dirty_pages(page_count(), false) { diff --git a/Kernel/Memory/VMObject.cpp b/Kernel/Memory/VMObject.cpp index 78db6f2d1b..a10897fddb 100644 --- a/Kernel/Memory/VMObject.cpp +++ b/Kernel/Memory/VMObject.cpp @@ -17,14 +17,28 @@ SpinlockProtected<VMObject::AllInstancesList>& VMObject::all_instances() return s_all_instances; } -VMObject::VMObject(VMObject const& other) - : m_physical_pages(other.m_physical_pages.must_clone_but_fixme_should_propagate_errors()) +ErrorOr<FixedArray<RefPtr<PhysicalPage>>> VMObject::try_clone_physical_pages() const { - all_instances().with([&](auto& list) { list.append(*this); }); + return m_physical_pages.try_clone(); +} + +FixedArray<RefPtr<PhysicalPage>> VMObject::must_clone_physical_pages_but_fixme_should_propagate_errors() const +{ + return MUST(try_clone_physical_pages()); +} + +ErrorOr<FixedArray<RefPtr<PhysicalPage>>> VMObject::try_create_physical_pages(size_t size) +{ + return FixedArray<RefPtr<PhysicalPage>>::try_create(ceil_div(size, static_cast<size_t>(PAGE_SIZE))); +} + +FixedArray<RefPtr<PhysicalPage>> VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size_t size) +{ + return MUST(try_create_physical_pages(size)); } -VMObject::VMObject(size_t size) - : m_physical_pages(FixedArray<RefPtr<PhysicalPage>>::must_create_but_fixme_should_propagate_errors(ceil_div(size, static_cast<size_t>(PAGE_SIZE)))) +VMObject::VMObject(FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages) + : m_physical_pages(move(new_physical_pages)) { all_instances().with([&](auto& list) { list.append(*this); }); } diff --git a/Kernel/Memory/VMObject.h b/Kernel/Memory/VMObject.h index 7997b86cf2..e2c775fd68 100644 --- a/Kernel/Memory/VMObject.h +++ b/Kernel/Memory/VMObject.h @@ -54,8 +54,11 @@ public: } protected: - explicit VMObject(size_t); - explicit VMObject(VMObject const&); + static ErrorOr<FixedArray<RefPtr<PhysicalPage>>> try_create_physical_pages(size_t); + static FixedArray<RefPtr<PhysicalPage>> must_create_physical_pages_but_fixme_should_propagate_errors(size_t); + ErrorOr<FixedArray<RefPtr<PhysicalPage>>> try_clone_physical_pages() const; + FixedArray<RefPtr<PhysicalPage>> must_clone_physical_pages_but_fixme_should_propagate_errors() const; + explicit VMObject(FixedArray<RefPtr<PhysicalPage>>&&); template<typename Callback> void for_each_region(Callback); |