VirtualBox

Changeset 5018 in vbox for trunk


Ignore:
Timestamp:
Sep 24, 2007 10:24:07 PM (17 years ago)
Author:
vboxsync
Message:

some code...

File:
1 edited

Legend:

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

    r5017 r5018  
    178178        uint32_t    pfn;
    179179        /** The GVM handle. (64K VMs) */
    180         uint32_t    iGVM : 16;
     180        uint32_t    hGVM : 16;
    181181        /** Reserved. */
    182182        uint32_t    u16Reserved : 14;
     
    190190        /** The reference count. */
    191191        uint32_t    cRefs;
    192         /** Reserved. Checksum or something? Two iGVMs for forking? */
     192        /** Reserved. Checksum or something? Two hGVMs for forking? */
    193193        uint32_t    u30Reserved : 30;
    194194        /** The page state. */
     
    222222        uint32_t    pfn : 24;
    223223        /** The GVM handle. (127 VMs) */
    224         uint32_t    iGVM : 7;
     224        uint32_t    hGVM : 7;
    225225        /** The top page state bit, MBZ. */
    226226        uint32_t    fZero : 1;
     
    339339     * is used as a preference when there are several chunks to choose from.
    340340     * When in legacy mode this isn't a preference any longer. */
    341     uint16_t        iGVM;
     341    uint16_t        hGVM;
    342342    /** The number of private pages. */
    343343    uint16_t        cPrivate;
     
    396396typedef struct GMM
    397397{
     398    /** Magic / eye catcher. GMM_MAGIC */
     399    uint32_t            u32Magic;
    398400    /** The fast mutex protecting the GMM.
    399401     * More fine grained locking can be implemented later if necessary. */
     
    417419typedef GMM *PGMM;
    418420
    419 
     421/** The value of GMM::u32Magic (Katsuhiro Otomo). */
     422#define GMM_MAGIC       0x19540414
     423
     424
     425
     426/*******************************************************************************
     427*   Internal Functions                                                         *
     428*******************************************************************************/
     429static DECLCALLBACK int gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM);
     430
     431
     432
     433/**
     434 * Initializes the GMM component.
     435 *
     436 * This is called when the VMMR0.r0 module is loaded and protected by the
     437 * loader semaphore.
     438 *
     439 * @returns VBox status code.
     440 */
     441GMMR0DECL(int) GMMR0Init(void)
     442{
     443    LogFlow(("GMMInit:\n"));
     444
     445    /*
     446     * Allocate the instance data and the lock(s).
     447     */
     448    PGMM pGMM = (PGMM)RTMemAllocZ(sizeof(*pGMM));
     449    if (!pGMM)
     450        return VERR_NO_MEMORY;
     451    pGMM->u32Magic = GMM_MAGIC;
     452    for (unsigned i = 0; i < RT_ELEMENTS(pGMM->ChunkTLB.aEntries); i++)
     453        pGMM->ChunkTLB.aEntries[i].idChunk = NIL_GMM_CHUNKID;
     454
     455    int rc = RTSemFastMutexCreate(&pGMM->Mtx);
     456    if (RT_SUCCESS(rc))
     457    {
     458        /*
     459         * Check and see if RTR0MemObjAllocPhysNC works.
     460         */
     461        RTR0MEMOBJ MemObj;
     462        rc = RTR0MemObjAllocPhysNC(&MemObj, _64K, NIL_RTHCPHYS);
     463        if (RT_SUCCESS(rc))
     464        {
     465            rc = RTR0MemObjFree(MemObj, true);
     466            AssertRC(rc);
     467        }
     468        else if (rc == VERR_NOT_SUPPORTED)
     469            pGMM->fLegacyMode = true;
     470        else
     471            SUPR0Printf("GMMR0Init: RTR0MemObjAllocPhysNC(,64K,Any) -> %d!\n", rc);
     472
     473        g_pGMM = pGMM;
     474        LogFlow(("GMMInit: pGMM=%p fLegacy=%RTbool\n", pGMM, pGMM->fLegacyMode));
     475        return VINF_SUCCESS;
     476    }
     477
     478    RTMemFree(pGMM);
     479    SUPR0Printf("GMMR0Init: failed! rc=%d\n", rc);
     480    return rc;
     481}
     482
     483
     484/**
     485 * Terminates the GMM component.
     486 */
     487GMMR0DECL(void) GMMR0Term(void)
     488{
     489    LogFlow(("GMMTerm:\n"));
     490
     491    /*
     492     * Take care / be paranoid...
     493     */
     494    PGMM pGMM = g_pGMM;
     495    if (!VALID_PTR(pGMM))
     496        return;
     497    if (pGMM->u32Magic != GMM_MAGIC)
     498    {
     499        SUPR0Printf("GMMR0Term: u32Magic=%#x\n", pGMM->u32Magic);
     500        return;
     501    }
     502
     503    /*
     504     * Undo what init did and free any resources we've acquired.
     505     */
     506    /* Destroy the fundamentals. */
     507    g_pGMM = NULL;
     508    pGMM->u32Magic++;
     509    RTSemEventDestroy(&pGMM->Mtx);
     510    pGMM->Mtx = NIL_RTSEMFASTMUTEX;
     511
     512    /* free any chunks still hanging around. */
     513    RTAvlU32Destroy(pGMM->Chunks, gmmR0TermDestroyChunk, pGMM);
     514
     515    /* finally the instance data itself. */
     516    RTMemFree(pGMM);
     517    LogFlow(("GMMTerm: done\n"));
     518}
     519
     520
     521/**
     522 * RTAvlU32Destroy callback.
     523 *
     524 * @returns 0
     525 * @param   pNode   The node to destroy.
     526 * @param   pvGMM   The GMM handle.
     527 */
     528static DECLCALLBACK int gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM)
     529{
     530    PGMMCHUNK pChunk = (PGMMCHUNK) pNode;
     531
     532    if (pChunk->cFree != (GMM_CHUNK_SIZE >> PAGE_SHIFT))
     533        SUPR0Printf("GMMR0Term: %p/%#x: cFree=%d cPrivate=%d cShared=%d cMappings=%d\n", pChunk,
     534                    pChunk->Core.Key, pChunk->cFree, pChunk->cPrivate, pChunk->cShared, pChunk->cMappings);
     535
     536    int rc = RTR0MemObjFree(pChunk->MemObj, true /* fFreeMappings */);
     537    if (RT_FAILURE(rc))
     538    {
     539        SUPR0Printf("GMMR0Term: %p/%#x: RTRMemObjFree(%p,true) -> %d (cMappings=%d)\n", pChunk,
     540                    pChunk->Core.Key, pChunk->MemObj, rc, pChunk->cMappings);
     541        AssertRC(rc);
     542    }
     543    pChunk->MemObj = NIL_RTR0MEMOBJ;
     544
     545    RTMemFree(pChunk->paMappings);
     546    pChunk->paMappings = NULL;
     547
     548    RTMemFree(pChunk);
     549    NOREF(pvGMM);
     550    return 0;
     551}
     552
     553
     554/**
     555 * Cleans up when a VM is terminated.
     556 *
     557 * @param   pVM     The VM structure.
     558 * @param   hGVM    The global VM handle.
     559 */
     560GMMR0DECL(void) GMMR0CleanupVM(PVM pVM, uint32_t hGVM)
     561{
     562    LogFlow(("GMMR0CleanupVM: pVM=%p hGVM=%#x\n", pVM, hGVM));
     563
     564    PGMM pGMM = g_pGMM;
     565    if (    !VALID_PTR(pGMM)
     566        ||  pGMM->u32Magic != GMM_MAGIC)
     567        return;
     568
     569    int rc =  RTSemFastMutexRequest(pGMM->Mtx);
     570    AssertRC(rc);
     571
     572    /*
     573     * Walk the entire pool looking for pages that belongs to this VM.
     574     * This is slow but necessary. Of course it won't work for shared
     575     * pages, but we'll deal with that later.
     576     */
     577
     578
     579    /*
     580     * Update over-commitment management and free chunks that are no
     581     * longer needed. If no VMs are around, free everything.
     582     */
     583
     584
     585    RTSemFastMutexRelease(pGMM->Mtx);
     586    LogFlow(("GMMR0CleanupVM: returns\n"));
     587}
     588
     589
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