VirtualBox

Changeset 20899 in vbox


Ignore:
Timestamp:
Jun 24, 2009 4:33:49 PM (16 years ago)
Author:
vboxsync
Message:

GMMR0.cpp: Sanity checks (disabled by default).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r20893 r20899  
    456456{
    457457    /** The number of free pages in the set. */
    458     uint64_t        cPages;
     458    uint64_t        cFreePages;
    459459    /** Chunks ordered by increasing number of free pages. */
    460460    PGMMCHUNK       apLists[GMM_CHUNK_FREE_SET_LISTS];
     
    562562
    563563
     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
    564607/*******************************************************************************
    565608*   Internal Functions                                                         *
     
    570613DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet);
    571614DECLINLINE(void) gmmR0UnlinkChunk(PGMMCHUNK pChunk);
     615static uint32_t gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uLineNo);
    572616static void gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
    573617static void gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage);
     
    746790    int rc = RTSemFastMutexRequest(pGMM->Mtx);
    747791    AssertRC(rc);
     792    GMM_CHECK_SANITY_UPON_ENTERING(pGMM);
    748793
    749794    /*
     
    847892    pGVM->gmm.s.fMayAllocate = false;
    848893
     894    GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
    849895    RTSemFastMutexRelease(pGMM->Mtx);
    850896
     
    10721118    rc = RTSemFastMutexRequest(pGMM->Mtx);
    10731119    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)
    10841125        {
    10851126            /*
    1086              * Update the records.
     1127             * Check if we can accomodate this.
    10871128             */
    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);
    10981149    }
    10991150    else
    1100         rc = VERR_WRONG_ORDER;
    1101 
     1151        rc = VERR_INTERNAL_ERROR_5;
    11021152    RTSemFastMutexRelease(pGMM->Mtx);
    11031153    LogFlow(("GMMR0InitialReservation: returns %Rrc\n", rc));
     
    11641214    rc = RTSemFastMutexRequest(pGMM->Mtx);
    11651215    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)
    11761221        {
    11771222            /*
    1178              * Update the records.
     1223             * Check if we can accomodate this.
    11791224             */
    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);
    11891244    }
    11901245    else
    1191         rc = VERR_WRONG_ORDER;
    1192 
     1246        rc = VERR_INTERNAL_ERROR_5;
    11931247    RTSemFastMutexRelease(pGMM->Mtx);
    11941248    LogFlow(("GMMR0UpdateReservation: returns %Rrc\n", rc));
     
    12151269
    12161270    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 */
     1285static 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 */
     1322static 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;
    12171331}
    12181332
     
    12881402    if (RT_LIKELY(pSet))
    12891403    {
    1290         pSet->cPages -= pChunk->cFree;
     1404        pSet->cFreePages -= pChunk->cFree;
    12911405
    12921406        PGMMCHUNK pPrev = pChunk->pFreePrev;
     
    13361450        pSet->apLists[iList] = pChunk;
    13371451
    1338         pSet->cPages += pChunk->cFree;
     1452        pSet->cFreePages += pChunk->cFree;
    13391453    }
    13401454}
     
    14461560        if (RT_SUCCESS(rc))
    14471561        {
    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))
    14521563            {
    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;
    14581580            }
    1459 
    1460             /* bail out */
    1461             rc = VERR_INTERNAL_ERROR;
     1581            else
     1582                rc = VERR_INTERNAL_ERROR_5;
     1583
    14621584            RTSemFastMutexRelease(pGMM->Mtx);
    14631585        }
     
    15151637    Assert(!pGMM->fLegacyAllocationMode);
    15161638
     1639    if (!GMM_CHECK_SANITY_IN_LOOPS(pGMM))
     1640        return VERR_INTERNAL_ERROR_4;
     1641
    15171642    if (!pGMM->fBoundMemoryMode)
    15181643    {
     
    15211646         */
    15221647        PGMMCHUNKFREESET pOtherSet = pSet == &pGMM->Private ? &pGMM->Shared : &pGMM->Private;
    1523         while (     pSet->cPages < cPages
    1524                &&   pOtherSet->cPages >= GMM_CHUNK_NUM_PAGES)
     1648        while (     pSet->cFreePages < cPages
     1649               &&   pOtherSet->cFreePages >= GMM_CHUNK_NUM_PAGES)
    15251650        {
    15261651            PGMMCHUNK pChunk = pOtherSet->apLists[GMM_CHUNK_FREE_SET_LISTS - 1];
     
    15391664         *       gmmR0AllocateOneChunk will re-take it temporarily while registering the chunk.
    15401665         */
    1541         while (pSet->cPages < cPages)
     1666        while (pSet->cFreePages < cPages)
    15421667        {
    15431668            RTSemFastMutexRelease(pGMM->Mtx);
     
    15471672            if (RT_FAILURE(rc))
    15481673                return rc;
     1674            if (!GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
     1675                return VERR_INTERNAL_ERROR_5;
    15491676        }
    15501677    }
     
    15821709            if (RT_FAILURE(rc))
    15831710                return rc;
     1711            if (!GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
     1712                return VERR_INTERNAL_ERROR_5;
    15841713        }
    15851714    }
     
    16991828    PGMMCHUNKFREESET pSet = &pGMM->Private;
    17001829#if 0 /** @todo this is broken, at least on windows... */
    1701     if (pSet->cPages < cPages)
     1830    if (pSet->cFreePages < cPages)
    17021831        return VERR_GMM_SEED_ME;
    17031832#endif
     
    17171846            return VERR_GMM_SEED_ME;
    17181847    }
    1719     else if (pSet->cPages < cPages) /* see #if 0 */
     1848    else if (pSet->cFreePages < cPages) /* see #if 0 */
    17201849        return VERR_GMM_SEED_ME;
    17211850
     
    19012030    rc = RTSemFastMutexRequest(pGMM->Mtx);
    19022031    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.cFixedPages
    1907                   &&  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++)
    19162045            {
    1917                 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPages[iPage].idPage);
    1918                 if (RT_LIKELY(pPage))
     2046                if (paPages[iPage].idPage != NIL_GMM_PAGEID)
    19192047                {
    1920                     if (RT_LIKELY(GMM_PAGE_IS_PRIVATE(pPage)))
     2048                    PGMMPAGE pPage = gmmR0GetPage(pGMM, paPages[iPage].idPage);
     2049                    if (RT_LIKELY(pPage))
    19212050                    {
    1922                         if (RT_LIKELY(pPage->Private.hGVM == pGVM->hSelf))
     2051                        if (RT_LIKELY(GMM_PAGE_IS_PRIVATE(pPage)))
    19232052                        {
    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                            }
    19332072                        }
    19342073                        else
    19352074                        {
    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;
    19392077                            break;
    19402078                        }
     
    19422080                    else
    19432081                    {
    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;
    19462084                        break;
    19472085                    }
    19482086                }
    1949                 else
     2087
     2088                if (paPages[iPage].idSharedPage != NIL_GMM_PAGEID)
    19502089                {
    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))
    19632092                    {
    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                        }
    19752113                    }
    19762114                    else
    19772115                    {
    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;
    19802118                        break;
    19812119                    }
    19822120                }
    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)
    19872132                    break;
    1988                 }
     2133                rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPagesToAlloc);
    19892134            }
    19902135        }
    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);
    20042139    }
    20052140    else
    2006         rc = VERR_WRONG_ORDER;
    2007 
     2141        rc = VERR_INTERNAL_ERROR_5;
    20082142    RTSemFastMutexRelease(pGMM->Mtx);
    20092143    LogFlow(("GMMR0AllocateHandyPages: returns %Rrc\n", rc));
     
    20682202    rc = RTSemFastMutexRequest(pGMM->Mtx);
    20692203    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);
    20882228    }
    20892229    else
    2090         rc = VERR_WRONG_ORDER;
    2091 
     2230        rc = VERR_INTERNAL_ERROR_5;
    20922231    RTSemFastMutexRelease(pGMM->Mtx);
    20932232    LogFlow(("GMMR0AllocatePages: returns %Rrc\n", rc));
     
    22322371    {
    22332372        pChunk->cFree++;
    2234         pChunk->pSet->cPages++;
     2373        pChunk->pSet->cFreePages++;
    22352374
    22362375        /*
     
    24582597    rc = RTSemFastMutexRequest(pGMM->Mtx);
    24592598    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;
    24632606    RTSemFastMutexRelease(pGMM->Mtx);
    24642607    LogFlow(("GMMR0FreePages: returns %Rrc\n", rc));
     
    25462689    rc = RTSemFastMutexRequest(pGMM->Mtx);
    25472690    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)
    25592701            {
    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));
    25672717            }
    25682718            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);
    25712730        }
    25722731        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);
    25842734    }
    25852735    else
    2586     {
    2587         rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
    2588     }
    2589 
     2736        rc = VERR_INTERNAL_ERROR_5;
    25902737    RTSemFastMutexRelease(pGMM->Mtx);
    25912738    LogFlow(("GMMR0BalloonedPages: returns %Rrc\n", rc));
     
    26522799    rc = RTSemFastMutexRequest(pGMM->Mtx);
    26532800    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);
    26682807
    26692808            /*
    2670              * Anything we need to do here now when the request has been completed?
     2809             * Record it.
    26712810             */
    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));
    26732826        }
    26742827        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);
    26772834    }
    26782835    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;
    26842837    RTSemFastMutexRelease(pGMM->Mtx);
    26852838    LogFlow(("GMMR0BalloonedPages: returns %Rrc\n", rc));
     
    28603013    rc = RTSemFastMutexRequest(pGMM->Mtx);
    28613014    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;
    28923050    RTSemFastMutexRelease(pGMM->Mtx);
    28933051
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette