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{
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);
//----------------------------------------------------------------------------//

View File

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

View File

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

View File

@ -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 <address>"},
{ "shell", CmdShell, "Start a new shell (nested)", },
{ "stkov", CmdStackOverflow, "Provoke a stack overflow" },