diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp index 620e3d9b39..ff965ceb5e 100644 --- a/Kernel/MemoryManager.cpp +++ b/Kernel/MemoryManager.cpp @@ -619,6 +619,8 @@ Region::Region(LinearAddress a, size_t s, String&& n, bool r, bool w, bool cow) , is_writable(w) , cow_map(Bitmap::create(m_vmo->page_count(), cow)) { + m_vmo->set_name(name); + MM.register_region(*this); } Region::Region(LinearAddress a, size_t s, RetainPtr&& vnode, String&& n, bool r, bool w) @@ -630,6 +632,7 @@ Region::Region(LinearAddress a, size_t s, RetainPtr&& v , is_writable(w) , cow_map(Bitmap::create(m_vmo->page_count())) { + MM.register_region(*this); } Region::Region(LinearAddress a, size_t s, RetainPtr&& vmo, size_t offset_in_vmo, String&& n, bool r, bool w, bool cow) @@ -642,10 +645,12 @@ Region::Region(LinearAddress a, size_t s, RetainPtr&& vmo, size_t offs , is_writable(w) , cow_map(Bitmap::create(m_vmo->page_count(), cow)) { + MM.register_region(*this); } Region::~Region() { + MM.unregister_region(*this); } void PhysicalPage::return_to_freelist() @@ -738,10 +743,24 @@ int Region::commit(Process& process) void MemoryManager::register_vmo(VMObject& vmo) { + InterruptDisabler disabler; m_vmos.set(&vmo); } void MemoryManager::unregister_vmo(VMObject& vmo) { + InterruptDisabler disabler; m_vmos.remove(&vmo); } + +void MemoryManager::register_region(Region& region) +{ + InterruptDisabler disabler; + m_regions.set(®ion); +} + +void MemoryManager::unregister_region(Region& region) +{ + InterruptDisabler disabler; + m_regions.remove(®ion); +} diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h index 14c3ec69da..6c4b19f7be 100644 --- a/Kernel/MemoryManager.h +++ b/Kernel/MemoryManager.h @@ -146,6 +146,7 @@ class MemoryManager { friend class Region; friend class VMObject; friend ByteBuffer procfs$mm(); + friend ByteBuffer procfs$regions(); public: static MemoryManager& the() PURE; @@ -181,6 +182,8 @@ private: void register_vmo(VMObject&); void unregister_vmo(VMObject&); + void register_region(Region&); + void unregister_region(Region&); LinearAddress allocate_linear_address_range(size_t); void map_region_at_address(PageDirectory*, Region&, LinearAddress, bool user_accessible); @@ -296,6 +299,7 @@ private: Vector> m_free_physical_pages; HashTable m_vmos; + HashTable m_regions; }; struct KernelPagingScope { diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 5e18e372f4..457397b06b 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -171,7 +171,12 @@ ByteBuffer procfs$mm() auto buffer = ByteBuffer::createUninitialized(1024 + 80 * MM.m_vmos.size()); char* ptr = (char*)buffer.pointer(); for (auto* vmo : MM.m_vmos) { - ptr += ksprintf(ptr, "VMO: %p %s (p:%u, r:%u)\n", vmo, vmo->name().characters(), vmo->page_count(), vmo->retainCount()); + ptr += ksprintf(ptr, "VMO: %p %s(%u): p:%4u %s\n", + vmo, + vmo->is_anonymous() ? "anon" : "file", + vmo->retainCount(), + vmo->page_count(), + vmo->name().characters()); } ptr += ksprintf(ptr, "VMO count: %u\n", MM.m_vmos.size()); ptr += ksprintf(ptr, "Free physical pages: %u\n", MM.m_free_physical_pages.size()); @@ -179,6 +184,22 @@ ByteBuffer procfs$mm() return buffer; } +ByteBuffer procfs$regions() +{ + // FIXME: Implement + InterruptDisabler disabler; + auto buffer = ByteBuffer::createUninitialized(1024 + 80 * MM.m_regions.size()); + char* ptr = (char*)buffer.pointer(); + for (auto* region : MM.m_regions) { + ptr += ksprintf(ptr, "Region: %p VMO=%p %s\n", + region, + ®ion->vmo(), + region->name.characters()); + } + ptr += ksprintf(ptr, "Region count: %u\n", MM.m_regions.size()); + buffer.trim(ptr - (char*)buffer.pointer()); + return buffer; +} ByteBuffer procfs$mounts() { @@ -302,6 +323,7 @@ bool ProcFileSystem::initialize() { SyntheticFileSystem::initialize(); addFile(createGeneratedFile("mm", procfs$mm)); + addFile(createGeneratedFile("regions", procfs$regions)); addFile(createGeneratedFile("mounts", procfs$mounts)); addFile(createGeneratedFile("kmalloc", procfs$kmalloc)); addFile(createGeneratedFile("summary", procfs$summary)); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 6b76380383..7f710a10fe 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -307,15 +307,11 @@ int Process::exec(const String& path, Vector&& arguments, Vector return -ENOTIMPL; } + { // Put everything into a scope so things get cleaned up before we yield-teleport into the new executable. auto vmo = VMObject::create_file_backed(descriptor->vnode(), descriptor->metadata().size); + vmo->set_name(descriptor->absolute_path()); auto* region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copyRef(), 0, "helper", true, false); -#if 0 - auto elfData = descriptor->readEntireFile(); - if (!elfData) - return -EIO; // FIXME: Get a more detailed error from VFS. -#endif - dword entry_eip = 0; PageDirectory* old_page_directory = m_page_directory; PageDirectory* new_page_directory = reinterpret_cast(kmalloc_page_aligned(sizeof(PageDirectory))); @@ -324,6 +320,7 @@ int Process::exec(const String& path, Vector&& arguments, Vector m_page_directory = new_page_directory; MM.enter_process_paging_scope(*this); + // FIXME: Should we consider doing on-demand paging here? Is it actually useful? bool success = region->page_in(*new_page_directory); ASSERT(success); @@ -400,10 +397,11 @@ int Process::exec(const String& path, Vector&& arguments, Vector #endif set_state(Skip1SchedulerPass); + } // Ready to yield-teleport! if (current == this) { bool success = Scheduler::yield(); - ASSERT(success); + ASSERT_NOT_REACHED(); } return 0;