X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=KernelLand%2FKernel%2Farch%2Fx86%2Fmm_phys.c;h=49d7a1a7635ff115d5eb0e498b5df7eedcf5b2c9;hb=ff00630ed805237683c2f8fa47765a1cf5a07578;hp=aa1b26030be7db6e0157071b08d61ca9e842488d;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/mm_phys.c b/KernelLand/Kernel/arch/x86/mm_phys.c index aa1b2603..49d7a1a7 100644 --- a/KernelLand/Kernel/arch/x86/mm_phys.c +++ b/KernelLand/Kernel/arch/x86/mm_phys.c @@ -10,6 +10,8 @@ //#define USE_STACK 1 #define TRACE_ALLOCS 0 // Print trace messages on AllocPhys/DerefPhys +static const int addrClasses[] = {0,16,20,24,32,64}; +static const int numAddrClasses = sizeof(addrClasses)/sizeof(addrClasses[0]); // === IMPORTS === extern char gKernelEnd[]; @@ -28,6 +30,7 @@ tMutex glPhysAlloc; Uint64 giPhysAlloc = 0; // Number of allocated pages Uint64 giPageCount = 0; // Total number of pages Uint64 giLastPossibleFree = 0; // Last possible free page (before all pages are used) +Uint64 giTotalMemorySize = 0; // Total number of allocatable pages Uint32 gaSuperBitmap[1024]; // Blocks of 1024 Pages Uint32 gaPageBitmap[1024*1024/32]; // Individual pages @@ -53,8 +56,12 @@ void MM_Install(tMBoot_Info *MBoot) ent->Size += 4; // If entry is RAM and is above `maxAddr`, change `maxAddr` - if(ent->Type == 1 && ent->Base + ent->Length > maxAddr) - maxAddr = ent->Base + ent->Length; + if(ent->Type == 1) + { + if(ent->Base + ent->Length > maxAddr) + maxAddr = ent->Base + ent->Length; + giTotalMemorySize += ent->Length >> 12; + } // Go to next entry ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size ); } @@ -81,7 +88,8 @@ void MM_Install(tMBoot_Info *MBoot) kernelPages = (Uint)&gKernelEnd - KERNEL_BASE - 0x100000; kernelPages += 0xFFF; // Page Align kernelPages >>= 12; - + giPhysAlloc += kernelPages; // Add to used count + // Fill page bitmap num = kernelPages/32; memsetd( &gaPageBitmap[0x100000/(4096*32)], -1, num ); @@ -109,7 +117,49 @@ void MM_Install(tMBoot_Info *MBoot) gaPageReferences = (void*)MM_REFCOUNT_BASE; - Log_Log("PMem", "Physical memory set up"); + Log_Log("PMem", "Physical memory set up (%lli pages of ~%lli MiB used)", + giPhysAlloc, (giTotalMemorySize*4)/1024 + ); +} + +void MM_DumpStatistics(void) +{ + int i, pg; + for( i = 1; i < numAddrClasses; i ++ ) + { + int first = (i == 1 ? 0 : (1UL << (addrClasses[i-1] - 12))); + int last = (1UL << (addrClasses[i] - 12)) - 1; + int nFree = 0; + int nMultiRef = 0; + int totalRefs = 0; + + if( last > giPageCount ) + last = giPageCount; + + int total = last - first + 1; + + for( pg = first; pg < last; pg ++ ) + { + if( !MM_GetPhysAddr(&gaPageReferences[pg]) || gaPageReferences[pg] == 0 ) { + nFree ++; + continue ; + } + totalRefs += gaPageReferences[pg]; + if(gaPageReferences[pg] > 1) + nMultiRef ++; + } + + int nUsed = (total - nFree); + Log_Log("MMPhys", "%ipbit - %i/%i used, %i reused, %i average reference count", + addrClasses[i], nUsed, total, nMultiRef, + nMultiRef ? (totalRefs-(nUsed - nMultiRef)) / nMultiRef : 0 + ); + + if( last == giPageCount ) + break; + } + Log_Log("MMPhys", "%lli/%lli total pages used, 0 - %i possible free range", + giPhysAlloc, giTotalMemorySize, giLastPossibleFree); } /** @@ -129,8 +179,6 @@ tPAddr MM_AllocPhys(void) // Classful scan #if 1 { - const int addrClasses[] = {0,16,20,24,32,64}; - const int numAddrClasses = sizeof(addrClasses)/sizeof(addrClasses[0]); int i; int first, last; for( i = numAddrClasses; i -- > 1; ) @@ -423,7 +471,10 @@ void MM_RefPhys(tPAddr PAddr) // Log_Debug("PMem", "MM_RefPhys: Allocating info for %X", PAddr); Mutex_Release( &glPhysAlloc ); if( MM_Allocate( addr ) == 0 ) { - Log_KernelPanic("PMem", "MM_RefPhys: Out of physical memory allocating info for %X", PAddr*PAGE_SIZE); + Log_KernelPanic("PMem", + "MM_RefPhys: Out of physical memory allocating info for %X", + PAddr*PAGE_SIZE + ); } Mutex_Acquire( &glPhysAlloc ); @@ -434,9 +485,13 @@ void MM_RefPhys(tPAddr PAddr) } gaPageReferences[ PAddr ] ++; } - - // Mark as used - gaPageBitmap[ PAddr / 32 ] |= 1 << (PAddr&31); + + // If not already used + if( !(gaPageBitmap[ PAddr / 32 ] & 1 << (PAddr&31)) ) { + giPhysAlloc ++; + // Mark as used + gaPageBitmap[ PAddr / 32 ] |= 1 << (PAddr&31); + } // Mark used block if(gaPageBitmap[ PAddr / 32 ] == -1)