1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-19 04:05:07 +00:00

Use a freelist for GDT entries.

Tweak the kmalloc space layout a bit. Get the spawn stress test up
and running again.
This commit is contained in:
Andreas Kling 2018-11-01 16:23:12 +01:00
parent 9da4864a9a
commit c70afd045e
6 changed files with 40 additions and 21 deletions

View file

@ -62,7 +62,7 @@ static bool contextSwitch(Process*);
static void redoKernelProcessTSS() static void redoKernelProcessTSS()
{ {
if (!s_kernelProcess->selector()) if (!s_kernelProcess->selector())
s_kernelProcess->setSelector(allocateGDTEntry()); s_kernelProcess->setSelector(gdt_alloc_entry());
auto& tssDescriptor = getGDTEntry(s_kernelProcess->selector()); auto& tssDescriptor = getGDTEntry(s_kernelProcess->selector());
@ -109,14 +109,14 @@ void Process::allocateLDT()
{ {
ASSERT(!m_tss.ldt); ASSERT(!m_tss.ldt);
static const WORD numLDTEntries = 4; static const WORD numLDTEntries = 4;
WORD newLDTSelector = allocateGDTEntry(); m_ldt_selector = gdt_alloc_entry();
m_ldtEntries = new Descriptor[numLDTEntries]; m_ldtEntries = new Descriptor[numLDTEntries];
#if 0 #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 at = %p\n", m_ldtEntries);
kprintf("new ldt table size = %u\n", (numLDTEntries * 8) - 1); kprintf("new ldt table size = %u\n", (numLDTEntries * 8) - 1);
#endif #endif
Descriptor& ldt = getGDTEntry(newLDTSelector); Descriptor& ldt = getGDTEntry(m_ldt_selector);
ldt.setBase(m_ldtEntries); ldt.setBase(m_ldtEntries);
ldt.setLimit(numLDTEntries * 8 - 1); ldt.setLimit(numLDTEntries * 8 - 1);
ldt.dpl = 0; ldt.dpl = 0;
@ -126,7 +126,7 @@ void Process::allocateLDT()
ldt.operation_size = 1; ldt.operation_size = 1;
ldt.descriptor_type = 0; ldt.descriptor_type = 0;
ldt.type = Descriptor::LDT; ldt.type = Descriptor::LDT;
m_tss.ldt = newLDTSelector; m_tss.ldt = m_ldt_selector;
} }
Vector<Process*> Process::allProcesses() Vector<Process*> Process::allProcesses()
@ -489,8 +489,14 @@ Process::~Process()
InterruptDisabler disabler; InterruptDisabler disabler;
ProcFileSystem::the().removeProcess(*this); ProcFileSystem::the().removeProcess(*this);
system.nprocess--; system.nprocess--;
if (isRing3()) {
delete [] m_ldtEntries; delete [] m_ldtEntries;
m_ldtEntries = nullptr; m_ldtEntries = nullptr;
gdt_free_entry(m_ldt_selector);
}
gdt_free_entry(selector());
if (m_kernelStack) { if (m_kernelStack) {
kfree(m_kernelStack); kfree(m_kernelStack);
@ -754,7 +760,7 @@ static bool contextSwitch(Process* t)
t->set_state(Process::Running); t->set_state(Process::Running);
if (!t->selector()) { if (!t->selector()) {
t->setSelector(allocateGDTEntry()); t->setSelector(gdt_alloc_entry());
auto& descriptor = getGDTEntry(t->selector()); auto& descriptor = getGDTEntry(t->selector());
descriptor.setBase(&t->tss()); descriptor.setBase(&t->tss());
descriptor.setLimit(0xffff); descriptor.setLimit(0xffff);

View file

@ -167,6 +167,7 @@ private:
State m_state { Invalid }; State m_state { Invalid };
DWORD m_wakeupTime { 0 }; DWORD m_wakeupTime { 0 };
TSS32 m_tss; TSS32 m_tss;
word m_ldt_selector { 0 };
Descriptor* m_ldtEntries { nullptr }; Descriptor* m_ldtEntries { nullptr };
Vector<OwnPtr<FileHandle>> m_file_descriptors; Vector<OwnPtr<FileHandle>> m_file_descriptors;
RingLevel m_ring { Ring0 }; RingLevel m_ring { Ring0 };

View file

@ -20,15 +20,20 @@ static Descriptor* s_gdt;
static IRQHandler** s_irqHandler; static IRQHandler** s_irqHandler;
static Vector<word, KmallocEternalAllocator>* s_gdt_freelist;
static WORD s_gdtLength; static WORD s_gdtLength;
WORD allocateGDTEntry() word gdt_alloc_entry()
{ {
// FIXME: This should not grow indefinitely. ASSERT(s_gdt_freelist);
ASSERT(s_gdtLength < 256); ASSERT(!s_gdt_freelist->isEmpty());
WORD newGDTEntry = s_gdtLength * 8; return s_gdt_freelist->takeLast();
s_gdtLength++; }
return newGDTEntry;
void gdt_free_entry(word entry)
{
s_gdt_freelist->append(entry);
} }
extern "C" void handleIRQ(); extern "C" void handleIRQ();
@ -310,6 +315,12 @@ void gdt_init()
s_gdt = static_cast<Descriptor*>(kmalloc_eternal(sizeof(Descriptor) * 256)); s_gdt = static_cast<Descriptor*>(kmalloc_eternal(sizeof(Descriptor) * 256));
s_gdtLength = 5; 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.address = s_gdt;
s_gdtr.size = (s_gdtLength * 8) - 1; s_gdtr.size = (s_gdtLength * 8) - 1;

View file

@ -66,7 +66,8 @@ void unregisterIRQHandler(BYTE number, IRQHandler&);
void flushIDT(); void flushIDT();
void flushGDT(); void flushGDT();
void loadTaskRegister(WORD selector); void loadTaskRegister(WORD selector);
WORD allocateGDTEntry(); word gdt_alloc_entry();
void gdt_free_entry(word);
Descriptor& getGDTEntry(WORD selector); Descriptor& getGDTEntry(WORD selector);
void writeGDTEntry(WORD selector, Descriptor&); void writeGDTEntry(WORD selector, Descriptor&);

View file

@ -106,13 +106,13 @@ static void spawn_stress()
{ {
dword lastAlloc = sum_alloc; dword lastAlloc = sum_alloc;
for (unsigned i = 0; i < 100; ++i) { for (unsigned i = 0; i < 10000; ++i) {
int error; int error;
Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0); 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); kprintf("delta:%u\n", sum_alloc - lastAlloc);
lastAlloc = sum_alloc; lastAlloc = sum_alloc;
sleep(600); sleep(60);
} }
for (;;) { for (;;) {
asm volatile("hlt"); asm volatile("hlt");

View file

@ -22,9 +22,9 @@ typedef struct
#define CHUNK_SIZE 128 #define CHUNK_SIZE 128
#define POOL_SIZE (1024 * 1024) #define POOL_SIZE (1024 * 1024)
#define PAGE_ALIGNED_BASE_PHYSICAL 0x380000 #define PAGE_ALIGNED_BASE_PHYSICAL 0x300000
#define ETERNAL_BASE_PHYSICAL 0x300000 #define ETERNAL_BASE_PHYSICAL 0x200000
#define BASE_PHYS 0x200000 #define BASE_PHYS 0x100000
PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8]; PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8];