summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-11-01 16:23:12 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-11-01 16:23:12 +0100
commitc70afd045e5b91837e77dcc7c54a44ddec39aab7 (patch)
tree09e9db03dc1587c839002bc5e8e2da93bd065357
parent9da4864a9a123ddc8b2a1d13ee86a727cac7eb67 (diff)
downloadserenity-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.cpp22
-rw-r--r--Kernel/Process.h1
-rw-r--r--Kernel/i386.cpp23
-rw-r--r--Kernel/i386.h3
-rw-r--r--Kernel/init.cpp6
-rw-r--r--Kernel/kmalloc.cpp6
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];