- Timestamp:
- May 27, 2011 4:17:12 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/gvm.h
r36448 r37242 100 100 struct GMMPERVM s; 101 101 #endif 102 uint8_t padding[ 256];102 uint8_t padding[512]; 103 103 } gmm; 104 104 105 105 /** The RAWPCIVM per vm data. */ 106 106 union -
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r37214 r37242 176 176 /** Pointer to set of free chunks. */ 177 177 typedef struct GMMCHUNKFREESET *PGMMCHUNKFREESET; 178 179 /** Pointer to a GMM allocation chunk. */180 typedef struct GMMCHUNK *PGMMCHUNK;181 178 182 179 /** … … 467 464 468 465 469 /** The GMMCHUNK::cFree shift count employed by gmmR0SelectFreeSetList. */470 #define GMM_CHUNK_FREE_SET_SHIFT 4471 /** Index of the list containing completely unused chunks.472 * The code ASSUMES this is the last list. */473 #define GMM_CHUNK_FREE_SET_UNUSED_LIST (GMM_CHUNK_NUM_PAGES >> GMM_CHUNK_FREE_SET_SHIFT)474 475 476 477 /**478 * A set of free chunks.479 */480 typedef struct GMMCHUNKFREESET481 {482 /** The number of free pages in the set. */483 uint64_t cFreePages;484 /** The generation ID for the set. This is incremented whenever485 * something is linked or unlinked from this set. */486 uint64_t idGeneration;487 /** Chunks ordered by increasing number of free pages.488 * In the final list the chunks are completely unused. */489 PGMMCHUNK apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST + 1];490 } GMMCHUNKFREESET;491 492 493 466 /** 494 467 * The GMM instance data. … … 512 485 GMMCHUNKTLB ChunkTLB; 513 486 /** The private free set. */ 514 GMMCHUNKFREESET Private ;487 GMMCHUNKFREESET PrivateX; 515 488 /** The shared free set. */ 516 489 GMMCHUNKFREESET Shared; … … 717 690 static DECLCALLBACK(int) gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM); 718 691 static bool gmmR0CleanupVMScanChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk); 692 DECLINLINE(void) gmmR0UnlinkChunk(PGMMCHUNK pChunk); 719 693 DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet); 720 DECLINLINE(void) gmmR0 UnlinkChunk(PGMMCHUNK pChunk);694 DECLINLINE(void) gmmR0SelectSetAndLinkChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk); 721 695 static uint32_t gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uLineNo); 722 696 static bool gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSem); 723 static void gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage);697 static void gmmR0FreeSharedPage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage); 724 698 static int gmmR0UnmapChunkLocked(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk); 725 699 static void gmmR0SharedModuleCleanup(PGMM pGMM, PGVM pGVM); … … 1247 1221 * Free empty chunks. 1248 1222 */ 1223 PGMMCHUNKFREESET pPrivateSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX; 1249 1224 do 1250 1225 { 1251 1226 fRedoFromStart = false; 1252 1227 iCountDown = 10240; 1253 pChunk = p GMM->Private.apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST];1228 pChunk = pPrivateSet->apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST]; 1254 1229 while (pChunk) 1255 1230 { … … 1259 1234 || pChunk->hGVM == pGVM->hSelf) 1260 1235 { 1261 uint64_t const idGenerationOld = p GMM->Private.idGeneration;1236 uint64_t const idGenerationOld = pPrivateSet->idGeneration; 1262 1237 if (gmmR0FreeChunk(pGMM, pGVM, pChunk, true /*fRelaxedSem*/)) 1263 1238 { 1264 1239 /* We've left the giant mutex, restart? (+1 for our unlink) */ 1265 fRedoFromStart = p GMM->Private.idGeneration != idGenerationOld + 1;1240 fRedoFromStart = pPrivateSet->idGeneration != idGenerationOld + 1; 1266 1241 if (fRedoFromStart) 1267 1242 break; … … 1275 1250 if (--iCountDown == 0) 1276 1251 { 1277 uint64_t const idGenerationOld = p GMM->Private.idGeneration;1252 uint64_t const idGenerationOld = pPrivateSet->idGeneration; 1278 1253 fRedoFromStart = gmmR0MutexYield(pGMM, &uLockNanoTS) 1279 && p GMM->Private.idGeneration != idGenerationOld;1254 && pPrivateSet->idGeneration != idGenerationOld; 1280 1255 if (fRedoFromStart) 1281 1256 break; … … 1387 1362 cShared++; 1388 1363 1389 gmmR0 LinkChunk(pChunk, pChunk->cShared ? &g_pGMM->Shared : &g_pGMM->Private);1364 gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk); 1390 1365 1391 1366 /* … … 1420 1395 gmmR0UnlinkChunk(pChunk); 1421 1396 pChunk->cFree = GMM_CHUNK_NUM_PAGES; 1422 gmmR0 LinkChunk(pChunk, pChunk->cShared ? &g_pGMM->Shared : &g_pGMM->Private);1397 gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk); 1423 1398 } 1424 1399 } … … 1717 1692 uint32_t cErrors = 0; 1718 1693 1719 cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Private , "private", pszFunction, uLineNo);1720 cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Shared, "shared", pszFunction, uLineNo);1694 cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->PrivateX, "private", pszFunction, uLineNo); 1695 cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Shared, "shared", pszFunction, uLineNo); 1721 1696 /** @todo add more sanity checks. */ 1722 1697 … … 1879 1854 } 1880 1855 } 1856 1857 1858 /** 1859 * Links the chunk onto the appropriate free list in the specified free set. 1860 * 1861 * If no free entries, it's not linked into any list. 1862 * 1863 * @param pChunk The allocation chunk. 1864 */ 1865 DECLINLINE(void) gmmR0SelectSetAndLinkChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk) 1866 { 1867 PGMMCHUNKFREESET pSet; 1868 if (pGMM->fBoundMemoryMode) 1869 pSet = &pGVM->gmm.s.Private; 1870 else if (pChunk->cShared) 1871 pSet = &pGMM->Shared; 1872 else 1873 pSet = &pGMM->PrivateX; 1874 gmmR0LinkChunk(pChunk, pSet); 1875 } 1876 1881 1877 1882 1878 … … 2096 2092 * Try steal free chunks from the other set first. (Only take 100% free chunks.) 2097 2093 */ 2098 PGMMCHUNKFREESET pOtherSet = pSet == &pGMM->Private ? &pGMM->Shared : &pGMM->Private;2094 PGMMCHUNKFREESET pOtherSet = pSet == &pGMM->PrivateX ? &pGMM->Shared : &pGMM->PrivateX; 2099 2095 while ( pSet->cFreePages < cPages 2100 2096 && pOtherSet->cFreePages >= GMM_CHUNK_NUM_PAGES) 2101 2097 { 2102 PGMMCHUNK pChunk = pOtherSet->apLists[RT_ELEMENTS(pOtherSet->apLists) - 1]; 2103 while ( pChunk 2104 && pChunk->cFree != GMM_CHUNK_NUM_PAGES) 2105 pChunk = pChunk->pFreeNext; 2098 PGMMCHUNK pChunk = pOtherSet->apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST]; 2106 2099 if (!pChunk) 2107 2100 break; 2101 Assert(pChunk->cFree != GMM_CHUNK_NUM_PAGES); 2108 2102 2109 2103 gmmR0UnlinkChunk(pChunk); … … 2274 2268 * is a bit extra work but it's easier to do it upfront than bailing out later. 2275 2269 */ 2276 PGMMCHUNKFREESET pSet = &pGMM->Private;2270 PGMMCHUNKFREESET pSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX; 2277 2271 if (pSet->cFreePages < cPages) 2278 2272 return VERR_GMM_SEED_ME; … … 2561 2555 pGVM->gmm.s.Allocated.cBasePages--; 2562 2556 if (!--pPage->Shared.cRefs) 2563 { 2564 gmmR0FreeSharedPage(pGMM, paPages[iPage].idSharedPage, pPage); 2565 } 2557 gmmR0FreeSharedPage(pGMM, pGVM, paPages[iPage].idSharedPage, pPage); 2566 2558 else 2567 2559 { … … 2592 2584 * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex! 2593 2585 */ 2586 #if 0 2587 rc = gmmR0AllocatePagesNew(pGMM, pGVM, cPagesToAlloc, paPages, GMMACCOUNT_BASE); 2588 #else 2594 2589 GMMR0ALLOCPAGESTRATEGY Strategy; 2595 2590 gmmR0AllocatePagesInitStrategy(pGMM, pGVM, &Strategy); … … 2600 2595 || pGMM->fLegacyAllocationMode) 2601 2596 break; 2602 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private , cPagesToAlloc, &Strategy);2597 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->PrivateX, cPagesToAlloc, &Strategy); 2603 2598 } 2599 #endif 2604 2600 } 2605 2601 else … … 2690 2686 || pGMM->fLegacyAllocationMode) 2691 2687 break; 2692 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private , cPages, &Strategy);2688 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->PrivateX, cPages, &Strategy); 2693 2689 } 2694 2690 } … … 2799 2795 if (RT_SUCCESS(rc)) 2800 2796 { 2797 PGMMCHUNKFREESET pSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX; 2801 2798 PGMMCHUNK pChunk; 2802 rc = gmmR0RegisterChunk(pGMM, &pGMM->Private, hMemObj, pGVM->hSelf, GMM_CHUNK_FLAGS_LARGE_PAGE, &pChunk);2799 rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, GMM_CHUNK_FLAGS_LARGE_PAGE, &pChunk); 2803 2800 if (RT_SUCCESS(rc)) 2804 2801 { … … 2826 2823 pGMM->cAllocatedPages += cPages; 2827 2824 2828 gmmR0LinkChunk(pChunk, &pGMM->Private);2825 gmmR0LinkChunk(pChunk, pSet); 2829 2826 gmmR0MutexRelease(pGMM); 2830 2827 } … … 3033 3030 * 3034 3031 * @param pGMM Pointer to the GMM instance data. 3032 * @param pGVM Pointer to the GVM instance. 3035 3033 * @param pChunk Pointer to the chunk this page belongs to. 3036 3034 * @param idPage The Page ID. 3037 3035 * @param pPage Pointer to the page. 3038 3036 */ 3039 static void gmmR0FreePageWorker(PGMM pGMM, PG MMCHUNK pChunk, uint32_t idPage, PGMMPAGE pPage)3037 static void gmmR0FreePageWorker(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, uint32_t idPage, PGMMPAGE pPage) 3040 3038 { 3041 3039 Log3(("F pPage=%p iPage=%#x/%#x u2State=%d iFreeHead=%#x\n", … … 3061 3059 gmmR0UnlinkChunk(pChunk); 3062 3060 pChunk->cFree++; 3063 gmmR0 LinkChunk(pChunk, pChunk->cShared ? &pGMM->Shared : &pGMM->Private);3061 gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk); 3064 3062 } 3065 3063 else … … 3092 3090 * 3093 3091 * @param pGMM Pointer to the GMM instance. 3092 * @param pGVM Pointer to the GVM instance. 3094 3093 * @param idPage The Page ID 3095 3094 * @param pPage The page structure. 3096 3095 */ 3097 DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage)3096 DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage) 3098 3097 { 3099 3098 PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT); … … 3108 3107 pGMM->cAllocatedPages--; 3109 3108 pGMM->cSharedPages--; 3110 gmmR0FreePageWorker(pGMM, p Chunk, idPage, pPage);3111 } 3112 3113 #ifdef VBOX_WITH_PAGE_SHARING 3109 gmmR0FreePageWorker(pGMM, pGVM, pChunk, idPage, pPage); 3110 } 3111 3112 #ifdef VBOX_WITH_PAGE_SHARING /** @todo move this away from here, this has nothing to do with the free() code. */ 3114 3113 3115 3114 /** … … 3169 3168 * 3170 3169 * @param pGMM Pointer to the GMM instance. 3170 * @param pGVM Pointer to the GVM instance. 3171 3171 * @param idPage The Page ID 3172 3172 * @param pPage The page structure. 3173 3173 */ 3174 DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage)3174 DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage) 3175 3175 { 3176 3176 PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT); … … 3182 3182 pChunk->cPrivate--; 3183 3183 pGMM->cAllocatedPages--; 3184 gmmR0FreePageWorker(pGMM, p Chunk, idPage, pPage);3184 gmmR0FreePageWorker(pGMM, pGVM, pChunk, idPage, pPage); 3185 3185 } 3186 3186 … … 3250 3250 Assert(pGVM->gmm.s.cPrivatePages); 3251 3251 pGVM->gmm.s.cPrivatePages--; 3252 gmmR0FreePrivatePage(pGMM, idPage, pPage);3252 gmmR0FreePrivatePage(pGMM, pGVM, idPage, pPage); 3253 3253 } 3254 3254 else … … 3266 3266 Assert(pPage->Shared.cRefs); 3267 3267 if (!--pPage->Shared.cRefs) 3268 gmmR0FreeSharedPage(pGMM, idPage, pPage);3268 gmmR0FreeSharedPage(pGMM, pGVM, idPage, pPage); 3269 3269 else 3270 3270 { … … 4025 4025 if (RT_SUCCESS(rc)) 4026 4026 { 4027 rc = gmmR0RegisterChunk(pGMM, &pG MM->Private, MemObj, pGVM->hSelf, 0 /*fChunkFlags*/, NULL);4027 rc = gmmR0RegisterChunk(pGMM, &pGVM->gmm.s.Private, MemObj, pGVM->hSelf, 0 /*fChunkFlags*/, NULL); 4028 4028 if (RT_SUCCESS(rc)) 4029 4029 gmmR0MutexRelease(pGMM); -
trunk/src/VBox/VMM/VMMR0/GMMR0Internal.h
r35346 r37242 64 64 typedef GMMSHAREDMODULEPERVM *PGMMSHAREDMODULEPERVM; 65 65 66 67 /** Pointer to a GMM allocation chunk. */ 68 typedef struct GMMCHUNK *PGMMCHUNK; 69 70 71 /** The GMMCHUNK::cFree shift count employed by gmmR0SelectFreeSetList. */ 72 #define GMM_CHUNK_FREE_SET_SHIFT 4 73 /** Index of the list containing completely unused chunks. 74 * The code ASSUMES this is the last list. */ 75 #define GMM_CHUNK_FREE_SET_UNUSED_LIST (GMM_CHUNK_NUM_PAGES >> GMM_CHUNK_FREE_SET_SHIFT) 76 77 /** 78 * A set of free chunks. 79 */ 80 typedef struct GMMCHUNKFREESET 81 { 82 /** The number of free pages in the set. */ 83 uint64_t cFreePages; 84 /** The generation ID for the set. This is incremented whenever 85 * something is linked or unlinked from this set. */ 86 uint64_t idGeneration; 87 /** Chunks ordered by increasing number of free pages. 88 * In the final list the chunks are completely unused. */ 89 PGMMCHUNK apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST + 1]; 90 } GMMCHUNKFREESET; 91 92 93 66 94 /** 67 95 * The per-VM GMM data. … … 69 97 typedef struct GMMPERVM 70 98 { 99 /** Free set for use in bound mode. */ 100 GMMCHUNKFREESET Private; 101 71 102 /** The reservations. */ 72 103 GMMVMSIZES Reserved;
Note:
See TracChangeset
for help on using the changeset viewer.