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
drivers
kernel
shared

View File

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

View File

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

View File

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