Changeset 20899 in vbox
- Timestamp:
- Jun 24, 2009 4:33:49 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r20893 r20899 456 456 { 457 457 /** The number of free pages in the set. */ 458 uint64_t c Pages;458 uint64_t cFreePages; 459 459 /** Chunks ordered by increasing number of free pages. */ 460 460 PGMMCHUNK apLists[GMM_CHUNK_FREE_SET_LISTS]; … … 562 562 563 563 564 /** @def GMM_CHECK_SANITY_UPON_ENTERING 565 * Checks the sanity of the GMM instance data before making changes. 566 * 567 * This is macro is a stub by default and must be enabled manually in the code. 568 * 569 * @returns true if sane, false if not. 570 * @param pGMM The name of the pGMM variable. 571 */ 572 #if defined(VBOX_STRICT) && 0 573 # define GMM_CHECK_SANITY_UPON_ENTERING(pGMM) (gmmR0SanityCheck((pGMM), __PRETTY_FUNCTION__, __LINE__) == 0) 574 #else 575 # define GMM_CHECK_SANITY_UPON_ENTERING(pGMM) (true) 576 #endif 577 578 /** @def GMM_CHECK_SANITY_UPON_LEAVING 579 * Checks the sanity of the GMM instance data after making changes. 580 * 581 * This is macro is a stub by default and must be enabled manually in the code. 582 * 583 * @returns true if sane, false if not. 584 * @param pGMM The name of the pGMM variable. 585 */ 586 #if defined(VBOX_STRICT) && 0 587 # define GMM_CHECK_SANITY_UPON_LEAVING(pGMM) (gmmR0SanityCheck((pGMM), __PRETTY_FUNCTION__, __LINE__) == 0) 588 #else 589 # define GMM_CHECK_SANITY_UPON_LEAVING(pGMM) (true) 590 #endif 591 592 /** @def GMM_CHECK_SANITY_IN_LOOPS 593 * Checks the sanity of the GMM instance in the allocation loops. 594 * 595 * This is macro is a stub by default and must be enabled manually in the code. 596 * 597 * @returns true if sane, false if not. 598 * @param pGMM The name of the pGMM variable. 599 */ 600 #if defined(VBOX_STRICT) && 0 601 # define GMM_CHECK_SANITY_IN_LOOPS(pGMM) (gmmR0SanityCheck((pGMM), __PRETTY_FUNCTION__, __LINE__) == 0) 602 #else 603 # define GMM_CHECK_SANITY_IN_LOOPS(pGMM) (true) 604 #endif 605 606 564 607 /******************************************************************************* 565 608 * Internal Functions * … … 570 613 DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet); 571 614 DECLINLINE(void) gmmR0UnlinkChunk(PGMMCHUNK pChunk); 615 static uint32_t gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uLineNo); 572 616 static void gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk); 573 617 static void gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage); … … 746 790 int rc = RTSemFastMutexRequest(pGMM->Mtx); 747 791 AssertRC(rc); 792 GMM_CHECK_SANITY_UPON_ENTERING(pGMM); 748 793 749 794 /* … … 847 892 pGVM->gmm.s.fMayAllocate = false; 848 893 894 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 849 895 RTSemFastMutexRelease(pGMM->Mtx); 850 896 … … 1072 1118 rc = RTSemFastMutexRequest(pGMM->Mtx); 1073 1119 AssertRC(rc); 1074 1075 if ( !pGVM->gmm.s.Reserved.cBasePages 1076 && !pGVM->gmm.s.Reserved.cFixedPages 1077 && !pGVM->gmm.s.Reserved.cShadowPages) 1078 { 1079 /* 1080 * Check if we can accomodate this. 1081 */ 1082 /* ... later ... */ 1083 if (RT_SUCCESS(rc)) 1120 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 1121 { 1122 if ( !pGVM->gmm.s.Reserved.cBasePages 1123 && !pGVM->gmm.s.Reserved.cFixedPages 1124 && !pGVM->gmm.s.Reserved.cShadowPages) 1084 1125 { 1085 1126 /* 1086 * Update the records.1127 * Check if we can accomodate this. 1087 1128 */ 1088 pGVM->gmm.s.Reserved.cBasePages = cBasePages; 1089 pGVM->gmm.s.Reserved.cFixedPages = cFixedPages; 1090 pGVM->gmm.s.Reserved.cShadowPages = cShadowPages; 1091 pGVM->gmm.s.enmPolicy = enmPolicy; 1092 pGVM->gmm.s.enmPriority = enmPriority; 1093 pGVM->gmm.s.fMayAllocate = true; 1094 1095 pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages; 1096 pGMM->cRegisteredVMs++; 1097 } 1129 /* ... later ... */ 1130 if (RT_SUCCESS(rc)) 1131 { 1132 /* 1133 * Update the records. 1134 */ 1135 pGVM->gmm.s.Reserved.cBasePages = cBasePages; 1136 pGVM->gmm.s.Reserved.cFixedPages = cFixedPages; 1137 pGVM->gmm.s.Reserved.cShadowPages = cShadowPages; 1138 pGVM->gmm.s.enmPolicy = enmPolicy; 1139 pGVM->gmm.s.enmPriority = enmPriority; 1140 pGVM->gmm.s.fMayAllocate = true; 1141 1142 pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages; 1143 pGMM->cRegisteredVMs++; 1144 } 1145 } 1146 else 1147 rc = VERR_WRONG_ORDER; 1148 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 1098 1149 } 1099 1150 else 1100 rc = VERR_WRONG_ORDER; 1101 1151 rc = VERR_INTERNAL_ERROR_5; 1102 1152 RTSemFastMutexRelease(pGMM->Mtx); 1103 1153 LogFlow(("GMMR0InitialReservation: returns %Rrc\n", rc)); … … 1164 1214 rc = RTSemFastMutexRequest(pGMM->Mtx); 1165 1215 AssertRC(rc); 1166 1167 if ( pGVM->gmm.s.Reserved.cBasePages 1168 && pGVM->gmm.s.Reserved.cFixedPages 1169 && pGVM->gmm.s.Reserved.cShadowPages) 1170 { 1171 /* 1172 * Check if we can accomodate this. 1173 */ 1174 /* ... later ... */ 1175 if (RT_SUCCESS(rc)) 1216 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 1217 { 1218 if ( pGVM->gmm.s.Reserved.cBasePages 1219 && pGVM->gmm.s.Reserved.cFixedPages 1220 && pGVM->gmm.s.Reserved.cShadowPages) 1176 1221 { 1177 1222 /* 1178 * Update the records.1223 * Check if we can accomodate this. 1179 1224 */ 1180 pGMM->cReservedPages -= pGVM->gmm.s.Reserved.cBasePages 1181 + pGVM->gmm.s.Reserved.cFixedPages 1182 + pGVM->gmm.s.Reserved.cShadowPages; 1183 pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages; 1184 1185 pGVM->gmm.s.Reserved.cBasePages = cBasePages; 1186 pGVM->gmm.s.Reserved.cFixedPages = cFixedPages; 1187 pGVM->gmm.s.Reserved.cShadowPages = cShadowPages; 1188 } 1225 /* ... later ... */ 1226 if (RT_SUCCESS(rc)) 1227 { 1228 /* 1229 * Update the records. 1230 */ 1231 pGMM->cReservedPages -= pGVM->gmm.s.Reserved.cBasePages 1232 + pGVM->gmm.s.Reserved.cFixedPages 1233 + pGVM->gmm.s.Reserved.cShadowPages; 1234 pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages; 1235 1236 pGVM->gmm.s.Reserved.cBasePages = cBasePages; 1237 pGVM->gmm.s.Reserved.cFixedPages = cFixedPages; 1238 pGVM->gmm.s.Reserved.cShadowPages = cShadowPages; 1239 } 1240 } 1241 else 1242 rc = VERR_WRONG_ORDER; 1243 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 1189 1244 } 1190 1245 else 1191 rc = VERR_WRONG_ORDER; 1192 1246 rc = VERR_INTERNAL_ERROR_5; 1193 1247 RTSemFastMutexRelease(pGMM->Mtx); 1194 1248 LogFlow(("GMMR0UpdateReservation: returns %Rrc\n", rc)); … … 1215 1269 1216 1270 return GMMR0UpdateReservation(pVM, idCpu, pReq->cBasePages, pReq->cShadowPages, pReq->cFixedPages); 1271 } 1272 1273 1274 /** 1275 * Performs sanity checks on a free set. 1276 * 1277 * @returns Error count. 1278 * 1279 * @param pGMM Pointer to the GMM instance. 1280 * @param pSet Pointer to the set. 1281 * @param pszSetName The set name. 1282 * @param pszFunction The function from which it was called. 1283 * @param uLine The line number. 1284 */ 1285 static uint32_t gmmR0SanityCheckSet(PGMM pGMM, PGMMCHUNKFREESET pSet, const char *pszSetName, 1286 const char *pszFunction, unsigned uLineNo) 1287 { 1288 uint32_t cErrors = 0; 1289 1290 /* 1291 * Count the free pages in all the chunks and match it against pSet->cFreePages. 1292 */ 1293 uint32_t cPages = 0; 1294 for (unsigned i = 0; i < RT_ELEMENTS(pSet->apLists); i++) 1295 { 1296 for (PGMMCHUNK pCur = pSet->apLists[i]; pCur; pCur = pCur->pFreeNext) 1297 { 1298 /** @todo check that the chunk is hash into the right set. */ 1299 cPages += pCur->cFree; 1300 } 1301 } 1302 if (RT_UNLIKELY(cPages != pSet->cFreePages)) 1303 { 1304 SUPR0Printf("GMM insanity: found %#x pages in the %s set, expected %#x. (%s, line %u)\n", 1305 cPages, pszSetName, pSet->cFreePages, pszFunction, uLineNo); 1306 cErrors++; 1307 } 1308 1309 return cErrors; 1310 } 1311 1312 1313 /** 1314 * Performs some sanity checks on the GMM while owning lock. 1315 * 1316 * @returns Error count. 1317 * 1318 * @param pGMM Pointer to the GMM instance. 1319 * @param pszFunction The function from which it is called. 1320 * @param uLineNo The line number. 1321 */ 1322 static uint32_t gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uLineNo) 1323 { 1324 uint32_t cErrors = 0; 1325 1326 cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Private, "private", pszFunction, uLineNo); 1327 cErrors += gmmR0SanityCheckSet(pGMM, &pGMM->Shared, "shared", pszFunction, uLineNo); 1328 /** @todo add more sanity checks. */ 1329 1330 return cErrors; 1217 1331 } 1218 1332 … … 1288 1402 if (RT_LIKELY(pSet)) 1289 1403 { 1290 pSet->c Pages -= pChunk->cFree;1404 pSet->cFreePages -= pChunk->cFree; 1291 1405 1292 1406 PGMMCHUNK pPrev = pChunk->pFreePrev; … … 1336 1450 pSet->apLists[iList] = pChunk; 1337 1451 1338 pSet->c Pages += pChunk->cFree;1452 pSet->cFreePages += pChunk->cFree; 1339 1453 } 1340 1454 } … … 1446 1560 if (RT_SUCCESS(rc)) 1447 1561 { 1448 pChunk->Core.Key = gmmR0AllocateChunkId(pGMM); 1449 if ( pChunk->Core.Key != NIL_GMM_CHUNKID 1450 && pChunk->Core.Key <= GMM_CHUNKID_LAST 1451 && RTAvlU32Insert(&pGMM->pChunks, &pChunk->Core)) 1562 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 1452 1563 { 1453 pGMM->cChunks++; 1454 gmmR0LinkChunk(pChunk, pSet); 1455 LogFlow(("gmmR0RegisterChunk: pChunk=%p id=%#x cChunks=%d\n", pChunk, pChunk->Core.Key, pGMM->cChunks)); 1456 RTSemFastMutexRelease(pGMM->Mtx); 1457 return VINF_SUCCESS; 1564 pChunk->Core.Key = gmmR0AllocateChunkId(pGMM); 1565 if ( pChunk->Core.Key != NIL_GMM_CHUNKID 1566 && pChunk->Core.Key <= GMM_CHUNKID_LAST 1567 && RTAvlU32Insert(&pGMM->pChunks, &pChunk->Core)) 1568 { 1569 pGMM->cChunks++; 1570 gmmR0LinkChunk(pChunk, pSet); 1571 LogFlow(("gmmR0RegisterChunk: pChunk=%p id=%#x cChunks=%d\n", pChunk, pChunk->Core.Key, pGMM->cChunks)); 1572 1573 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 1574 RTSemFastMutexRelease(pGMM->Mtx); 1575 return VINF_SUCCESS; 1576 } 1577 1578 /* bail out */ 1579 rc = VERR_INTERNAL_ERROR; 1458 1580 } 1459 1460 /* bail out */1461 rc = VERR_INTERNAL_ERROR; 1581 else 1582 rc = VERR_INTERNAL_ERROR_5; 1583 1462 1584 RTSemFastMutexRelease(pGMM->Mtx); 1463 1585 } … … 1515 1637 Assert(!pGMM->fLegacyAllocationMode); 1516 1638 1639 if (!GMM_CHECK_SANITY_IN_LOOPS(pGMM)) 1640 return VERR_INTERNAL_ERROR_4; 1641 1517 1642 if (!pGMM->fBoundMemoryMode) 1518 1643 { … … 1521 1646 */ 1522 1647 PGMMCHUNKFREESET pOtherSet = pSet == &pGMM->Private ? &pGMM->Shared : &pGMM->Private; 1523 while ( pSet->c Pages < cPages1524 && pOtherSet->c Pages >= GMM_CHUNK_NUM_PAGES)1648 while ( pSet->cFreePages < cPages 1649 && pOtherSet->cFreePages >= GMM_CHUNK_NUM_PAGES) 1525 1650 { 1526 1651 PGMMCHUNK pChunk = pOtherSet->apLists[GMM_CHUNK_FREE_SET_LISTS - 1]; … … 1539 1664 * gmmR0AllocateOneChunk will re-take it temporarily while registering the chunk. 1540 1665 */ 1541 while (pSet->c Pages < cPages)1666 while (pSet->cFreePages < cPages) 1542 1667 { 1543 1668 RTSemFastMutexRelease(pGMM->Mtx); … … 1547 1672 if (RT_FAILURE(rc)) 1548 1673 return rc; 1674 if (!GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 1675 return VERR_INTERNAL_ERROR_5; 1549 1676 } 1550 1677 } … … 1582 1709 if (RT_FAILURE(rc)) 1583 1710 return rc; 1711 if (!GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 1712 return VERR_INTERNAL_ERROR_5; 1584 1713 } 1585 1714 } … … 1699 1828 PGMMCHUNKFREESET pSet = &pGMM->Private; 1700 1829 #if 0 /** @todo this is broken, at least on windows... */ 1701 if (pSet->c Pages < cPages)1830 if (pSet->cFreePages < cPages) 1702 1831 return VERR_GMM_SEED_ME; 1703 1832 #endif … … 1717 1846 return VERR_GMM_SEED_ME; 1718 1847 } 1719 else if (pSet->c Pages < cPages) /* see #if 0 */1848 else if (pSet->cFreePages < cPages) /* see #if 0 */ 1720 1849 return VERR_GMM_SEED_ME; 1721 1850 … … 1901 2030 rc = RTSemFastMutexRequest(pGMM->Mtx); 1902 2031 AssertRC(rc); 1903 1904 /* No allocations before the initial reservation has been made! */1905 if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages 1906 && pGVM->gmm.s.Reserved.cFixedPages1907 && pGVM->gmm.s.Reserved.cShadowPages))1908 {1909 /*1910 * Perform the updates.1911 * Stop on the first error.1912 */1913 for (iPage = 0; iPage < cPagesToUpdate; iPage++)1914 {1915 if (paPages[iPage].idPage != NIL_GMM_PAGEID)2032 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 2033 { 2034 2035 /* No allocations before the initial reservation has been made! */ 2036 if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages 2037 && pGVM->gmm.s.Reserved.cFixedPages 2038 && pGVM->gmm.s.Reserved.cShadowPages)) 2039 { 2040 /* 2041 * Perform the updates. 2042 * Stop on the first error. 2043 */ 2044 for (iPage = 0; iPage < cPagesToUpdate; iPage++) 1916 2045 { 1917 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPages[iPage].idPage); 1918 if (RT_LIKELY(pPage)) 2046 if (paPages[iPage].idPage != NIL_GMM_PAGEID) 1919 2047 { 1920 if (RT_LIKELY(GMM_PAGE_IS_PRIVATE(pPage))) 2048 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPages[iPage].idPage); 2049 if (RT_LIKELY(pPage)) 1921 2050 { 1922 if (RT_LIKELY( pPage->Private.hGVM == pGVM->hSelf))2051 if (RT_LIKELY(GMM_PAGE_IS_PRIVATE(pPage))) 1923 2052 { 1924 AssertCompile(NIL_RTHCPHYS > GMM_GCPHYS_LAST && GMM_GCPHYS_UNSHAREABLE > GMM_GCPHYS_LAST); 1925 if (RT_LIKELY(paPages[iPage].HCPhysGCPhys <= GMM_GCPHYS_LAST)) 1926 pPage->Private.pfn = paPages[iPage].HCPhysGCPhys >> PAGE_SHIFT; 1927 else if (paPages[iPage].HCPhysGCPhys == GMM_GCPHYS_UNSHAREABLE) 1928 pPage->Private.pfn = GMM_PAGE_PFN_UNSHAREABLE; 1929 /* else: NIL_RTHCPHYS nothing */ 1930 1931 paPages[iPage].idPage = NIL_GMM_PAGEID; 1932 paPages[iPage].HCPhysGCPhys = NIL_RTHCPHYS; 2053 if (RT_LIKELY(pPage->Private.hGVM == pGVM->hSelf)) 2054 { 2055 AssertCompile(NIL_RTHCPHYS > GMM_GCPHYS_LAST && GMM_GCPHYS_UNSHAREABLE > GMM_GCPHYS_LAST); 2056 if (RT_LIKELY(paPages[iPage].HCPhysGCPhys <= GMM_GCPHYS_LAST)) 2057 pPage->Private.pfn = paPages[iPage].HCPhysGCPhys >> PAGE_SHIFT; 2058 else if (paPages[iPage].HCPhysGCPhys == GMM_GCPHYS_UNSHAREABLE) 2059 pPage->Private.pfn = GMM_PAGE_PFN_UNSHAREABLE; 2060 /* else: NIL_RTHCPHYS nothing */ 2061 2062 paPages[iPage].idPage = NIL_GMM_PAGEID; 2063 paPages[iPage].HCPhysGCPhys = NIL_RTHCPHYS; 2064 } 2065 else 2066 { 2067 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not owner! hGVM=%#x hSelf=%#x\n", 2068 iPage, paPages[iPage].idPage, pPage->Private.hGVM, pGVM->hSelf)); 2069 rc = VERR_GMM_NOT_PAGE_OWNER; 2070 break; 2071 } 1933 2072 } 1934 2073 else 1935 2074 { 1936 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not owner! hGVM=%#x hSelf=%#x\n", 1937 iPage, paPages[iPage].idPage, pPage->Private.hGVM, pGVM->hSelf)); 1938 rc = VERR_GMM_NOT_PAGE_OWNER; 2075 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not private! %.*Rhxs\n", iPage, paPages[iPage].idPage, sizeof(*pPage), pPage)); 2076 rc = VERR_GMM_PAGE_NOT_PRIVATE; 1939 2077 break; 1940 2078 } … … 1942 2080 else 1943 2081 { 1944 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not private! %.*Rhxs\n", iPage, paPages[iPage].idPage, sizeof(*pPage), pPage));1945 rc = VERR_GMM_PAGE_NOT_ PRIVATE;2082 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not found! (private)\n", iPage, paPages[iPage].idPage)); 2083 rc = VERR_GMM_PAGE_NOT_FOUND; 1946 2084 break; 1947 2085 } 1948 2086 } 1949 else 2087 2088 if (paPages[iPage].idSharedPage != NIL_GMM_PAGEID) 1950 2089 { 1951 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not found! (private)\n", iPage, paPages[iPage].idPage)); 1952 rc = VERR_GMM_PAGE_NOT_FOUND; 1953 break; 1954 } 1955 } 1956 1957 if (paPages[iPage].idSharedPage != NIL_GMM_PAGEID) 1958 { 1959 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPages[iPage].idSharedPage); 1960 if (RT_LIKELY(pPage)) 1961 { 1962 if (RT_LIKELY(GMM_PAGE_IS_SHARED(pPage))) 2090 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPages[iPage].idSharedPage); 2091 if (RT_LIKELY(pPage)) 1963 2092 { 1964 AssertCompile(NIL_RTHCPHYS > GMM_GCPHYS_LAST && GMM_GCPHYS_UNSHAREABLE > GMM_GCPHYS_LAST); 1965 Assert(pPage->Shared.cRefs); 1966 Assert(pGVM->gmm.s.cSharedPages); 1967 Assert(pGVM->gmm.s.Allocated.cBasePages); 1968 1969 pGVM->gmm.s.cSharedPages--; 1970 pGVM->gmm.s.Allocated.cBasePages--; 1971 if (!--pPage->Shared.cRefs) 1972 gmmR0FreeSharedPage(pGMM, paPages[iPage].idSharedPage, pPage); 1973 1974 paPages[iPage].idSharedPage = NIL_GMM_PAGEID; 2093 if (RT_LIKELY(GMM_PAGE_IS_SHARED(pPage))) 2094 { 2095 AssertCompile(NIL_RTHCPHYS > GMM_GCPHYS_LAST && GMM_GCPHYS_UNSHAREABLE > GMM_GCPHYS_LAST); 2096 Assert(pPage->Shared.cRefs); 2097 Assert(pGVM->gmm.s.cSharedPages); 2098 Assert(pGVM->gmm.s.Allocated.cBasePages); 2099 2100 pGVM->gmm.s.cSharedPages--; 2101 pGVM->gmm.s.Allocated.cBasePages--; 2102 if (!--pPage->Shared.cRefs) 2103 gmmR0FreeSharedPage(pGMM, paPages[iPage].idSharedPage, pPage); 2104 2105 paPages[iPage].idSharedPage = NIL_GMM_PAGEID; 2106 } 2107 else 2108 { 2109 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not shared!\n", iPage, paPages[iPage].idSharedPage)); 2110 rc = VERR_GMM_PAGE_NOT_SHARED; 2111 break; 2112 } 1975 2113 } 1976 2114 else 1977 2115 { 1978 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not shared!\n", iPage, paPages[iPage].idSharedPage));1979 rc = VERR_GMM_PAGE_NOT_ SHARED;2116 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not found! (shared)\n", iPage, paPages[iPage].idSharedPage)); 2117 rc = VERR_GMM_PAGE_NOT_FOUND; 1980 2118 break; 1981 2119 } 1982 2120 } 1983 else 1984 { 1985 Log(("GMMR0AllocateHandyPages: #%#x/%#x: Not found! (shared)\n", iPage, paPages[iPage].idSharedPage)); 1986 rc = VERR_GMM_PAGE_NOT_FOUND; 2121 } 2122 2123 /* 2124 * Join paths with GMMR0AllocatePages for the allocation. 2125 * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex! 2126 */ 2127 while (RT_SUCCESS(rc)) 2128 { 2129 rc = gmmR0AllocatePages(pGMM, pGVM, cPagesToAlloc, paPages, GMMACCOUNT_BASE); 2130 if ( rc != VERR_GMM_SEED_ME 2131 || pGMM->fLegacyAllocationMode) 1987 2132 break; 1988 }2133 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPagesToAlloc); 1989 2134 } 1990 2135 } 1991 1992 /* 1993 * Join paths with GMMR0AllocatePages for the allocation. 1994 * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex! 1995 */ 1996 while (RT_SUCCESS(rc)) 1997 { 1998 rc = gmmR0AllocatePages(pGMM, pGVM, cPagesToAlloc, paPages, GMMACCOUNT_BASE); 1999 if ( rc != VERR_GMM_SEED_ME 2000 || pGMM->fLegacyAllocationMode) 2001 break; 2002 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPagesToAlloc); 2003 } 2136 else 2137 rc = VERR_WRONG_ORDER; 2138 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 2004 2139 } 2005 2140 else 2006 rc = VERR_WRONG_ORDER; 2007 2141 rc = VERR_INTERNAL_ERROR_5; 2008 2142 RTSemFastMutexRelease(pGMM->Mtx); 2009 2143 LogFlow(("GMMR0AllocateHandyPages: returns %Rrc\n", rc)); … … 2068 2202 rc = RTSemFastMutexRequest(pGMM->Mtx); 2069 2203 AssertRC(rc); 2070 2071 /* No allocations before the initial reservation has been made! */ 2072 if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages 2073 && pGVM->gmm.s.Reserved.cFixedPages 2074 && pGVM->gmm.s.Reserved.cShadowPages)) 2075 { 2076 /* 2077 * gmmR0AllocatePages seed loop. 2078 * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex! 2079 */ 2080 while (RT_SUCCESS(rc)) 2081 { 2082 rc = gmmR0AllocatePages(pGMM, pGVM, cPages, paPages, enmAccount); 2083 if ( rc != VERR_GMM_SEED_ME 2084 || pGMM->fLegacyAllocationMode) 2085 break; 2086 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPages); 2087 } 2204 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 2205 { 2206 2207 /* No allocations before the initial reservation has been made! */ 2208 if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages 2209 && pGVM->gmm.s.Reserved.cFixedPages 2210 && pGVM->gmm.s.Reserved.cShadowPages)) 2211 { 2212 /* 2213 * gmmR0AllocatePages seed loop. 2214 * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex! 2215 */ 2216 while (RT_SUCCESS(rc)) 2217 { 2218 rc = gmmR0AllocatePages(pGMM, pGVM, cPages, paPages, enmAccount); 2219 if ( rc != VERR_GMM_SEED_ME 2220 || pGMM->fLegacyAllocationMode) 2221 break; 2222 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPages); 2223 } 2224 } 2225 else 2226 rc = VERR_WRONG_ORDER; 2227 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 2088 2228 } 2089 2229 else 2090 rc = VERR_WRONG_ORDER; 2091 2230 rc = VERR_INTERNAL_ERROR_5; 2092 2231 RTSemFastMutexRelease(pGMM->Mtx); 2093 2232 LogFlow(("GMMR0AllocatePages: returns %Rrc\n", rc)); … … 2232 2371 { 2233 2372 pChunk->cFree++; 2234 pChunk->pSet->c Pages++;2373 pChunk->pSet->cFreePages++; 2235 2374 2236 2375 /* … … 2458 2597 rc = RTSemFastMutexRequest(pGMM->Mtx); 2459 2598 AssertRC(rc); 2460 2461 rc = gmmR0FreePages(pGMM, pGVM, cPages, paPages, enmAccount); 2462 2599 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 2600 { 2601 rc = gmmR0FreePages(pGMM, pGVM, cPages, paPages, enmAccount); 2602 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 2603 } 2604 else 2605 rc = VERR_INTERNAL_ERROR_5; 2463 2606 RTSemFastMutexRelease(pGMM->Mtx); 2464 2607 LogFlow(("GMMR0FreePages: returns %Rrc\n", rc)); … … 2546 2689 rc = RTSemFastMutexRequest(pGMM->Mtx); 2547 2690 AssertRC(rc); 2548 if (pGVM->gmm.s.Allocated.cBasePages >= cPagesToFree) 2549 { 2550 /* 2551 * Record the ballooned memory. 2552 */ 2553 pGMM->cBalloonedPages += cBalloonedPages; 2554 if (pGVM->gmm.s.cReqBalloonedPages) 2555 { 2556 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2557 pGVM->gmm.s.cReqActuallyBalloonedPages += cBalloonedPages; 2558 if (fCompleted) 2691 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 2692 { 2693 2694 if (pGVM->gmm.s.Allocated.cBasePages >= cPagesToFree) 2695 { 2696 /* 2697 * Record the ballooned memory. 2698 */ 2699 pGMM->cBalloonedPages += cBalloonedPages; 2700 if (pGVM->gmm.s.cReqBalloonedPages) 2559 2701 { 2560 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx; / VM: Total=%#llx Req=%#llx Actual=%#llx (completed)\n", cBalloonedPages, 2561 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages)); 2562 2563 /* 2564 * Anything we need to do here now when the request has been completed? 2565 */ 2566 pGVM->gmm.s.cReqBalloonedPages = 0; 2702 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2703 pGVM->gmm.s.cReqActuallyBalloonedPages += cBalloonedPages; 2704 if (fCompleted) 2705 { 2706 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx; / VM: Total=%#llx Req=%#llx Actual=%#llx (completed)\n", cBalloonedPages, 2707 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages)); 2708 2709 /* 2710 * Anything we need to do here now when the request has been completed? 2711 */ 2712 pGVM->gmm.s.cReqBalloonedPages = 0; 2713 } 2714 else 2715 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n", cBalloonedPages, 2716 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages)); 2567 2717 } 2568 2718 else 2569 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n", cBalloonedPages, 2570 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages)); 2719 { 2720 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2721 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx (user)\n", 2722 cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages)); 2723 } 2724 2725 /* 2726 * Any pages to free? 2727 */ 2728 if (cPagesToFree) 2729 rc = gmmR0FreePages(pGMM, pGVM, cPagesToFree, paPages, GMMACCOUNT_BASE); 2571 2730 } 2572 2731 else 2573 { 2574 pGVM->gmm.s.cBalloonedPages += cBalloonedPages; 2575 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx (user)\n", 2576 cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages)); 2577 } 2578 2579 /* 2580 * Any pages to free? 2581 */ 2582 if (cPagesToFree) 2583 rc = gmmR0FreePages(pGMM, pGVM, cPagesToFree, paPages, GMMACCOUNT_BASE); 2732 rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH; 2733 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 2584 2734 } 2585 2735 else 2586 { 2587 rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH; 2588 } 2589 2736 rc = VERR_INTERNAL_ERROR_5; 2590 2737 RTSemFastMutexRelease(pGMM->Mtx); 2591 2738 LogFlow(("GMMR0BalloonedPages: returns %Rrc\n", rc)); … … 2652 2799 rc = RTSemFastMutexRequest(pGMM->Mtx); 2653 2800 AssertRC(rc); 2654 2655 if (pGVM->gmm.s.cBalloonedPages < cPages) 2656 { 2657 Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.cBalloonedPages); 2658 2659 /* 2660 * Record it. 2661 */ 2662 pGMM->cBalloonedPages -= cPages; 2663 pGVM->gmm.s.cBalloonedPages -= cPages; 2664 if (pGVM->gmm.s.cReqDeflatePages) 2665 { 2666 Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx Req=%#llx\n", cPages, 2667 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqDeflatePages)); 2801 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 2802 { 2803 2804 if (pGVM->gmm.s.cBalloonedPages < cPages) 2805 { 2806 Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.cBalloonedPages); 2668 2807 2669 2808 /* 2670 * Anything we need to do here now when the request has been completed?2809 * Record it. 2671 2810 */ 2672 pGVM->gmm.s.cReqDeflatePages = 0; 2811 pGMM->cBalloonedPages -= cPages; 2812 pGVM->gmm.s.cBalloonedPages -= cPages; 2813 if (pGVM->gmm.s.cReqDeflatePages) 2814 { 2815 Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx Req=%#llx\n", cPages, 2816 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqDeflatePages)); 2817 2818 /* 2819 * Anything we need to do here now when the request has been completed? 2820 */ 2821 pGVM->gmm.s.cReqDeflatePages = 0; 2822 } 2823 else 2824 Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx\n", cPages, 2825 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages)); 2673 2826 } 2674 2827 else 2675 Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx\n", cPages, 2676 pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages)); 2828 { 2829 Log(("GMMR0DeflatedBalloon: cBalloonedPages=%#llx cPages=%#x\n", pGVM->gmm.s.cBalloonedPages, cPages)); 2830 rc = VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH; 2831 } 2832 2833 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 2677 2834 } 2678 2835 else 2679 { 2680 Log(("GMMR0DeflatedBalloon: cBalloonedPages=%#llx cPages=%#x\n", pGVM->gmm.s.cBalloonedPages, cPages)); 2681 rc = VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH; 2682 } 2683 2836 rc = VERR_INTERNAL_ERROR_5; 2684 2837 RTSemFastMutexRelease(pGMM->Mtx); 2685 2838 LogFlow(("GMMR0BalloonedPages: returns %Rrc\n", rc)); … … 2860 3013 rc = RTSemFastMutexRequest(pGMM->Mtx); 2861 3014 AssertRC(rc); 2862 2863 PGMMCHUNK pMap = NULL; 2864 if (idChunkMap != NIL_GVM_HANDLE) 2865 { 2866 pMap = gmmR0GetChunk(pGMM, idChunkMap); 2867 if (RT_LIKELY(pMap)) 2868 rc = gmmR0MapChunk(pGMM, pGVM, pMap, ppvR3); 2869 else 2870 { 2871 Log(("GMMR0MapUnmapChunk: idChunkMap=%#x\n", idChunkMap)); 2872 rc = VERR_GMM_CHUNK_NOT_FOUND; 2873 } 2874 } 2875 2876 if ( idChunkUnmap != NIL_GMM_CHUNKID 2877 && RT_SUCCESS(rc)) 2878 { 2879 PGMMCHUNK pUnmap = gmmR0GetChunk(pGMM, idChunkUnmap); 2880 if (RT_LIKELY(pUnmap)) 2881 rc = gmmR0UnmapChunk(pGMM, pGVM, pUnmap); 2882 else 2883 { 2884 Log(("GMMR0MapUnmapChunk: idChunkUnmap=%#x\n", idChunkUnmap)); 2885 rc = VERR_GMM_CHUNK_NOT_FOUND; 2886 } 2887 2888 if (RT_FAILURE(rc) && pMap) 2889 gmmR0UnmapChunk(pGMM, pGVM, pMap); 2890 } 2891 3015 if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) 3016 { 3017 PGMMCHUNK pMap = NULL; 3018 if (idChunkMap != NIL_GVM_HANDLE) 3019 { 3020 pMap = gmmR0GetChunk(pGMM, idChunkMap); 3021 if (RT_LIKELY(pMap)) 3022 rc = gmmR0MapChunk(pGMM, pGVM, pMap, ppvR3); 3023 else 3024 { 3025 Log(("GMMR0MapUnmapChunk: idChunkMap=%#x\n", idChunkMap)); 3026 rc = VERR_GMM_CHUNK_NOT_FOUND; 3027 } 3028 } 3029 3030 if ( idChunkUnmap != NIL_GMM_CHUNKID 3031 && RT_SUCCESS(rc)) 3032 { 3033 PGMMCHUNK pUnmap = gmmR0GetChunk(pGMM, idChunkUnmap); 3034 if (RT_LIKELY(pUnmap)) 3035 rc = gmmR0UnmapChunk(pGMM, pGVM, pUnmap); 3036 else 3037 { 3038 Log(("GMMR0MapUnmapChunk: idChunkUnmap=%#x\n", idChunkUnmap)); 3039 rc = VERR_GMM_CHUNK_NOT_FOUND; 3040 } 3041 3042 if (RT_FAILURE(rc) && pMap) 3043 gmmR0UnmapChunk(pGMM, pGVM, pMap); 3044 } 3045 3046 GMM_CHECK_SANITY_UPON_LEAVING(pGMM); 3047 } 3048 else 3049 rc = VERR_INTERNAL_ERROR_5; 2892 3050 RTSemFastMutexRelease(pGMM->Mtx); 2893 3051
Note:
See TracChangeset
for help on using the changeset viewer.