VirtualBox

Changeset 37242 in vbox for trunk


Ignore:
Timestamp:
May 27, 2011 4:17:12 PM (14 years ago)
Author:
vboxsync
Message:

GMMR0: Keep the free bound-mode memory in the GVM instead of in GMM.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/gvm.h

    r36448 r37242  
    100100        struct GMMPERVM     s;
    101101#endif
    102         uint8_t             padding[256];
     102        uint8_t             padding[512];
    103103    } gmm;
    104    
     104
    105105    /** The RAWPCIVM per vm data. */
    106106    union
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r37214 r37242  
    176176/** Pointer to set of free chunks.  */
    177177typedef struct GMMCHUNKFREESET *PGMMCHUNKFREESET;
    178 
    179 /** Pointer to a GMM allocation chunk. */
    180 typedef struct GMMCHUNK *PGMMCHUNK;
    181178
    182179/**
     
    467464
    468465
    469 /** The GMMCHUNK::cFree shift count employed by gmmR0SelectFreeSetList. */
    470 #define GMM_CHUNK_FREE_SET_SHIFT    4
    471 /** 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 GMMCHUNKFREESET
    481 {
    482     /** The number of free pages in the set. */
    483     uint64_t            cFreePages;
    484     /** The generation ID for the set.  This is incremented whenever
    485      *  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 
    493466/**
    494467 * The GMM instance data.
     
    512485    GMMCHUNKTLB         ChunkTLB;
    513486    /** The private free set. */
    514     GMMCHUNKFREESET     Private;
     487    GMMCHUNKFREESET     PrivateX;
    515488    /** The shared free set. */
    516489    GMMCHUNKFREESET     Shared;
     
    717690static DECLCALLBACK(int)     gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM);
    718691static bool                  gmmR0CleanupVMScanChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
     692DECLINLINE(void)             gmmR0UnlinkChunk(PGMMCHUNK pChunk);
    719693DECLINLINE(void)             gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet);
    720 DECLINLINE(void)             gmmR0UnlinkChunk(PGMMCHUNK pChunk);
     694DECLINLINE(void)             gmmR0SelectSetAndLinkChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
    721695static uint32_t              gmmR0SanityCheck(PGMM pGMM, const char *pszFunction, unsigned uLineNo);
    722696static bool                  gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSem);
    723 static void                  gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage);
     697static void                  gmmR0FreeSharedPage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage);
    724698static int                   gmmR0UnmapChunkLocked(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
    725699static void                  gmmR0SharedModuleCleanup(PGMM pGMM, PGVM pGVM);
     
    12471221         * Free empty chunks.
    12481222         */
     1223        PGMMCHUNKFREESET pPrivateSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX;
    12491224        do
    12501225        {
    12511226            fRedoFromStart = false;
    12521227            iCountDown = 10240;
    1253             pChunk = pGMM->Private.apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST];
     1228            pChunk = pPrivateSet->apLists[GMM_CHUNK_FREE_SET_UNUSED_LIST];
    12541229            while (pChunk)
    12551230            {
     
    12591234                    || pChunk->hGVM == pGVM->hSelf)
    12601235                {
    1261                     uint64_t const idGenerationOld = pGMM->Private.idGeneration;
     1236                    uint64_t const idGenerationOld = pPrivateSet->idGeneration;
    12621237                    if (gmmR0FreeChunk(pGMM, pGVM, pChunk, true /*fRelaxedSem*/))
    12631238                    {
    12641239                        /* We've left the giant mutex, restart? (+1 for our unlink) */
    1265                         fRedoFromStart = pGMM->Private.idGeneration != idGenerationOld + 1;
     1240                        fRedoFromStart = pPrivateSet->idGeneration != idGenerationOld + 1;
    12661241                        if (fRedoFromStart)
    12671242                            break;
     
    12751250                if (--iCountDown == 0)
    12761251                {
    1277                     uint64_t const idGenerationOld = pGMM->Private.idGeneration;
     1252                    uint64_t const idGenerationOld = pPrivateSet->idGeneration;
    12781253                    fRedoFromStart = gmmR0MutexYield(pGMM, &uLockNanoTS)
    1279                                   && pGMM->Private.idGeneration != idGenerationOld;
     1254                                  && pPrivateSet->idGeneration != idGenerationOld;
    12801255                    if (fRedoFromStart)
    12811256                        break;
     
    13871362                cShared++;
    13881363
    1389         gmmR0LinkChunk(pChunk, pChunk->cShared ? &g_pGMM->Shared : &g_pGMM->Private);
     1364        gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk);
    13901365
    13911366        /*
     
    14201395            gmmR0UnlinkChunk(pChunk);
    14211396            pChunk->cFree = GMM_CHUNK_NUM_PAGES;
    1422             gmmR0LinkChunk(pChunk, pChunk->cShared ? &g_pGMM->Shared : &g_pGMM->Private);
     1397            gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk);
    14231398        }
    14241399    }
     
    17171692    uint32_t cErrors = 0;
    17181693
    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);
    17211696    /** @todo add more sanity checks. */
    17221697
     
    18791854    }
    18801855}
     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 */
     1865DECLINLINE(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
    18811877
    18821878
     
    20962092         * Try steal free chunks from the other set first. (Only take 100% free chunks.)
    20972093         */
    2098         PGMMCHUNKFREESET pOtherSet = pSet == &pGMM->Private ? &pGMM->Shared : &pGMM->Private;
     2094        PGMMCHUNKFREESET pOtherSet = pSet == &pGMM->PrivateX ? &pGMM->Shared : &pGMM->PrivateX;
    20992095        while (     pSet->cFreePages < cPages
    21002096               &&   pOtherSet->cFreePages >= GMM_CHUNK_NUM_PAGES)
    21012097        {
    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];
    21062099            if (!pChunk)
    21072100                break;
     2101            Assert(pChunk->cFree != GMM_CHUNK_NUM_PAGES);
    21082102
    21092103            gmmR0UnlinkChunk(pChunk);
     
    22742268     * is a bit extra work but it's easier to do it upfront than bailing out later.
    22752269     */
    2276     PGMMCHUNKFREESET pSet = &pGMM->Private;
     2270    PGMMCHUNKFREESET pSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX;
    22772271    if (pSet->cFreePages < cPages)
    22782272        return VERR_GMM_SEED_ME;
     
    25612555                            pGVM->gmm.s.Allocated.cBasePages--;
    25622556                            if (!--pPage->Shared.cRefs)
    2563                             {
    2564                                 gmmR0FreeSharedPage(pGMM, paPages[iPage].idSharedPage, pPage);
    2565                             }
     2557                                gmmR0FreeSharedPage(pGMM, pGVM, paPages[iPage].idSharedPage, pPage);
    25662558                            else
    25672559                            {
     
    25922584             * Note! gmmR0AllocateMoreChunks may leave the protection of the mutex!
    25932585             */
     2586#if 0
     2587            rc = gmmR0AllocatePagesNew(pGMM, pGVM, cPagesToAlloc, paPages, GMMACCOUNT_BASE);
     2588#else
    25942589            GMMR0ALLOCPAGESTRATEGY Strategy;
    25952590            gmmR0AllocatePagesInitStrategy(pGMM, pGVM, &Strategy);
     
    26002595                    ||  pGMM->fLegacyAllocationMode)
    26012596                    break;
    2602                 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPagesToAlloc, &Strategy);
     2597                rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->PrivateX, cPagesToAlloc, &Strategy);
    26032598            }
     2599#endif
    26042600        }
    26052601        else
     
    26902686                    ||  pGMM->fLegacyAllocationMode)
    26912687                    break;
    2692                 rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->Private, cPages, &Strategy);
     2688                rc = gmmR0AllocateMoreChunks(pGMM, pGVM, &pGMM->PrivateX, cPages, &Strategy);
    26932689            }
    26942690        }
     
    27992795        if (RT_SUCCESS(rc))
    28002796        {
     2797            PGMMCHUNKFREESET pSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX;
    28012798            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);
    28032800            if (RT_SUCCESS(rc))
    28042801            {
     
    28262823                pGMM->cAllocatedPages            += cPages;
    28272824
    2828                 gmmR0LinkChunk(pChunk, &pGMM->Private);
     2825                gmmR0LinkChunk(pChunk, pSet);
    28292826                gmmR0MutexRelease(pGMM);
    28302827            }
     
    30333030 *
    30343031 * @param   pGMM        Pointer to the GMM instance data.
     3032 * @param   pGVM        Pointer to the GVM instance.
    30353033 * @param   pChunk      Pointer to the chunk this page belongs to.
    30363034 * @param   idPage      The Page ID.
    30373035 * @param   pPage       Pointer to the page.
    30383036 */
    3039 static void gmmR0FreePageWorker(PGMM pGMM, PGMMCHUNK pChunk, uint32_t idPage, PGMMPAGE pPage)
     3037static void gmmR0FreePageWorker(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, uint32_t idPage, PGMMPAGE pPage)
    30403038{
    30413039    Log3(("F pPage=%p iPage=%#x/%#x u2State=%d iFreeHead=%#x\n",
     
    30613059        gmmR0UnlinkChunk(pChunk);
    30623060        pChunk->cFree++;
    3063         gmmR0LinkChunk(pChunk, pChunk->cShared ? &pGMM->Shared : &pGMM->Private);
     3061        gmmR0SelectSetAndLinkChunk(pGMM, pGVM, pChunk);
    30643062    }
    30653063    else
     
    30923090 *
    30933091 * @param   pGMM        Pointer to the GMM instance.
     3092 * @param   pGVM        Pointer to the GVM instance.
    30943093 * @param   idPage      The Page ID
    30953094 * @param   pPage       The page structure.
    30963095 */
    3097 DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage)
     3096DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage)
    30983097{
    30993098    PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
     
    31083107    pGMM->cAllocatedPages--;
    31093108    pGMM->cSharedPages--;
    3110     gmmR0FreePageWorker(pGMM, pChunk, 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. */
    31143113
    31153114/**
     
    31693168 *
    31703169 * @param   pGMM        Pointer to the GMM instance.
     3170 * @param   pGVM        Pointer to the GVM instance.
    31713171 * @param   idPage      The Page ID
    31723172 * @param   pPage       The page structure.
    31733173 */
    3174 DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, uint32_t idPage, PGMMPAGE pPage)
     3174DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage)
    31753175{
    31763176    PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
     
    31823182    pChunk->cPrivate--;
    31833183    pGMM->cAllocatedPages--;
    3184     gmmR0FreePageWorker(pGMM, pChunk, idPage, pPage);
     3184    gmmR0FreePageWorker(pGMM, pGVM, pChunk, idPage, pPage);
    31853185}
    31863186
     
    32503250                    Assert(pGVM->gmm.s.cPrivatePages);
    32513251                    pGVM->gmm.s.cPrivatePages--;
    3252                     gmmR0FreePrivatePage(pGMM, idPage, pPage);
     3252                    gmmR0FreePrivatePage(pGMM, pGVM, idPage, pPage);
    32533253                }
    32543254                else
     
    32663266                Assert(pPage->Shared.cRefs);
    32673267                if (!--pPage->Shared.cRefs)
    3268                     gmmR0FreeSharedPage(pGMM, idPage, pPage);
     3268                    gmmR0FreeSharedPage(pGMM, pGVM, idPage, pPage);
    32693269                else
    32703270                {
     
    40254025    if (RT_SUCCESS(rc))
    40264026    {
    4027         rc = gmmR0RegisterChunk(pGMM, &pGMM->Private, MemObj, pGVM->hSelf, 0 /*fChunkFlags*/, NULL);
     4027        rc = gmmR0RegisterChunk(pGMM, &pGVM->gmm.s.Private, MemObj, pGVM->hSelf, 0 /*fChunkFlags*/, NULL);
    40284028        if (RT_SUCCESS(rc))
    40294029            gmmR0MutexRelease(pGMM);
  • trunk/src/VBox/VMM/VMMR0/GMMR0Internal.h

    r35346 r37242  
    6464typedef GMMSHAREDMODULEPERVM *PGMMSHAREDMODULEPERVM;
    6565
     66
     67/** Pointer to a GMM allocation chunk. */
     68typedef 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 */
     80typedef 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
    6694/**
    6795 * The per-VM GMM data.
     
    6997typedef struct GMMPERVM
    7098{
     99    /** Free set for use in bound mode. */
     100    GMMCHUNKFREESET     Private;
     101
    71102    /** The reservations. */
    72103    GMMVMSIZES          Reserved;
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