mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
Kernel: Handle AnonymousVMObject allocation failure when forking
Thanks to all the RAII, AnonymousVMObject::try_clone() can now gracefully handle allocation failure.
This commit is contained in:
parent
0672163840
commit
89a9ae7d0c
2 changed files with 13 additions and 9 deletions
|
@ -46,19 +46,21 @@ RefPtr<VMObject> AnonymousVMObject::try_clone()
|
|||
// one would keep the one it still has. This ensures that the original
|
||||
// one and this one, as well as the clone have sufficient resources
|
||||
// to cow all pages as needed
|
||||
m_shared_committed_cow_pages = try_create<SharedCommittedCowPages>(committed_pages.release_value());
|
||||
auto new_shared_committed_cow_pages = try_create<SharedCommittedCowPages>(committed_pages.release_value());
|
||||
|
||||
if (!m_shared_committed_cow_pages)
|
||||
if (!new_shared_committed_cow_pages)
|
||||
return {};
|
||||
|
||||
auto clone = adopt_ref_if_nonnull(new (nothrow) AnonymousVMObject(*this, *new_shared_committed_cow_pages));
|
||||
if (!clone)
|
||||
return {};
|
||||
|
||||
m_shared_committed_cow_pages = move(new_shared_committed_cow_pages);
|
||||
|
||||
// Both original and clone become COW. So create a COW map for ourselves
|
||||
// or reset all pages to be copied again if we were previously cloned
|
||||
ensure_or_reset_cow_map();
|
||||
|
||||
// FIXME: If this allocation fails, we need to rollback all changes.
|
||||
auto clone = adopt_ref_if_nonnull(new (nothrow) AnonymousVMObject(*this));
|
||||
VERIFY(clone);
|
||||
|
||||
if (m_unused_committed_pages.has_value() && !m_unused_committed_pages->is_empty()) {
|
||||
// The parent vmobject didn't use up all committed pages. When
|
||||
// cloning (fork) we will overcommit. For this purpose we drop all
|
||||
|
@ -153,9 +155,9 @@ AnonymousVMObject::AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>> physical_
|
|||
}
|
||||
}
|
||||
|
||||
AnonymousVMObject::AnonymousVMObject(AnonymousVMObject const& other)
|
||||
AnonymousVMObject::AnonymousVMObject(AnonymousVMObject const& other, NonnullRefPtr<SharedCommittedCowPages> shared_committed_cow_pages)
|
||||
: VMObject(other)
|
||||
, m_shared_committed_cow_pages(other.m_shared_committed_cow_pages)
|
||||
, m_shared_committed_cow_pages(move(shared_committed_cow_pages))
|
||||
, m_purgeable(other.m_purgeable)
|
||||
{
|
||||
ensure_cow_map();
|
||||
|
|
|
@ -39,10 +39,12 @@ public:
|
|||
size_t purge();
|
||||
|
||||
private:
|
||||
class SharedCommittedCowPages;
|
||||
|
||||
explicit AnonymousVMObject(size_t, AllocationStrategy, Optional<CommittedPhysicalPageSet>);
|
||||
explicit AnonymousVMObject(PhysicalAddress, size_t);
|
||||
explicit AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>>);
|
||||
explicit AnonymousVMObject(AnonymousVMObject const&);
|
||||
explicit AnonymousVMObject(AnonymousVMObject const&, NonnullRefPtr<SharedCommittedCowPages>);
|
||||
|
||||
virtual StringView class_name() const override { return "AnonymousVMObject"sv; }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue