More improvements in allocator

This commit is contained in:
Adrien Bourmault 2020-01-21 01:08:28 +01:00
parent e854a92753
commit c8a7775b4f
4 changed files with 84 additions and 103 deletions

View File

@ -32,7 +32,8 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
typedef struct AllocatedPage_t{ typedef struct AllocatedPage_t{
void *phyAddress; void *phyAddressBegin;
void *phyAddressEnd;
ulong id; ulong id;
struct AllocatedPage_t *next; struct AllocatedPage_t *next;
} AllocatedPage_t; } AllocatedPage_t;
@ -46,7 +47,7 @@ ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size,
ulong MmAllocPageFrame(size_t size, bool contiguous); ulong MmAllocPageFrame(size_t size, bool contiguous);
void MmFreePageFrame(ulong id); void MmFreePageFrame(ulong id);
error_t MmTestBusyPage(void); error_t MmTestBusyPage(ulong size, ulong flags);
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -276,7 +276,7 @@ ulong *MmGetPageDescriptorFromVirtual(void *virtualAddr)
pd = (pde_t *)((ulong)pdp[pdpIndex] & 0xFFFFFFFFFF000); 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 // Select bit from 12 to 51
if (!((ulong)pd[pdIndex] & 0xFFFFFFFFFF000)) { if (!((ulong)pd[pdIndex] & 0xFFFFFFFFFF000)) {

View File

@ -40,7 +40,7 @@ enum
Whatever2 = 1UL << 62 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 MemoryMap_t memoryMap;
extern ulong MmPhysLastKernAddress; 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; AllocatedPage_t *busyPage = &busyPagesList;
bool isBusy = false; ulong isBusy = 0;
// In case of NVS, ACPI or BADRAM zone, considered busy // In case of NVS, ACPI or BADRAM zone, considered busy
if (!MmGetAvailZoneSize(phyPageAddr)) if (!MmGetAvailZoneSize(phyPageAddr))
@ -61,8 +62,10 @@ static bool isPageBusy(void *phyPageAddr)
// Search in the busylist if the phy addr is here // Search in the busylist if the phy addr is here
while(busyPage->next) { while(busyPage->next) {
busyPage = busyPage->next; busyPage = busyPage->next;
if (phyPageAddr == busyPage->phyAddress) { if (phyPageAddr >= busyPage->phyAddressBegin
isBusy = true; && phyPageAddr <= busyPage->phyAddressEnd
) {
isBusy = (ulong)busyPage->phyAddressEnd;
break; break;
} }
} }
@ -78,7 +81,8 @@ static void printBusyPages(void)
} else { } else {
while(busyPage->next) { while(busyPage->next) {
busyPage = 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 { } else {
while(busyPage->next) { while(busyPage->next) {
busyPage = busyPage->next; busyPage = busyPage->next;
c += 4096; c += 4096 + (busyPage->phyAddressEnd - busyPage->phyAddressBegin);
} }
} }
return c; return c;
} }
static void addPageToBusyList(void *phyPageAddr, ulong id) static void addPageToBusyList(void *phyPageAddrBegin, void *phyPageAddrEnd, ulong id)
{ {
AllocatedPage_t *busyPage = &busyPagesList; AllocatedPage_t *busyPage = &busyPagesList;
AllocatedPage_t *prevBusyPage = NULL; AllocatedPage_t *prevBusyPage = NULL;
@ -109,7 +113,7 @@ static void addPageToBusyList(void *phyPageAddr, ulong id)
prevBusyPage = busyPage; prevBusyPage = busyPage;
busyPage = busyPage->next; busyPage = busyPage->next;
if (busyPage->phyAddress > phyPageAddr) { if (busyPage->phyAddressBegin > phyPageAddrEnd) {
busyPage = prevBusyPage; busyPage = prevBusyPage;
break; break;
} }
@ -117,13 +121,14 @@ static void addPageToBusyList(void *phyPageAddr, ulong id)
AllocatedPage_t *newBusyPage = AllocatedPage_t *newBusyPage =
(AllocatedPage_t*)malloc(sizeof(AllocatedPage_t)); (AllocatedPage_t*)malloc(sizeof(AllocatedPage_t));
newBusyPage->phyAddress = phyPageAddr; newBusyPage->phyAddressBegin = phyPageAddrBegin;
newBusyPage->phyAddressEnd = phyPageAddrEnd;
newBusyPage->id = id; newBusyPage->id = id;
newBusyPage->next = busyPage->next; newBusyPage->next = busyPage->next;
busyPage->next = newBusyPage; busyPage->next = newBusyPage;
} }
static void removePageFromBusyList(void *phyPageAddr) static void removePageFromBusyList(void *phyPageAddrBegin)
{ {
AllocatedPage_t *busyPage = &busyPagesList; AllocatedPage_t *busyPage = &busyPagesList;
AllocatedPage_t *prevBusyPage = NULL; AllocatedPage_t *prevBusyPage = NULL;
@ -132,7 +137,7 @@ static void removePageFromBusyList(void *phyPageAddr)
prevBusyPage = busyPage; prevBusyPage = busyPage;
busyPage = busyPage->next; busyPage = busyPage->next;
if (phyPageAddr == busyPage->phyAddress) { if (phyPageAddrBegin == busyPage->phyAddressBegin) {
prevBusyPage->next = busyPage->next; prevBusyPage->next = busyPage->next;
free(busyPage); free(busyPage);
break; break;
@ -143,15 +148,17 @@ static void removePageFromBusyList(void *phyPageAddr)
// //
// Returns an id to identify a page frame allocated (kernel) // Returns an id to identify a page frame allocated (kernel)
// //
ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, ulong MmAllocPageFrame(size_t size, bool contiguous)
bool contiguous)
{ {
static ulong id = 0; 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; size_t curNumber = 0;
bool inBlock = false;
void *futureBegin = 0;
void *futureEnd = 0;
ulong busyLastAddr = 0;
// Incrementing id // Incrementing id
id++; id++;
@ -159,61 +166,48 @@ ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size,
// Maximum PHYSICAL address in memory // Maximum PHYSICAL address in memory
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize; ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
////DebugLog("Allocating %d pages...\n", *pageNumber); DebugLog("Allocating %d pages...\n", pageNumber);
if (contiguous) {
for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE);
curPage < (void*)phRamSize; curPage += KPAGESIZE) { curPage < (void*)phRamSize; curPage += KPAGESIZE) {
if (!isPageBusy(curPage)) { busyLastAddr = isPageBusy(curPage);
(*frameListPtr)[curNumber] = curPage;
inBlock = true; if (!busyLastAddr) {
////DebugLog("Select page : %p\n", curPage);
if (++curNumber >= *pageNumber) { if (!futureBegin) {
futureBegin = curPage;
//DebugLog("Select begin : %p\n", curPage);
}
futureEnd = curPage;
//DebugLog("Select page : %p\n", curPage);
if (++curNumber >= pageNumber) {
break; break;
} }
} else {
if (!contiguous) {
if (futureBegin && futureEnd)
addPageToBusyList(futureBegin, futureEnd, id);
futureBegin = 0;
} else { } else {
inBlock = false;
}
if (contiguous)
if (!inBlock)
curNumber = 0; curNumber = 0;
} futureBegin = 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;
}
} }
} }
} }
if (curNumber != *pageNumber) { if (curNumber != pageNumber) {
KeStartPanic("MmAllocPageFrameEx() : No more free pages to allocate"); KeStartPanic("MmAllocPageFrame() : No more free pages to allocate");
} }
for (size_t i = 0; i < *pageNumber; i++) { if (futureBegin && futureEnd)
addPageToBusyList((*frameListPtr)[i], id); addPageToBusyList(futureBegin, futureEnd, id);
////DebugLog("Allocating page : %p\n", *frameListPtr[i]);
}
NSuccessfulAlloc++; NSuccessfulAlloc++;
return id; 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 // Frees a page frame by its id
// //
@ -226,7 +220,7 @@ void MmFreePageFrame(ulong id)
busyPage = busyPage->next; busyPage = busyPage->next;
if (id == busyPage->id) { if (id == busyPage->id) {
removePageFromBusyList(busyPage->phyAddress); removePageFromBusyList(busyPage->phyAddressBegin);
success = true; success = true;
} }
} }
@ -245,16 +239,17 @@ error_t MmMapPageFrame(ulong id, void *virtAddr, ulong flags)
while(busyPage->next) { while(busyPage->next) {
busyPage = busyPage->next; busyPage = busyPage->next;
if (MmTransPhyToVirtAddr(busyPage->phyAddress)) { if (id == busyPage->id) {
for (void *addr = busyPage->phyAddressBegin; addr <= busyPage->phyAddressEnd; addr += KPAGESIZE) {
if (MmTransPhyToVirtAddr(addr)) {
return EADDRINUSE; return EADDRINUSE;
} }
//DebugLog("Map %p at %p\n", addr, virtAddr);
if (id == busyPage->id) { MmMapPage((void*)((ulong)virtAddr), (void*)addr, flags);
DebugLog("Map %p at %p\n", busyPage->phyAddress, virtAddr);
MmMapPage((void*)((ulong)virtAddr), busyPage->phyAddress, flags);
virtAddr += KPAGESIZE; virtAddr += KPAGESIZE;
} }
} }
}
return EOK; return EOK;
} }
@ -266,10 +261,15 @@ error_t MmUnmapPageFrame(ulong id)
while(busyPage->next) { while(busyPage->next) {
busyPage = busyPage->next; busyPage = busyPage->next;
actualPhys = 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) { if (actualPhys && id == busyPage->id) {
MmUnmapPage(MmTransPhyToVirtAddr(busyPage->phyAddress)); MmUnmapPage(MmTransPhyToVirtAddr(addr));
}
}
} }
} }
@ -278,10 +278,8 @@ error_t MmUnmapPageFrame(ulong id)
ulong tab[4000] = {0}; 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++) { */ /* for (int i = 0; i < 2000; i++) { */
/* if (rand() %2) { */ /* if (rand() %2) { */
/* if (rand() %2) { */ /* if (rand() %2) { */
@ -296,41 +294,23 @@ error_t MmTestBusyPage(void)
/* } */ /* } */
ulong a = KeGetTicks(); ulong a = KeGetTicks();
DebugLog("Start alloc 30 MB: %lu s\n", a/1000); DebugLog("Start alloc 1: %lu s\n", a/1000);
tab[0] = MmAllocPageFrame(100*MB, NORMAL); tab[0] = MmAllocPageFrame(size*KB, NORMAL);
ulong b = KeGetTicks(); ulong b = KeGetTicks();
DebugLog("End alloc : %lu s\n", b/1000); DebugLog("End alloc : %lu s\n", b/1000);
DebugLog("Alloc time : %lu s\n", (b-a)/1000); DebugLog("Alloc time : %lu s\n", (b-a)/1000);
DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB); DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB);
/* a = KeGetTicks(); */ printBusyPages();
/* 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); */
a = KeGetTicks(); a = KeGetTicks();
DebugLog("Start map at %p: %lu ms\n", USERSPACE, a); DebugLog("Start map at %p wit %p: %lu ms\n", USERSPACE, flags, a);
MmMapPageFrame(tab[0], (void*)(USERSPACE), PRESENT | READWRITE | USERSPACE); MmMapPageFrame(tab[0], (void*)(USERSPACE), flags);
b = KeGetTicks(); b = KeGetTicks();
DebugLog("End map : %lu ms\n", b); DebugLog("End map : %lu ms\n", b);
DebugLog("Map time : %lu ms\n", (b-a)); DebugLog("Map time : %lu ms\n", (b-a));
//printBusyPages(); DebugLog("Finished !\n");
//DebugLog("Finished !\n");
return EOK; return EOK;
} }

View File

@ -239,9 +239,9 @@ error_t CmdPageUnmap(int argc, char **argv, char *cmdline)
return EOK; 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; return err;
} }
@ -311,7 +311,7 @@ static Command_t testcmdtable[] =
" virtual address (paging)"}, " virtual address (paging)"},
{ "pmap", CmdPageMap, "Map a page to given physical addr" }, { "pmap", CmdPageMap, "Map a page to given physical addr" },
{ "punmap", CmdPageUnmap, "Unmap a page" }, { "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 <address>"}, { "pf", CmdPF, "Provoke a PF. Usage: pfault <address>"},
{ "shell", CmdShell, "Start a new shell (nested)", }, { "shell", CmdShell, "Start a new shell (nested)", },
{ "stkov", CmdStackOverflow, "Provoke a stack overflow" }, { "stkov", CmdStackOverflow, "Provoke a stack overflow" },