From c8a7775b4f605b92c4e5b72f03a16f82f9e4482a Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 21 Jan 2020 01:08:28 +0100 Subject: [PATCH] More improvements in allocator --- include/mm/palloc.h | 5 +- kaleid/kernel/mm/paging.c | 2 +- kaleid/kernel/mm/palloc.c | 174 ++++++++++++++++-------------------- kaleid/kernel/sh/testcmds.c | 6 +- 4 files changed, 84 insertions(+), 103 deletions(-) diff --git a/include/mm/palloc.h b/include/mm/palloc.h index 98dc5b2..518aea7 100644 --- a/include/mm/palloc.h +++ b/include/mm/palloc.h @@ -32,7 +32,8 @@ //----------------------------------------------------------------------------// typedef struct AllocatedPage_t{ - void *phyAddress; + void *phyAddressBegin; + void *phyAddressEnd; ulong id; struct AllocatedPage_t *next; } AllocatedPage_t; @@ -46,7 +47,7 @@ ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, ulong MmAllocPageFrame(size_t size, bool contiguous); void MmFreePageFrame(ulong id); -error_t MmTestBusyPage(void); +error_t MmTestBusyPage(ulong size, ulong flags); //----------------------------------------------------------------------------// diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c index 7a42a1a..f7ca459 100644 --- a/kaleid/kernel/mm/paging.c +++ b/kaleid/kernel/mm/paging.c @@ -276,7 +276,7 @@ ulong *MmGetPageDescriptorFromVirtual(void *virtualAddr) pd = (pde_t *)((ulong)pdp[pdpIndex] & 0xFFFFFFFFFF000); } - DebugLog("\tPD[%d] = %p\n", pdIndex, pd[pdIndex]); + //DebugLog("\tPD[%d] = %p\n", pdIndex, pd[pdIndex]); // Select bit from 12 to 51 if (!((ulong)pd[pdIndex] & 0xFFFFFFFFFF000)) { diff --git a/kaleid/kernel/mm/palloc.c b/kaleid/kernel/mm/palloc.c index b9e3761..6a8e229 100644 --- a/kaleid/kernel/mm/palloc.c +++ b/kaleid/kernel/mm/palloc.c @@ -40,7 +40,7 @@ enum Whatever2 = 1UL << 62 }; -static AllocatedPage_t busyPagesList = { (void*)0, 0, (AllocatedPage_t*)0 }; +static AllocatedPage_t busyPagesList = { (void*)0, (void*)0, 0, (AllocatedPage_t*)0 }; extern MemoryMap_t memoryMap; extern ulong MmPhysLastKernAddress; @@ -49,10 +49,11 @@ static ulong NSuccessfulFree = 0; //--------- -static bool isPageBusy(void *phyPageAddr) +// Returns 0 if page is not busy, its last address if yes +static ulong isPageBusy(void *phyPageAddr) { AllocatedPage_t *busyPage = &busyPagesList; - bool isBusy = false; + ulong isBusy = 0; // In case of NVS, ACPI or BADRAM zone, considered busy if (!MmGetAvailZoneSize(phyPageAddr)) @@ -61,8 +62,10 @@ static bool isPageBusy(void *phyPageAddr) // Search in the busylist if the phy addr is here while(busyPage->next) { busyPage = busyPage->next; - if (phyPageAddr == busyPage->phyAddress) { - isBusy = true; + if (phyPageAddr >= busyPage->phyAddressBegin + && phyPageAddr <= busyPage->phyAddressEnd + ) { + isBusy = (ulong)busyPage->phyAddressEnd; break; } } @@ -78,7 +81,8 @@ static void printBusyPages(void) } else { while(busyPage->next) { busyPage = busyPage->next; - KernLog("Busy page at %p\n", busyPage->phyAddress); + KernLog("Busy page at %p-%p\n", busyPage->phyAddressBegin, + busyPage->phyAddressEnd); } } } @@ -93,14 +97,14 @@ static ulong MmBusyPagesSpace(void) } else { while(busyPage->next) { busyPage = busyPage->next; - c += 4096; + c += 4096 + (busyPage->phyAddressEnd - busyPage->phyAddressBegin); } } return c; } -static void addPageToBusyList(void *phyPageAddr, ulong id) +static void addPageToBusyList(void *phyPageAddrBegin, void *phyPageAddrEnd, ulong id) { AllocatedPage_t *busyPage = &busyPagesList; AllocatedPage_t *prevBusyPage = NULL; @@ -109,7 +113,7 @@ static void addPageToBusyList(void *phyPageAddr, ulong id) prevBusyPage = busyPage; busyPage = busyPage->next; - if (busyPage->phyAddress > phyPageAddr) { + if (busyPage->phyAddressBegin > phyPageAddrEnd) { busyPage = prevBusyPage; break; } @@ -117,13 +121,14 @@ static void addPageToBusyList(void *phyPageAddr, ulong id) AllocatedPage_t *newBusyPage = (AllocatedPage_t*)malloc(sizeof(AllocatedPage_t)); - newBusyPage->phyAddress = phyPageAddr; + newBusyPage->phyAddressBegin = phyPageAddrBegin; + newBusyPage->phyAddressEnd = phyPageAddrEnd; newBusyPage->id = id; newBusyPage->next = busyPage->next; busyPage->next = newBusyPage; } -static void removePageFromBusyList(void *phyPageAddr) +static void removePageFromBusyList(void *phyPageAddrBegin) { AllocatedPage_t *busyPage = &busyPagesList; AllocatedPage_t *prevBusyPage = NULL; @@ -132,7 +137,7 @@ static void removePageFromBusyList(void *phyPageAddr) prevBusyPage = busyPage; busyPage = busyPage->next; - if (phyPageAddr == busyPage->phyAddress) { + if (phyPageAddrBegin == busyPage->phyAddressBegin) { prevBusyPage->next = busyPage->next; free(busyPage); break; @@ -143,15 +148,17 @@ static void removePageFromBusyList(void *phyPageAddr) // // Returns an id to identify a page frame allocated (kernel) // -ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, - bool contiguous) +ulong MmAllocPageFrame(size_t size, bool contiguous) { static ulong id = 0; - *pageNumber = (((ulong)size - 1) / KPAGESIZE) + 1; + ulong pageNumber = (((ulong)size - 1) / KPAGESIZE) + 1; - *frameListPtr = (void**)malloc(sizeof(void*)*(*pageNumber)); size_t curNumber = 0; - bool inBlock = false; + + void *futureBegin = 0; + void *futureEnd = 0; + + ulong busyLastAddr = 0; // Incrementing id id++; @@ -159,61 +166,48 @@ ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, // Maximum PHYSICAL address in memory ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize; - ////DebugLog("Allocating %d pages...\n", *pageNumber); - if (contiguous) { - for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); - curPage < (void*)phRamSize; curPage += KPAGESIZE) { - if (!isPageBusy(curPage)) { - (*frameListPtr)[curNumber] = curPage; - inBlock = true; - ////DebugLog("Select page : %p\n", curPage); - if (++curNumber >= *pageNumber) { - break; - } + DebugLog("Allocating %d pages...\n", pageNumber); + for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); + curPage < (void*)phRamSize; curPage += KPAGESIZE) { + busyLastAddr = isPageBusy(curPage); + + if (!busyLastAddr) { + + if (!futureBegin) { + futureBegin = curPage; + //DebugLog("Select begin : %p\n", curPage); + } + + futureEnd = curPage; + //DebugLog("Select page : %p\n", curPage); + if (++curNumber >= pageNumber) { + break; + } + + } else { + if (!contiguous) { + if (futureBegin && futureEnd) + addPageToBusyList(futureBegin, futureEnd, id); + futureBegin = 0; } else { - inBlock = false; - } - if (contiguous) - if (!inBlock) - curNumber = 0; - } - } else { - for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); - curPage < (void*)phRamSize; curPage += KPAGESIZE) { - if (!isPageBusy(curPage)) { - (*frameListPtr)[curNumber] = curPage; - ////DebugLog("Select page : %p\n", curPage); - if (++curNumber >= *pageNumber) { - break; - } + curNumber = 0; + futureBegin = 0; } } } - if (curNumber != *pageNumber) { - KeStartPanic("MmAllocPageFrameEx() : No more free pages to allocate"); + if (curNumber != pageNumber) { + KeStartPanic("MmAllocPageFrame() : No more free pages to allocate"); } - for (size_t i = 0; i < *pageNumber; i++) { - addPageToBusyList((*frameListPtr)[i], id); - ////DebugLog("Allocating page : %p\n", *frameListPtr[i]); - } + if (futureBegin && futureEnd) + addPageToBusyList(futureBegin, futureEnd, id); NSuccessfulAlloc++; return id; } -ulong MmAllocPageFrame(size_t size, bool contiguous) -{ - void **ptr = NULL; - ulong d = 0; - return MmAllocPageFrameEx(&ptr, &d, size, contiguous); - (void)ptr; - (void)d; -} - - // // Frees a page frame by its id // @@ -226,7 +220,7 @@ void MmFreePageFrame(ulong id) busyPage = busyPage->next; if (id == busyPage->id) { - removePageFromBusyList(busyPage->phyAddress); + removePageFromBusyList(busyPage->phyAddressBegin); success = true; } } @@ -245,14 +239,15 @@ error_t MmMapPageFrame(ulong id, void *virtAddr, ulong flags) while(busyPage->next) { busyPage = busyPage->next; - if (MmTransPhyToVirtAddr(busyPage->phyAddress)) { - return EADDRINUSE; - } - if (id == busyPage->id) { - DebugLog("Map %p at %p\n", busyPage->phyAddress, virtAddr); - MmMapPage((void*)((ulong)virtAddr), busyPage->phyAddress, flags); - virtAddr += KPAGESIZE; + for (void *addr = busyPage->phyAddressBegin; addr <= busyPage->phyAddressEnd; addr += KPAGESIZE) { + if (MmTransPhyToVirtAddr(addr)) { + return EADDRINUSE; + } + //DebugLog("Map %p at %p\n", addr, virtAddr); + MmMapPage((void*)((ulong)virtAddr), (void*)addr, flags); + virtAddr += KPAGESIZE; + } } } @@ -266,10 +261,15 @@ error_t MmUnmapPageFrame(ulong id) while(busyPage->next) { busyPage = busyPage->next; - actualPhys = MmTransPhyToVirtAddr(busyPage->phyAddress); - if (actualPhys && id == busyPage->id) { - MmUnmapPage(MmTransPhyToVirtAddr(busyPage->phyAddress)); + if (id == busyPage->id) { + for (void *addr = busyPage->phyAddressBegin; addr <= busyPage->phyAddressEnd; addr += KPAGESIZE) { + actualPhys = MmTransPhyToVirtAddr(addr); + //DebugLog("Map %p at %p\n", addr, virtAddr); + if (actualPhys && id == busyPage->id) { + MmUnmapPage(MmTransPhyToVirtAddr(addr)); + } + } } } @@ -278,10 +278,8 @@ error_t MmUnmapPageFrame(ulong id) ulong tab[4000] = {0}; -error_t MmTestBusyPage(void) +error_t MmTestBusyPage(ulong size, ulong flags) { - int j = 0; - /* for (int i = 0; i < 2000; i++) { */ /* if (rand() %2) { */ /* if (rand() %2) { */ @@ -296,41 +294,23 @@ error_t MmTestBusyPage(void) /* } */ ulong a = KeGetTicks(); - DebugLog("Start alloc 30 MB: %lu s\n", a/1000); - tab[0] = MmAllocPageFrame(100*MB, NORMAL); + DebugLog("Start alloc 1: %lu s\n", a/1000); + tab[0] = MmAllocPageFrame(size*KB, NORMAL); ulong b = KeGetTicks(); DebugLog("End alloc : %lu s\n", b/1000); DebugLog("Alloc time : %lu s\n", (b-a)/1000); DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB); - /* a = KeGetTicks(); */ - /* DebugLog("Start alloc 30MB : %lu s\n", a/1000); */ - /* tab[j++] = MmAllocPageFrame(5*MB, NORMAL); */ - /* b = KeGetTicks(); */ - /* DebugLog("End alloc : %lu s\n", b/1000); */ - /* DebugLog("Alloc time : %lu s\n", (b-a)/1000); */ - /* DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB); */ - - /* j = 0; */ - - /* a = KeGetTicks(); */ - /* DebugLog("Start free : %lu ms\n", a); */ - /* MmFreePageFrame(tab[j++]); */ - /* b = KeGetTicks(); */ - /* DebugLog("End free : %lu ms\n", b); */ - /* DebugLog("Free time : %lu ms\n", (b-a)); */ - /* DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB); */ + printBusyPages(); a = KeGetTicks(); - DebugLog("Start map at %p: %lu ms\n", USERSPACE, a); - MmMapPageFrame(tab[0], (void*)(USERSPACE), PRESENT | READWRITE | USERSPACE); + DebugLog("Start map at %p wit %p: %lu ms\n", USERSPACE, flags, a); + MmMapPageFrame(tab[0], (void*)(USERSPACE), flags); b = KeGetTicks(); DebugLog("End map : %lu ms\n", b); DebugLog("Map time : %lu ms\n", (b-a)); - //printBusyPages(); - - //DebugLog("Finished !\n"); + DebugLog("Finished !\n"); return EOK; } diff --git a/kaleid/kernel/sh/testcmds.c b/kaleid/kernel/sh/testcmds.c index 9d9895e..c5bd3e0 100644 --- a/kaleid/kernel/sh/testcmds.c +++ b/kaleid/kernel/sh/testcmds.c @@ -239,9 +239,9 @@ error_t CmdPageUnmap(int argc, char **argv, char *cmdline) return EOK; } -error_t CmdPageBlock(int argc, char **argv, char *cmdline) +error_t CmdPageAlloc(int argc, char **argv, char *cmdline) { - error_t err = MmTestBusyPage(); + error_t err = MmTestBusyPage(strtoul(argv[1], NULL, 0), strtoul(argv[2], NULL, 0)); return err; } @@ -311,7 +311,7 @@ static Command_t testcmdtable[] = " virtual address (paging)"}, { "pmap", CmdPageMap, "Map a page to given physical addr" }, { "punmap", CmdPageUnmap, "Unmap a page" }, - { "pblck", CmdPageBlock, "Find a free block of pages" }, + { "palloc", CmdPageAlloc, "Alloc x KB of pages" }, { "pf", CmdPF, "Provoke a PF. Usage: pfault
"}, { "shell", CmdShell, "Start a new shell (nested)", }, { "stkov", CmdStackOverflow, "Provoke a stack overflow" },