mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:17:45 +00:00
Kernel: Use RAII to manage committed physical pages
We had issues with committed physical pages getting miscounted in some situations, and instead of figuring out what was going wrong and making sure all the commits had matching uncommits, this patch makes the problem go away by adding an RAII class to manage this instead. :^) MemoryManager::commit_user_physical_pages() now returns an (optional) CommittedPhysicalPageSet. You can then allocate pages from the page set by calling take_one() on it. Any unallocated pages are uncommitted upon destruction of the page set.
This commit is contained in:
parent
ec49213f7b
commit
fa627c1eb2
4 changed files with 121 additions and 93 deletions
|
@ -14,22 +14,6 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
class CommittedCowPages : public RefCounted<CommittedCowPages> {
|
||||
AK_MAKE_NONCOPYABLE(CommittedCowPages);
|
||||
|
||||
public:
|
||||
CommittedCowPages() = delete;
|
||||
|
||||
explicit CommittedCowPages(size_t);
|
||||
~CommittedCowPages();
|
||||
|
||||
[[nodiscard]] NonnullRefPtr<PhysicalPage> allocate_one();
|
||||
[[nodiscard]] size_t is_empty() const { return m_committed_pages == 0; }
|
||||
|
||||
public:
|
||||
size_t m_committed_pages { 0 };
|
||||
};
|
||||
|
||||
class AnonymousVMObject final : public VMObject {
|
||||
public:
|
||||
virtual ~AnonymousVMObject() override;
|
||||
|
@ -55,7 +39,7 @@ public:
|
|||
size_t purge();
|
||||
|
||||
private:
|
||||
explicit AnonymousVMObject(size_t, AllocationStrategy);
|
||||
explicit AnonymousVMObject(size_t, AllocationStrategy, Optional<CommittedPhysicalPageSet>);
|
||||
explicit AnonymousVMObject(PhysicalAddress, size_t);
|
||||
explicit AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>>);
|
||||
explicit AnonymousVMObject(AnonymousVMObject const&);
|
||||
|
@ -71,11 +55,28 @@ private:
|
|||
Bitmap& ensure_cow_map();
|
||||
void ensure_or_reset_cow_map();
|
||||
|
||||
size_t m_unused_committed_pages { 0 };
|
||||
Optional<CommittedPhysicalPageSet> m_unused_committed_pages;
|
||||
Bitmap m_cow_map;
|
||||
|
||||
// We share a pool of committed cow-pages with clones
|
||||
RefPtr<CommittedCowPages> m_shared_committed_cow_pages;
|
||||
// AnonymousVMObject shares committed COW pages with cloned children (happens on fork)
|
||||
class SharedCommittedCowPages : public RefCounted<SharedCommittedCowPages> {
|
||||
AK_MAKE_NONCOPYABLE(SharedCommittedCowPages);
|
||||
|
||||
public:
|
||||
SharedCommittedCowPages() = delete;
|
||||
|
||||
explicit SharedCommittedCowPages(CommittedPhysicalPageSet&&);
|
||||
~SharedCommittedCowPages();
|
||||
|
||||
[[nodiscard]] NonnullRefPtr<PhysicalPage> take_one();
|
||||
[[nodiscard]] bool is_empty() const { return m_committed_pages.is_empty(); }
|
||||
|
||||
public:
|
||||
SpinLock<u8> m_lock;
|
||||
CommittedPhysicalPageSet m_committed_pages;
|
||||
};
|
||||
|
||||
RefPtr<SharedCommittedCowPages> m_shared_committed_cow_pages;
|
||||
|
||||
bool m_purgeable { false };
|
||||
bool m_volatile { false };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue