mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:47:44 +00:00
Kernel: Don't COW volatile VM objects
If a purgeable VM object is in the "volatile" state when we're asked to make a COW clone of it, make life simpler by simply "purging" the cloned object right away. This effectively means that a fork()'ed child process will discover its purgeable+volatile regions to be empty if/when it tries making them non-volatile.
This commit is contained in:
parent
297c0748f0
commit
5fb91e2e84
1 changed files with 14 additions and 7 deletions
|
@ -18,17 +18,21 @@ RefPtr<VMObject> AnonymousVMObject::try_clone()
|
||||||
// We need to acquire our lock so we copy a sane state
|
// We need to acquire our lock so we copy a sane state
|
||||||
ScopedSpinLock lock(m_lock);
|
ScopedSpinLock lock(m_lock);
|
||||||
|
|
||||||
|
if (is_purgeable() && is_volatile()) {
|
||||||
|
// If this object is purgeable+volatile, create a new zero-filled purgeable+volatile
|
||||||
|
// object, effectively "pre-purging" it in the child process.
|
||||||
|
auto clone = try_create_purgeable_with_size(size(), AllocationStrategy::None);
|
||||||
|
if (!clone)
|
||||||
|
return {};
|
||||||
|
clone->m_volatile = true;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
// We're the parent. Since we're about to become COW we need to
|
// We're the parent. Since we're about to become COW we need to
|
||||||
// commit the number of pages that we need to potentially allocate
|
// commit the number of pages that we need to potentially allocate
|
||||||
// so that the parent is still guaranteed to be able to have all
|
// so that the parent is still guaranteed to be able to have all
|
||||||
// non-volatile memory available.
|
// non-volatile memory available.
|
||||||
size_t new_cow_pages_needed = 0;
|
size_t new_cow_pages_needed = page_count();
|
||||||
|
|
||||||
if (is_volatile()) {
|
|
||||||
// NOTE: If this object is currently volatile, we don't own any committed pages.
|
|
||||||
} else {
|
|
||||||
new_cow_pages_needed = page_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgln_if(COMMIT_DEBUG, "Cloning {:p}, need {} committed cow pages", this, new_cow_pages_needed);
|
dbgln_if(COMMIT_DEBUG, "Cloning {:p}, need {} committed cow pages", this, new_cow_pages_needed);
|
||||||
|
|
||||||
|
@ -205,11 +209,14 @@ KResult AnonymousVMObject::set_volatile(bool is_volatile, bool& was_purged)
|
||||||
page = MM.shared_zero_page();
|
page = MM.shared_zero_page();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (m_unused_committed_pages) {
|
if (m_unused_committed_pages) {
|
||||||
MM.uncommit_user_physical_pages(m_unused_committed_pages);
|
MM.uncommit_user_physical_pages(m_unused_committed_pages);
|
||||||
m_unused_committed_pages = 0;
|
m_unused_committed_pages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_shared_committed_cow_pages = nullptr;
|
||||||
|
|
||||||
m_volatile = true;
|
m_volatile = true;
|
||||||
m_was_purged = false;
|
m_was_purged = false;
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue