summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/VMMR0/GMMR0.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMR0/GMMR0.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/VMMR0/GMMR0.cpp')
-rw-r--r--src/VBox/VMM/VMMR0/GMMR0.cpp45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/VBox/VMM/VMMR0/GMMR0.cpp b/src/VBox/VMM/VMMR0/GMMR0.cpp
index 54b7a732..aa0cd610 100644
--- a/src/VBox/VMM/VMMR0/GMMR0.cpp
+++ b/src/VBox/VMM/VMMR0/GMMR0.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007-2012 Oracle Corporation
+ * Copyright (C) 2007-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -1959,7 +1959,7 @@ static uint32_t gmmR0AllocateChunkId(PGMM pGMM)
if ( (uint32_t)idChunk < GMM_CHUNKID_LAST
&& idChunk > NIL_GMM_CHUNKID)
{
- idChunk = ASMBitNextClear(&pGMM->bmChunkId[0], GMM_CHUNKID_LAST + 1, idChunk);
+ idChunk = ASMBitNextClear(&pGMM->bmChunkId[0], GMM_CHUNKID_LAST + 1, idChunk - 1);
if (idChunk > NIL_GMM_CHUNKID)
{
AssertMsgReturn(!ASMAtomicBitTestAndSet(&pGMM->bmChunkId[0], idChunk), ("%#x\n", idChunk), NIL_GMM_CHUNKID);
@@ -2380,12 +2380,13 @@ static uint32_t gmmR0AllocatePagesInBoundMode(PGVM pGVM, uint32_t iPage, uint32_
/**
- * Checks if we should start picking pages from chunks of other VMs.
+ * Checks if we should start picking pages from chunks of other VMs because
+ * we're getting close to the system memory or reserved limit.
*
* @returns @c true if we should, @c false if we should first try allocate more
* chunks.
*/
-static bool gmmR0ShouldAllocatePagesInOtherChunks(PGVM pGVM)
+static bool gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLimits(PGVM pGVM)
{
/*
* Don't allocate a new chunk if we're
@@ -2413,6 +2414,24 @@ static bool gmmR0ShouldAllocatePagesInOtherChunks(PGVM pGVM)
/**
+ * Checks if we should start picking pages from chunks of other VMs because
+ * there is a lot of free pages around.
+ *
+ * @returns @c true if we should, @c false if we should first try allocate more
+ * chunks.
+ */
+static bool gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLotsFree(PGMM pGMM)
+{
+ /*
+ * Setting the limit at 16 chunks (32 MB) at the moment.
+ */
+ if (pGMM->PrivateX.cFreePages >= GMM_CHUNK_NUM_PAGES * 16)
+ return true;
+ return false;
+}
+
+
+/**
* Common worker for GMMR0AllocateHandyPages and GMMR0AllocatePages.
*
* @returns VBox status code:
@@ -2536,8 +2555,12 @@ static int gmmR0AllocatePagesNew(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGE
{
/* Maybe we should try getting pages from chunks "belonging" to
other VMs before allocating more chunks? */
- if (gmmR0ShouldAllocatePagesInOtherChunks(pGVM))
+ bool fTriedOnSameAlready = false;
+ if (gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLimits(pGVM))
+ {
iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);
+ fTriedOnSameAlready = true;
+ }
/* Allocate memory from empty chunks. */
if (iPage < cPages)
@@ -2547,6 +2570,16 @@ static int gmmR0AllocatePagesNew(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGE
if (iPage < cPages)
iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->Shared, pGVM, iPage, cPages, paPages);
+ /* If there is a lof of free pages spread around, try not waste
+ system memory on more chunks. (Should trigger defragmentation.) */
+ if ( !fTriedOnSameAlready
+ && gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLotsFree(pGMM))
+ {
+ iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);
+ if (iPage < cPages)
+ iPage = gmmR0AllocatePagesIndiscriminately(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);
+ }
+
/*
* Ok, try allocate new chunks.
*/
@@ -5119,7 +5152,7 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu)
Args.idCpu = pVCpu->idCpu;
rc = RTAvlGCPtrDoWithAll(&pGVM->gmm.s.pSharedModuleTree, true /* fFromLeft */, gmmR0CheckSharedModule, &Args);
- Log(("GMMR0CheckSharedModules done!\n"));
+ Log(("GMMR0CheckSharedModules done (rc=%Rrc)!\n", rc));
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
}
else