More improvements in allocator
This commit is contained in:
parent
e854a92753
commit
c8a7775b4f
|
@ -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);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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" },
|
||||
|
|
Loading…
Reference in New Issue