diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-11-05 10:23:00 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-11-05 10:23:00 +0100 |
commit | 72cdc62155be8af67ff9328bc4226a69bbbb659c (patch) | |
tree | be86883b319ff581da9b04007ece362ebc75f4fe /Kernel/MemoryManager.h | |
parent | b5c5286ee19b6414ad20496e31913efb79002b2c (diff) | |
download | serenity-72cdc62155be8af67ff9328bc4226a69bbbb659c.zip |
Replace zones with individually tracked physical pages.
It's just a simple struct { ref_count, paddr }.
This will allow me to implement lazy zeroing and COW pages.
Diffstat (limited to 'Kernel/MemoryManager.h')
-rw-r--r-- | Kernel/MemoryManager.h | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h index 0ebe056666..39e295afa3 100644 --- a/Kernel/MemoryManager.h +++ b/Kernel/MemoryManager.h @@ -17,34 +17,50 @@ enum class PageFaultResponse { Continue, }; -struct PageDirectory { - dword entries[1024]; - PhysicalAddress physical_addresses[1024]; -}; - -struct Zone : public Retainable<Zone> { - friend ByteBuffer procfs$mm(); +class PhysicalPage { + friend class MemoryManager; public: - ~Zone(); - size_t size() const { return m_pages.size() * PAGE_SIZE; } - - const Vector<PhysicalAddress>& pages() const { return m_pages; } + ~PhysicalPage() { } + PhysicalAddress paddr() const { return m_paddr; } + + void retain() + { + ASSERT(m_retain_count); + ++m_retain_count; + } + + void release() + { + ASSERT(m_retain_count); + if (!--m_retain_count) + return_to_freelist(); + } private: - friend class MemoryManager; - explicit Zone(Vector<PhysicalAddress>&&); + PhysicalPage(PhysicalAddress paddr) + : m_paddr(paddr) + { + } + + void return_to_freelist(); - Vector<PhysicalAddress> m_pages; + unsigned m_retain_count { 1 }; + PhysicalAddress m_paddr; +}; + +struct PageDirectory { + dword entries[1024]; + RetainPtr<PhysicalPage> physical_pages[1024]; }; struct Region : public Retainable<Region> { - Region(LinearAddress, size_t, RetainPtr<Zone>&&, String&&, bool r, bool w); + Region(LinearAddress, size_t, Vector<RetainPtr<PhysicalPage>>, String&&, bool r, bool w); ~Region(); RetainPtr<Region> clone(); LinearAddress linearAddress; size_t size { 0 }; - RetainPtr<Zone> zone; + Vector<RetainPtr<PhysicalPage>> physical_pages; String name; bool is_readable { true }; bool is_writable { true }; @@ -54,6 +70,7 @@ struct Region : public Retainable<Region> { class MemoryManager { AK_MAKE_ETERNAL + friend class PhysicalPage; friend ByteBuffer procfs$mm(); public: static MemoryManager& the() PURE; @@ -64,14 +81,9 @@ public: PageFaultResponse handlePageFault(const PageFault&); - RetainPtr<Zone> createZone(size_t); - bool mapRegion(Process&, Region&); bool unmapRegion(Process&, Region&); - void registerZone(Zone&); - void unregisterZone(Zone&); - void populate_page_directory(PageDirectory&); void release_page_directory(PageDirectory&); @@ -84,6 +96,8 @@ public: bool validate_user_read(const Process&, LinearAddress) const; bool validate_user_write(const Process&, LinearAddress) const; + Vector<RetainPtr<PhysicalPage>> allocate_physical_pages(size_t count); + private: MemoryManager(); ~MemoryManager(); @@ -96,16 +110,14 @@ private: void flushEntireTLB(); void flushTLB(LinearAddress); - PhysicalAddress allocate_page_table(); - void deallocate_page_table(PhysicalAddress); + RetainPtr<PhysicalPage> allocate_page_table(PageDirectory&, unsigned index); + void deallocate_page_table(PageDirectory&, unsigned index); void protectMap(LinearAddress, size_t length); void create_identity_mapping(LinearAddress, size_t length); void remove_identity_mapping(LinearAddress, size_t); - Vector<PhysicalAddress> allocatePhysicalPages(size_t count); - struct PageDirectoryEntry { explicit PageDirectoryEntry(dword* pde) : m_pde(pde) { } @@ -192,9 +204,7 @@ private: LinearAddress m_next_laddr; - HashTable<Zone*> m_zones; - - Vector<PhysicalAddress> m_freePages; + Vector<RetainPtr<PhysicalPage>> m_free_physical_pages; }; struct KernelPagingScope { |