VirtualBox

Changeset 38956 in vbox


Ignore:
Timestamp:
Oct 6, 2011 12:43:01 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
74327
Message:

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

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r38955 r38956  
    958958         */
    959959        pMap = (PPGMCHUNKR3MAP)RTAvlU32Get(&pVM->pgm.s.ChunkR3Map.pTree, idChunk);
    960         if (!pMap)
     960        if (pMap)
     961            pMap->iLastUsed = pVM->pgm.s.ChunkR3Map.iNow;
     962        else
    961963        {
    962964# ifdef IN_RING0
     
    977979        pTlbe->idChunk = idChunk;
    978980        pTlbe->pChunk = pMap;
    979         pMap->iAge = 0;
    980981    }
    981982
     
    10741075        pMap = (PPGMCHUNKR3MAP)RTAvlU32Get(&pVM->pgm.s.ChunkR3Map.pTree, idChunk);
    10751076        if (pMap)
     1077        {
    10761078            AssertPtr(pMap->pv);
     1079            pMap->iLastUsed = pVM->pgm.s.ChunkR3Map.iNow;
     1080        }
    10771081        else
    10781082        {
     
    10951099        pTlbe->idChunk = idChunk;
    10961100        pTlbe->pChunk = pMap;
    1097         pMap->iAge = 0;
    10981101    }
    10991102
     
    18651868        Assert(pMap->cRefs >= 1);
    18661869        pMap->cRefs--;
    1867         pMap->iAge = 0;
    18681870    }
    18691871    pgmUnlock(pVM);
  • 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);
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r38953 r38956  
    16201620    /** The key is the chunk id. */
    16211621    AVLU32NODECORE                      Core;
    1622     /** The current age thingy. */
    1623     uint32_t                            iAge;
     1622    /** The time (ChunkR3Map.iNow) this chunk was last used.  Used for unmap
     1623     *  selection. */
     1624    uint32_t                            iLastUsed;
    16241625    /** The current reference count. */
    16251626    uint32_t volatile                   cRefs;
     
    31743175#endif
    31753176#if HC_ARCH_BITS == 32
    3176         uint32_t                    u32Alignment;
     3177        uint32_t                    u32Alignment0;
    31773178#endif
    31783179        /** The chunk mapping TLB. */
     
    31833184         * @cfgm    PGM/MaxRing3Chunks */
    31843185        uint32_t                    cMax;
    3185         /** The current time. */
     3186        /** The current time.  This is incremented whenever a chunk is inserted. */
    31863187        uint32_t                    iNow;
    3187         /** Number of pgmR3PhysChunkFindUnmapCandidate calls left to the next ageing. */
    3188         uint32_t                    AgeingCountdown;
     3188        /** Alignment padding. */
     3189        uint32_t                    u32Alignment1;
    31893190    } ChunkR3Map;
    31903191
  • trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp

    r38953 r38956  
    610610    GEN_CHECK_OFF(PGM, ChunkR3Map.cMax);
    611611    GEN_CHECK_OFF(PGM, ChunkR3Map.iNow);
    612     GEN_CHECK_OFF(PGM, ChunkR3Map.AgeingCountdown);
    613612    GEN_CHECK_OFF(PGM, PhysTlbHC);
    614613    GEN_CHECK_OFF(PGM, PhysTlbHC.aEntries[0]);
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