VirtualBox

Changeset 38956 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Oct 6, 2011 12:43:01 PM (13 years ago)
Author:
vboxsync
Message:

PGM: Avoid requiring a full tree walk to age the mapping chunks (changes the age into a time stamp).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r38955 r38956  
    37033703    /* Age compression - ASSUMES iNow == 4. */
    37043704    PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode;
    3705     if (pChunk->iAge >= UINT32_C(0xffffff00))
    3706         pChunk->iAge = 3;
    3707     else if (pChunk->iAge >= UINT32_C(0xfffff000))
    3708         pChunk->iAge = 2;
    3709     else if (pChunk->iAge)
    3710         pChunk->iAge = 1;
    3711     else /* iAge = 0 */
    3712         pChunk->iAge = 4;
     3705    if (pChunk->iLastUsed >= UINT32_C(0xffffff00))
     3706        pChunk->iLastUsed = 3;
     3707    else if (pChunk->iLastUsed >= UINT32_C(0xfffff000))
     3708        pChunk->iLastUsed = 2;
     3709    else if (pChunk->iLastUsed)
     3710        pChunk->iLastUsed = 1;
     3711    else /* iLastUsed = 0 */
     3712        pChunk->iLastUsed = 4;
    37133713    return 0;
    3714 }
    3715 
    3716 
    3717 /**
    3718  * Tree enumeration callback that updates the chunks that have
    3719  * been used since the last
    3720  */
    3721 static DECLCALLBACK(int) pgmR3PhysChunkAgeingCallback(PAVLU32NODECORE pNode, void *pvUser)
    3722 {
    3723     PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode;
    3724     if (!pChunk->iAge)
    3725     {
    3726         PVM pVM = (PVM)pvUser;
    3727         pChunk->iAge = pVM->pgm.s.ChunkR3Map.iNow;
    3728     }
    3729     return 0;
    3730 }
    3731 
    3732 
    3733 /**
    3734  * Performs ageing of the ring-3 chunk mappings.
    3735  *
    3736  * @param   pVM         The VM handle.
    3737  */
    3738 VMMR3DECL(void) PGMR3PhysChunkAgeing(PVM pVM)
    3739 {
    3740     pgmLock(pVM);
    3741     pVM->pgm.s.ChunkR3Map.AgeingCountdown = RT_MIN(pVM->pgm.s.ChunkR3Map.cMax / 4, 1024);
    3742     pVM->pgm.s.ChunkR3Map.iNow++;
    3743     if (pVM->pgm.s.ChunkR3Map.iNow == 0)
    3744     {
    3745         pVM->pgm.s.ChunkR3Map.iNow = 4;
    3746         RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingRolloverCallback, pVM);
    3747     }
    3748     else
    3749         RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingCallback, pVM);
    3750     pgmUnlock(pVM);
    37513714}
    37523715
     
    37593722    PVM                 pVM;            /**< The VM handle. */
    37603723    PPGMCHUNKR3MAP      pChunk;         /**< The chunk to unmap. */
    3761     uint32_t            iLastAge;       /**< Highest age found so far. */
    37623724} PGMR3PHYSCHUNKUNMAPCB, *PPGMR3PHYSCHUNKUNMAPCB;
    37633725
     
    37733735
    37743736    /*
    3775      * Check for locks and age.
     3737     * Check for locks and compare when last used.
    37763738     */
    37773739    if (pChunk->cRefs)
    37783740        return 0;
    3779     if (!pChunk->iAge)
     3741    if (pChunk->cPermRefs)
    37803742        return 0;
    3781     if (pArg->iLastAge >= pChunk->iAge)
     3743    if (   pArg->pChunk
     3744        && pChunk->iLastUsed >= pArg->pChunk->iLastUsed)
    37823745        return 0;
    37833746
     
    38043767            return 0;
    38053768
    3806     pArg->pChunk   = pChunk;
    3807     pArg->iLastAge = pChunk->iAge;
     3769    pArg->pChunk = pChunk;
    38083770    return 0;
    38093771}
     
    38243786
    38253787    /*
    3826      * Do tree ageing first?
    3827      */
    3828     if (pVM->pgm.s.ChunkR3Map.AgeingCountdown-- == 0)
    3829     {
    3830         STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkAging, a);
    3831         PGMR3PhysChunkAgeing(pVM);
    3832         STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkAging, a);
    3833     }
    3834 
    3835     /*
    38363788     * Enumerate the age tree starting with the left most node.
    38373789     */
    38383790    STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkFindCandidate, a);
    38393791    PGMR3PHYSCHUNKUNMAPCB Args;
    3840     Args.pVM      = pVM;
    3841     Args.pChunk   = NULL;
    3842     Args.iLastAge = 0;
     3792    Args.pVM    = pVM;
     3793    Args.pChunk = NULL;
    38433794    RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkUnmapCandidateCallback, &Args);
    38443795    Assert(Args.pChunk);
     
    39833934
    39843935    /*
     3936     * Move the chunk time forward.
     3937     */
     3938    pVM->pgm.s.ChunkR3Map.iNow++;
     3939    if (pVM->pgm.s.ChunkR3Map.iNow == 0)
     3940    {
     3941        pVM->pgm.s.ChunkR3Map.iNow = 4;
     3942        RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingRolloverCallback, NULL);
     3943    }
     3944
     3945    /*
    39853946     * Allocate a new tracking structure first.
    39863947     */
     
    39913952#endif
    39923953    AssertReturn(pChunk, VERR_NO_MEMORY);
    3993     pChunk->Core.Key = idChunk;
     3954    pChunk->Core.Key  = idChunk;
     3955    pChunk->iLastUsed = pVM->pgm.s.ChunkR3Map.iNow;
    39943956
    39953957    /*
     
    39983960    GMMMAPUNMAPCHUNKREQ Req;
    39993961    Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    4000     Req.Hdr.cbReq = sizeof(Req);
    4001     Req.pvR3 = NULL;
    4002     Req.idChunkMap = idChunk;
     3962    Req.Hdr.cbReq    = sizeof(Req);
     3963    Req.pvR3         = NULL;
     3964    Req.idChunkMap   = idChunk;
    40033965    Req.idChunkUnmap = NIL_GMM_CHUNKID;
    40043966
     
    40093971    if (RT_SUCCESS(rc))
    40103972    {
     3973        pChunk->pv = Req.pvR3;
     3974
    40113975        /*
    40123976         * If we're running out of virtual address space, then we should
     
    40534017         * the chunk we're going to return isn't unmapped by accident.
    40544018         */
    4055         /* insert the new one. */
    40564019        AssertPtr(Req.pvR3);
    4057         pChunk->pv = Req.pvR3;
    40584020        bool fRc = RTAvlU32Insert(&pVM->pgm.s.ChunkR3Map.pTree, &pChunk->Core);
    40594021        AssertRelease(fRc);
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