speed up initial page frame loop

This commit is contained in:
nakst 2021-09-22 20:30:49 +01:00
parent 0319f08a1a
commit 5422a9e01e
3 changed files with 34 additions and 6 deletions

View File

@ -1003,6 +1003,7 @@ void ACPI::Initialise() {
uint64_t end = ProcessorReadTimeStamp(); uint64_t end = ProcessorReadTimeStamp();
timeStampTicksPerMs = (end - start) >> 3; timeStampTicksPerMs = (end - start) >> 3;
ProcessorEnableInterrupts(); ProcessorEnableInterrupts();
// EsPrint("timeStampTicksPerMs = %d\n", timeStampTicksPerMs);
// Add some entropy. // Add some entropy.
{ {

View File

@ -374,7 +374,10 @@ void MMPhysicalInsertZeroedPage(uintptr_t page) {
MMUpdateAvailablePageCount(true); MMUpdateAvailablePageCount(true);
} }
void MMPhysicalInsertFreePage(uintptr_t page) { void MMPhysicalInsertFreePagesStart() {
}
void MMPhysicalInsertFreePagesNext(uintptr_t page) {
MMPageFrame *frame = pmm.pageFrames + page; MMPageFrame *frame = pmm.pageFrames + page;
frame->state = MMPageFrame::FREE; frame->state = MMPageFrame::FREE;
@ -387,7 +390,9 @@ void MMPhysicalInsertFreePage(uintptr_t page) {
pmm.freeOrZeroedPageBitset.Put(page); pmm.freeOrZeroedPageBitset.Put(page);
pmm.countFreePages++; pmm.countFreePages++;
}
void MMPhysicalInsertFreePagesEnd() {
if (pmm.countFreePages > MM_ZERO_PAGE_THRESHOLD) { if (pmm.countFreePages > MM_ZERO_PAGE_THRESHOLD) {
KEventSet(&pmm.zeroPageEvent, false, true); KEventSet(&pmm.zeroPageEvent, false, true);
} }
@ -550,6 +555,8 @@ void MMPhysicalFree(uintptr_t page, bool mutexAlreadyAcquired, size_t count) {
page >>= K_PAGE_BITS; page >>= K_PAGE_BITS;
MMPhysicalInsertFreePagesStart();
for (uintptr_t i = 0; i < count; i++, page++) { for (uintptr_t i = 0; i < count; i++, page++) {
MMPageFrame *frame = pmm.pageFrames + page; MMPageFrame *frame = pmm.pageFrames + page;
@ -561,9 +568,11 @@ void MMPhysicalFree(uintptr_t page, bool mutexAlreadyAcquired, size_t count) {
pmm.countActivePages--; pmm.countActivePages--;
} }
MMPhysicalInsertFreePage(page); MMPhysicalInsertFreePagesNext(page);
} }
MMPhysicalInsertFreePagesEnd();
if (!mutexAlreadyAcquired) KMutexRelease(&pmm.pageFrameMutex); if (!mutexAlreadyAcquired) KMutexRelease(&pmm.pageFrameMutex);
} }
@ -2291,13 +2300,21 @@ void MMInitialise() {
pmm.freeOrZeroedPageBitset.Initialise(physicalMemoryHighest >> K_PAGE_BITS, true); pmm.freeOrZeroedPageBitset.Initialise(physicalMemoryHighest >> K_PAGE_BITS, true);
uint64_t commitLimit = 0; uint64_t commitLimit = 0;
MMPhysicalInsertFreePagesStart();
while (physicalMemoryRegionsPagesCount) { for (uintptr_t i = 0; i < physicalMemoryRegionsCount; i++) {
// TODO This loop is a bit slow... uintptr_t base = physicalMemoryRegions[i].baseAddress >> K_PAGE_BITS;
MMPhysicalInsertFreePage(MMPhysicalAllocate(ES_FLAGS_DEFAULT) >> K_PAGE_BITS); uintptr_t count = physicalMemoryRegions[i].pageCount;
commitLimit++; commitLimit += count;
for (uintptr_t j = 0; j < count; j++) {
MMPhysicalInsertFreePagesNext(base + j);
}
} }
MMPhysicalInsertFreePagesEnd();
physicalMemoryRegionsPagesCount = 0;
pmm.commitLimit = pmm.commitFixedLimit = commitLimit; pmm.commitLimit = pmm.commitFixedLimit = commitLimit;
KernelLog(LOG_INFO, "Memory", "pmm initialised", "MMInitialise - PMM initialised with a fixed commit limit of %d pages.\n", pmm.commitLimit); KernelLog(LOG_INFO, "Memory", "pmm initialised", "MMInitialise - PMM initialised with a fixed commit limit of %d pages.\n", pmm.commitLimit);
} }

View File

@ -15,7 +15,9 @@ struct Bitset {
size_t singleCount; size_t singleCount;
size_t groupCount; size_t groupCount;
#ifdef DEBUG_BUILD
bool modCheck; bool modCheck;
#endif
}; };
#else #else
@ -36,8 +38,10 @@ void Bitset::PutAll() {
} }
uintptr_t Bitset::Get(size_t count, uintptr_t align, uintptr_t below) { uintptr_t Bitset::Get(size_t count, uintptr_t align, uintptr_t below) {
#ifdef DEBUG_BUILD
if (modCheck) KernelPanic("Bitset::Allocate - Concurrent modification.\n"); if (modCheck) KernelPanic("Bitset::Allocate - Concurrent modification.\n");
modCheck = true; EsDefer({modCheck = false;}); modCheck = true; EsDefer({modCheck = false;});
#endif
uintptr_t returnValue = (uintptr_t) -1; uintptr_t returnValue = (uintptr_t) -1;
@ -148,20 +152,25 @@ bool Bitset::Read(uintptr_t index) {
} }
void Bitset::Take(uintptr_t index) { void Bitset::Take(uintptr_t index) {
#ifdef DEBUG_BUILD
if (modCheck) KernelPanic("Bitset::Take - Concurrent modification.\n"); if (modCheck) KernelPanic("Bitset::Take - Concurrent modification.\n");
modCheck = true; EsDefer({modCheck = false;}); modCheck = true; EsDefer({modCheck = false;});
#endif
uintptr_t group = index / BITSET_GROUP_SIZE; uintptr_t group = index / BITSET_GROUP_SIZE;
#ifdef DEBUG_BUILD
if (!(singleUsage[index >> 5] & (1 << (index & 31)))) { if (!(singleUsage[index >> 5] & (1 << (index & 31)))) {
KernelPanic("Bitset::Take - Attempting to take a entry that has already been taken.\n"); KernelPanic("Bitset::Take - Attempting to take a entry that has already been taken.\n");
} }
#endif
groupUsage[group]--; groupUsage[group]--;
singleUsage[index >> 5] &= ~(1 << (index & 31)); singleUsage[index >> 5] &= ~(1 << (index & 31));
} }
void Bitset::Put(uintptr_t index) { void Bitset::Put(uintptr_t index) {
#ifdef DEBUG_BUILD
if (modCheck) KernelPanic("Bitset::Put - Concurrent modification.\n"); if (modCheck) KernelPanic("Bitset::Put - Concurrent modification.\n");
modCheck = true; EsDefer({modCheck = false;}); modCheck = true; EsDefer({modCheck = false;});
@ -172,6 +181,7 @@ void Bitset::Put(uintptr_t index) {
if (singleUsage[index >> 5] & (1 << (index & 31))) { if (singleUsage[index >> 5] & (1 << (index & 31))) {
KernelPanic("Bitset::Put - Duplicate entry.\n"); KernelPanic("Bitset::Put - Duplicate entry.\n");
} }
#endif
{ {
singleUsage[index >> 5] |= 1 << (index & 31); singleUsage[index >> 5] |= 1 << (index & 31);