summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-28 10:26:07 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-10-28 10:28:21 +0100
commitc76dc9a047c54293f148b3b35c5e538ed2871ed1 (patch)
tree9e8bd3172f8264999fffb788b8b8dde1d8bcc1b0 /Kernel
parent0a6a2521e8f32a434dc0bf824c7ad1e2b989088a (diff)
downloadserenity-c76dc9a047c54293f148b3b35c5e538ed2871ed1.zip
Add /proc/mm and a /bin/mm utility that just dumps it.
This shows some info about the MM. Right now it's just the zone count and the number of free physical pages. Lots more can be added. Also added "exit" to sh so we can nest shells and exit from them. I also noticed that we were leaking all the physical pages, so fixed that.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/MemoryManager.cpp42
-rw-r--r--Kernel/MemoryManager.h15
-rw-r--r--Kernel/ProcFileSystem.cpp13
-rwxr-xr-xKernel/sync-sh1
4 files changed, 54 insertions, 17 deletions
diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp
index 0f32eb9679..c22e8b3e0e 100644
--- a/Kernel/MemoryManager.cpp
+++ b/Kernel/MemoryManager.cpp
@@ -34,9 +34,7 @@ void MemoryManager::initializePaging()
memset(m_pageTableOne, 0, 4096);
memset(m_pageDirectory, 0, 4096);
- kprintf("MM: Page directory @ %p\n", m_pageDirectory);
- kprintf("MM: Page table zero @ %p\n", m_pageTableZero);
- kprintf("MM: Page table one @ %p\n", m_pageTableOne);
+ kprintf("[MM] Page directory @ %p\n", m_pageDirectory);
// Make null dereferences crash.
protectMap(LinearAddress(0), 4 * KB);
@@ -72,7 +70,7 @@ auto MemoryManager::ensurePTE(LinearAddress linearAddress) -> PageTableEntry
PageDirectoryEntry pde = PageDirectoryEntry(&m_pageDirectory[pageDirectoryIndex]);
if (!pde.isPresent()) {
- kprintf("PDE %u !present, allocating\n", pageDirectoryIndex);
+ kprintf("[MM] PDE %u not present, allocating\n", pageDirectoryIndex);
if (pageDirectoryIndex == 0) {
pde.setPageTableBase((dword)m_pageTableZero);
pde.setUserAllowed(true);
@@ -85,7 +83,7 @@ auto MemoryManager::ensurePTE(LinearAddress linearAddress) -> PageTableEntry
pde.setWritable(true);
} else {
auto* pageTable = allocatePageTable();
- kprintf("allocated page table %u (for laddr=%p) at %p\n", pageDirectoryIndex, linearAddress.get(), pageTable);
+ kprintf("[MM] Allocated page table #%u (for laddr=%p) at %p\n", pageDirectoryIndex, linearAddress.get(), pageTable);
memset(pageTable, 0, 4096);
pde.setPageTableBase((dword)pageTable);
pde.setUserAllowed(true);
@@ -134,7 +132,7 @@ void MemoryManager::initialize()
PageFaultResponse MemoryManager::handlePageFault(const PageFault& fault)
{
ASSERT_INTERRUPTS_DISABLED();
- kprintf("MM: handlePageFault(%w) at laddr=%p\n", fault.code(), fault.address().get());
+ kprintf("[MM] handlePageFault(%w) at laddr=%p\n", fault.code(), fault.address().get());
if (fault.isNotPresent()) {
kprintf(" >> NP fault!\n");
} else if (fault.isProtectionViolation()) {
@@ -143,11 +141,36 @@ PageFaultResponse MemoryManager::handlePageFault(const PageFault& fault)
return PageFaultResponse::ShouldCrash;
}
+void MemoryManager::registerZone(Zone& zone)
+{
+ ASSERT_INTERRUPTS_DISABLED();
+ m_zones.set(&zone);
+}
+
+void MemoryManager::unregisterZone(Zone& zone)
+{
+ ASSERT_INTERRUPTS_DISABLED();
+ m_zones.remove(&zone);
+ m_freePages.append(move(zone.m_pages));
+}
+
+Zone::Zone(Vector<PhysicalAddress>&& pages)
+ : m_pages(move(pages))
+{
+ MM.registerZone(*this);
+}
+
+Zone::~Zone()
+{
+ MM.unregisterZone(*this);
+}
+
RetainPtr<Zone> MemoryManager::createZone(size_t size)
{
+ InterruptDisabler disabler;
auto pages = allocatePhysicalPages(ceilDiv(size, PAGE_SIZE));
if (pages.isEmpty()) {
- kprintf("MM: createZone: no physical pages for size %u", size);
+ kprintf("[MM] createZone: no physical pages for size %u", size);
return nullptr;
}
return adopt(*new Zone(move(pages)));
@@ -170,7 +193,7 @@ byte* MemoryManager::quickMapOnePage(PhysicalAddress physicalAddress)
{
ASSERT_INTERRUPTS_DISABLED();
auto pte = ensurePTE(LinearAddress(4 * MB));
- kprintf("quickmap %x @ %x {pte @ %p}\n", physicalAddress.get(), 4*MB, pte.ptr());
+ kprintf("[MM] quickmap %x @ %x {pte @ %p}\n", physicalAddress.get(), 4*MB, pte.ptr());
pte.setPhysicalPageBase(physicalAddress.pageBase());
pte.setPresent(true);
pte.setWritable(true);
@@ -297,7 +320,7 @@ bool MemoryManager::mapRegionsForTask(Task& task)
bool copyToZone(Zone& zone, const void* data, size_t size)
{
if (zone.size() < size) {
- kprintf("copyToZone: can't fit %u bytes into zone with size %u\n", size, zone.size());
+ kprintf("[MM] copyToZone: can't fit %u bytes into zone with size %u\n", size, zone.size());
return false;
}
@@ -314,4 +337,3 @@ bool copyToZone(Zone& zone, const void* data, size_t size)
return true;
}
-
diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h
index 0c88607433..4ed3ff66f7 100644
--- a/Kernel/MemoryManager.h
+++ b/Kernel/MemoryManager.h
@@ -5,7 +5,7 @@
#include <AK/Retainable.h>
#include <AK/RetainPtr.h>
#include <AK/Vector.h>
-#include <AK/HashMap.h>
+#include <AK/HashTable.h>
#include "Task.h"
class Task;
@@ -17,7 +17,7 @@ enum class PageFaultResponse {
struct Zone : public Retainable<Zone> {
public:
- ~Zone() { }
+ ~Zone();
size_t size() const { return m_pages.size() * PAGE_SIZE; }
const Vector<PhysicalAddress>& pages() const { return m_pages; }
@@ -25,10 +25,7 @@ public:
private:
friend class MemoryManager;
friend bool copyToZone(Zone&, const void* data, size_t);
- explicit Zone(Vector<PhysicalAddress>&& pages)
- : m_pages(move(pages))
- {
- }
+ explicit Zone(Vector<PhysicalAddress>&&);
Vector<PhysicalAddress> m_pages;
};
@@ -38,6 +35,7 @@ bool copyToZone(Zone&, const void* data, size_t);
#define MM MemoryManager::the()
class MemoryManager {
+ friend ByteBuffer procfs$mm();
public:
static MemoryManager& the() PURE;
@@ -62,6 +60,9 @@ public:
bool mapRegionsForTask(Task&);
bool unmapRegionsForTask(Task&);
+ void registerZone(Zone&);
+ void unregisterZone(Zone&);
+
private:
MemoryManager();
~MemoryManager();
@@ -161,7 +162,7 @@ private:
dword* m_pageTableZero;
dword* m_pageTableOne;
- HashMap<int, RetainPtr<Zone>> m_zones;
+ HashTable<Zone*> m_zones;
Vector<PhysicalAddress> m_freePages;
};
diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp
index 8457361cf4..f7b7f3f5cb 100644
--- a/Kernel/ProcFileSystem.cpp
+++ b/Kernel/ProcFileSystem.cpp
@@ -118,6 +118,18 @@ void ProcFileSystem::removeProcess(Task& task)
m_pid2inode.remove(pid);
}
+ByteBuffer procfs$mm()
+{
+ InterruptDisabler disabler;
+ auto buffer = ByteBuffer::createUninitialized(1024);
+ char* ptr = (char*)buffer.pointer();
+ ptr += ksprintf(ptr, "Zone count: %u\n", MM.m_zones.size());
+ ptr += ksprintf(ptr, "Free physical pages: %u\n", MM.m_freePages.size());
+ buffer.trim(ptr - (char*)buffer.pointer());
+ return buffer;
+}
+
+
ByteBuffer procfs$mounts()
{
InterruptDisabler disabler;
@@ -171,6 +183,7 @@ ByteBuffer procfs$summary()
bool ProcFileSystem::initialize()
{
SyntheticFileSystem::initialize();
+ addFile(createGeneratedFile("mm", procfs$mm));
addFile(createGeneratedFile("mounts", procfs$mounts));
addFile(createGeneratedFile("kmalloc", procfs$kmalloc));
addFile(createGeneratedFile("summary", procfs$summary));
diff --git a/Kernel/sync-sh b/Kernel/sync-sh
index 8584eaa626..4847c68a40 100755
--- a/Kernel/sync-sh
+++ b/Kernel/sync-sh
@@ -15,6 +15,7 @@ cp ../Userland/cat mnt/bin/cat
cp ../Userland/uname mnt/bin/uname
cp ../Userland/clear mnt/bin/clear
cp ../Userland/tst mnt/bin/tst
+cp ../Userland/mm mnt/bin/mm
cp kernel.map mnt/
umount mnt
sync