diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-11-01 16:23:12 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-11-01 16:23:12 +0100 |
commit | c70afd045e5b91837e77dcc7c54a44ddec39aab7 (patch) | |
tree | 09e9db03dc1587c839002bc5e8e2da93bd065357 | |
parent | 9da4864a9a123ddc8b2a1d13ee86a727cac7eb67 (diff) | |
download | serenity-c70afd045e5b91837e77dcc7c54a44ddec39aab7.zip |
Use a freelist for GDT entries.
Tweak the kmalloc space layout a bit. Get the spawn stress test up
and running again.
-rw-r--r-- | Kernel/Process.cpp | 22 | ||||
-rw-r--r-- | Kernel/Process.h | 1 | ||||
-rw-r--r-- | Kernel/i386.cpp | 23 | ||||
-rw-r--r-- | Kernel/i386.h | 3 | ||||
-rw-r--r-- | Kernel/init.cpp | 6 | ||||
-rw-r--r-- | Kernel/kmalloc.cpp | 6 |
6 files changed, 40 insertions, 21 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index d87da636f7..1c2597d042 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -62,7 +62,7 @@ static bool contextSwitch(Process*); static void redoKernelProcessTSS() { if (!s_kernelProcess->selector()) - s_kernelProcess->setSelector(allocateGDTEntry()); + s_kernelProcess->setSelector(gdt_alloc_entry()); auto& tssDescriptor = getGDTEntry(s_kernelProcess->selector()); @@ -109,14 +109,14 @@ void Process::allocateLDT() { ASSERT(!m_tss.ldt); static const WORD numLDTEntries = 4; - WORD newLDTSelector = allocateGDTEntry(); + m_ldt_selector = gdt_alloc_entry(); m_ldtEntries = new Descriptor[numLDTEntries]; #if 0 - kprintf("new ldt selector = %x\n", newLDTSelector); + kprintf("new ldt selector = %x\n", m_ldt_selector); kprintf("new ldt table at = %p\n", m_ldtEntries); kprintf("new ldt table size = %u\n", (numLDTEntries * 8) - 1); #endif - Descriptor& ldt = getGDTEntry(newLDTSelector); + Descriptor& ldt = getGDTEntry(m_ldt_selector); ldt.setBase(m_ldtEntries); ldt.setLimit(numLDTEntries * 8 - 1); ldt.dpl = 0; @@ -126,7 +126,7 @@ void Process::allocateLDT() ldt.operation_size = 1; ldt.descriptor_type = 0; ldt.type = Descriptor::LDT; - m_tss.ldt = newLDTSelector; + m_tss.ldt = m_ldt_selector; } Vector<Process*> Process::allProcesses() @@ -489,8 +489,14 @@ Process::~Process() InterruptDisabler disabler; ProcFileSystem::the().removeProcess(*this); system.nprocess--; - delete [] m_ldtEntries; - m_ldtEntries = nullptr; + + if (isRing3()) { + delete [] m_ldtEntries; + m_ldtEntries = nullptr; + gdt_free_entry(m_ldt_selector); + } + + gdt_free_entry(selector()); if (m_kernelStack) { kfree(m_kernelStack); @@ -754,7 +760,7 @@ static bool contextSwitch(Process* t) t->set_state(Process::Running); if (!t->selector()) { - t->setSelector(allocateGDTEntry()); + t->setSelector(gdt_alloc_entry()); auto& descriptor = getGDTEntry(t->selector()); descriptor.setBase(&t->tss()); descriptor.setLimit(0xffff); diff --git a/Kernel/Process.h b/Kernel/Process.h index d8be6ab6aa..27f78d461c 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -167,6 +167,7 @@ private: State m_state { Invalid }; DWORD m_wakeupTime { 0 }; TSS32 m_tss; + word m_ldt_selector { 0 }; Descriptor* m_ldtEntries { nullptr }; Vector<OwnPtr<FileHandle>> m_file_descriptors; RingLevel m_ring { Ring0 }; diff --git a/Kernel/i386.cpp b/Kernel/i386.cpp index 0a778ca9cd..9ebdd95c19 100644 --- a/Kernel/i386.cpp +++ b/Kernel/i386.cpp @@ -20,15 +20,20 @@ static Descriptor* s_gdt; static IRQHandler** s_irqHandler; +static Vector<word, KmallocEternalAllocator>* s_gdt_freelist; + static WORD s_gdtLength; -WORD allocateGDTEntry() +word gdt_alloc_entry() { - // FIXME: This should not grow indefinitely. - ASSERT(s_gdtLength < 256); - WORD newGDTEntry = s_gdtLength * 8; - s_gdtLength++; - return newGDTEntry; + ASSERT(s_gdt_freelist); + ASSERT(!s_gdt_freelist->isEmpty()); + return s_gdt_freelist->takeLast(); +} + +void gdt_free_entry(word entry) +{ + s_gdt_freelist->append(entry); } extern "C" void handleIRQ(); @@ -310,6 +315,12 @@ void gdt_init() s_gdt = static_cast<Descriptor*>(kmalloc_eternal(sizeof(Descriptor) * 256)); s_gdtLength = 5; + s_gdt_freelist = new Vector<word, KmallocEternalAllocator>(); + s_gdt_freelist->ensureCapacity(256); + for (size_t i = s_gdtLength; i < 256; ++i) + s_gdt_freelist->uncheckedAppend(i * 8); + + s_gdtLength = 256; s_gdtr.address = s_gdt; s_gdtr.size = (s_gdtLength * 8) - 1; diff --git a/Kernel/i386.h b/Kernel/i386.h index 3ffb4a8e31..f5634fe92b 100644 --- a/Kernel/i386.h +++ b/Kernel/i386.h @@ -66,7 +66,8 @@ void unregisterIRQHandler(BYTE number, IRQHandler&); void flushIDT(); void flushGDT(); void loadTaskRegister(WORD selector); -WORD allocateGDTEntry(); +word gdt_alloc_entry(); +void gdt_free_entry(word); Descriptor& getGDTEntry(WORD selector); void writeGDTEntry(WORD selector, Descriptor&); diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 1c6763d007..96ec5be317 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -106,13 +106,13 @@ static void spawn_stress() { dword lastAlloc = sum_alloc; - for (unsigned i = 0; i < 100; ++i) { + for (unsigned i = 0; i < 10000; ++i) { int error; Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0); - kprintf("malloc stats: alloc:%u free:%u\n", sum_alloc, sum_free); + kprintf("malloc stats: alloc:%u free:%u page_aligned:%u eternal:%u\n", sum_alloc, sum_free, kmalloc_page_aligned, kmalloc_sum_eternal); kprintf("delta:%u\n", sum_alloc - lastAlloc); lastAlloc = sum_alloc; - sleep(600); + sleep(60); } for (;;) { asm volatile("hlt"); diff --git a/Kernel/kmalloc.cpp b/Kernel/kmalloc.cpp index 735bc1884d..e9c6cf286c 100644 --- a/Kernel/kmalloc.cpp +++ b/Kernel/kmalloc.cpp @@ -22,9 +22,9 @@ typedef struct #define CHUNK_SIZE 128 #define POOL_SIZE (1024 * 1024) -#define PAGE_ALIGNED_BASE_PHYSICAL 0x380000 -#define ETERNAL_BASE_PHYSICAL 0x300000 -#define BASE_PHYS 0x200000 +#define PAGE_ALIGNED_BASE_PHYSICAL 0x300000 +#define ETERNAL_BASE_PHYSICAL 0x200000 +#define BASE_PHYS 0x100000 PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8]; |