More improvements in allocator
This commit is contained in:
parent
e854a92753
commit
c8a7775b4f
|
@ -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);
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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) {
|
busyLastAddr = isPageBusy(curPage);
|
||||||
if (!isPageBusy(curPage)) {
|
|
||||||
(*frameListPtr)[curNumber] = curPage;
|
if (!busyLastAddr) {
|
||||||
inBlock = true;
|
|
||||||
////DebugLog("Select page : %p\n", curPage);
|
if (!futureBegin) {
|
||||||
if (++curNumber >= *pageNumber) {
|
futureBegin = curPage;
|
||||||
break;
|
//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 {
|
} else {
|
||||||
inBlock = false;
|
curNumber = 0;
|
||||||
}
|
futureBegin = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,14 +239,15 @@ 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)) {
|
|
||||||
return EADDRINUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id == busyPage->id) {
|
if (id == busyPage->id) {
|
||||||
DebugLog("Map %p at %p\n", busyPage->phyAddress, virtAddr);
|
for (void *addr = busyPage->phyAddressBegin; addr <= busyPage->phyAddressEnd; addr += KPAGESIZE) {
|
||||||
MmMapPage((void*)((ulong)virtAddr), busyPage->phyAddress, flags);
|
if (MmTransPhyToVirtAddr(addr)) {
|
||||||
virtAddr += KPAGESIZE;
|
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) {
|
while(busyPage->next) {
|
||||||
busyPage = busyPage->next;
|
busyPage = busyPage->next;
|
||||||
actualPhys = MmTransPhyToVirtAddr(busyPage->phyAddress);
|
|
||||||
|
|
||||||
if (actualPhys && id == busyPage->id) {
|
if (id == busyPage->id) {
|
||||||
MmUnmapPage(MmTransPhyToVirtAddr(busyPage->phyAddress));
|
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};
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" },
|
||||||
|
|
Loading…
Reference in New Issue