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
Notes: sideshowbarker 2024-07-19 18:34:40 +09:00
6 changed files with 40 additions and 21 deletions

View file

@ -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);

View file

@ -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 };

View file

@ -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;

View file

@ -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&);

View file

@ -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");

View file

@ -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];