VirtualBox

Changeset 36902 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Apr 30, 2011 11:57:28 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71482
Message:

PGM: Implemented RAM range search trees (disabled).

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

Legend:

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

    r36894 r36902  
    161161
    162162/**
     163 * Tests if a value of type RTGCPHYS is negative if the type had been signed
     164 * instead of unsigned.
     165 *
     166 * @returns @c true if negative, @c false if positive or zero.
     167 * @param   a_GCPhys        The value to test.
     168 * @todo    Move me to iprt/types.h.
     169 */
     170#define RTGCPHYS_IS_NEGATIVE(a_GCPhys)  ((a_GCPhys) & ((RTGCPHYS)1 << (sizeof(RTGCPHYS)*8 - 1)))
     171
     172
     173/**
    163174 * Slow worker for pgmPhysGetRange.
    164175 *
     
    168179{
    169180    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
     181
     182#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
     183    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
     184    while (pRam)
     185    {
     186        RTGCPHYS off = GCPhys - pRam->GCPhys;
     187        if (off < pRam->cb)
     188        {
     189            pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
     190            return pRam;
     191        }
     192        if (RTGCPHYS_IS_NEGATIVE(off))
     193            pRam = pRam->CTX_SUFF(pLeft);
     194        else
     195            pRam = pRam->CTX_SUFF(pRight);
     196    }
     197    return NULL;
     198#else
    170199    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
    171200    while (GCPhys > pRam->GCPhysLast)
     
    180209    pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
    181210    return pRam;
     211#endif
    182212}
    183213
     
    191221{
    192222    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
     223
     224#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
     225    PPGMRAMRANGE pLastLeft = NULL;
     226    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
     227    while (pRam)
     228    {
     229        RTGCPHYS off = GCPhys - pRam->GCPhys;
     230        if (off < pRam->cb)
     231        {
     232            pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
     233            return pRam;
     234        }
     235        if (RTGCPHYS_IS_NEGATIVE(off))
     236        {
     237            pLastLeft = pRam;
     238            pRam = pRam->CTX_SUFF(pLeft);
     239        }
     240        else
     241            pRam = pRam->CTX_SUFF(pRight);
     242    }
     243    return pLastLeft;
     244#else
    193245    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
    194246    while (GCPhys > pRam->GCPhysLast)
     
    200252    pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
    201253    return pRam;
     254#endif
    202255}
    203256
     
    211264{
    212265    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
     266
     267#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
     268    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
     269    while (pRam)
     270    {
     271        RTGCPHYS off = GCPhys - pRam->GCPhys;
     272        if (off < pRam->cb)
     273        {
     274            pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
     275            return &pRam->aPages[off >> PAGE_SHIFT];
     276        }
     277
     278        if (RTGCPHYS_IS_NEGATIVE(off))
     279            pRam = pRam->CTX_SUFF(pLeft);
     280        else
     281            pRam = pRam->CTX_SUFF(pRight);
     282    }
     283#else
    213284    for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
    214285         pRam;
     
    222293        }
    223294    }
     295#endif
    224296    return NULL;
    225297}
     
    234306{
    235307    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
     308
     309#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
     310    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
     311    while (pRam)
     312    {
     313        RTGCPHYS off = GCPhys - pRam->GCPhys;
     314        if (off < pRam->cb)
     315        {
     316            pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
     317            *ppPage = &pRam->aPages[off >> PAGE_SHIFT];
     318            return VINF_SUCCESS;
     319        }
     320
     321        if (RTGCPHYS_IS_NEGATIVE(off))
     322            pRam = pRam->CTX_SUFF(pLeft);
     323        else
     324            pRam = pRam->CTX_SUFF(pRight);
     325    }
     326#else
    236327    for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
    237328         pRam;
     
    246337        }
    247338    }
     339#endif
     340
    248341    *ppPage = NULL;
    249342    return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
     
    259352{
    260353    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbMisses));
    261     for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
    262          pRam;
    263          pRam = pRam->CTX_SUFF(pNext))
     354
     355#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
     356    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangeTree);
     357    while (pRam)
    264358    {
    265359        RTGCPHYS off = GCPhys - pRam->GCPhys;
     
    271365            return VINF_SUCCESS;
    272366        }
    273     }
     367
     368        if (RTGCPHYS_IS_NEGATIVE(off))
     369            pRam = pRam->CTX_SUFF(pLeft);
     370        else
     371            pRam = pRam->CTX_SUFF(pRight);
     372    }
     373#else
     374    for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
     375         pRam;
     376         pRam = pRam->CTX_SUFF(pNext))
     377    {
     378        RTGCPHYS off = GCPhys - pRam->GCPhys;
     379        if (off < pRam->cb)
     380        {
     381            pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)] = pRam;
     382            *ppRam  = pRam;
     383            *ppPage = &pRam->aPages[off >> PAGE_SHIFT];
     384            return VINF_SUCCESS;
     385        }
     386    }
     387#endif
    274388
    275389    *ppRam  = NULL;
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r36897 r36902  
    578578}
    579579
     580#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
     581
     582#define MAKE_LEAF(a_pNode) \
     583    do { \
     584        (a_pNode)->pLeftR3  = NIL_RTR3PTR; \
     585        (a_pNode)->pRightR3 = NIL_RTR3PTR; \
     586        (a_pNode)->pLeftR0  = NIL_RTR0PTR; \
     587        (a_pNode)->pRightR0 = NIL_RTR0PTR; \
     588        (a_pNode)->pLeftRC  = NIL_RTRCPTR; \
     589        (a_pNode)->pRightRC = NIL_RTRCPTR; \
     590    } while (0)
     591
     592#define INSERT_LEFT(a_pParent, a_pNode) \
     593    do { \
     594        (a_pParent)->pLeftR3 = (a_pNode); \
     595        (a_pParent)->pLeftR0 = (a_pNode)->pSelfR0; \
     596        (a_pParent)->pLeftRC = (a_pNode)->pSelfRC; \
     597    } while (0)
     598#define INSERT_RIGHT(a_pParent, a_pNode) \
     599    do { \
     600        (a_pParent)->pRightR3 = (a_pNode); \
     601        (a_pParent)->pRightR0 = (a_pNode)->pSelfR0; \
     602        (a_pParent)->pRightRC = (a_pNode)->pSelfRC; \
     603    } while (0)
     604
     605
     606/**
     607 * Recursive tree builder.
     608 *
     609 * @param   ppRam           Pointer to the iterator variable.
     610 * @param   iHeight         The hight about normal leaf nodes.  Inserts a leaf
     611 *                          node if 0.
     612 */
     613static PPGMRAMRANGE pgmR3PhysRebuildRamRangeSearchTreesRecursively(PPGMRAMRANGE *ppRam, int iDepth)
     614{
     615    PPGMRAMRANGE pRam;
     616    if (iDepth <= 0)
     617    {
     618        /*
     619         * Leaf node.
     620         */
     621        pRam = *ppRam;
     622        if (pRam)
     623        {
     624            *ppRam = pRam->pNextR3;
     625            MAKE_LEAF(pRam);
     626        }
     627    }
     628    else
     629    {
     630
     631        /*
     632         * Intermediate node.
     633         */
     634        PPGMRAMRANGE pLeft = pgmR3PhysRebuildRamRangeSearchTreesRecursively(ppRam, iDepth - 1);
     635
     636        pRam = *ppRam;
     637        if (!pRam)
     638            return pLeft;
     639        *ppRam = pRam->pNextR3;
     640        MAKE_LEAF(pRam);
     641        INSERT_LEFT(pRam, pLeft);
     642
     643        PPGMRAMRANGE pRight = pgmR3PhysRebuildRamRangeSearchTreesRecursively(ppRam, iDepth - 1);
     644        if (pRight)
     645            INSERT_RIGHT(pRam, pRight);
     646    }
     647    return pRam;
     648}
     649
    580650
    581651/**
     
    586656static void pgmR3PhysRebuildRamRangeSearchTrees(PVM pVM)
    587657{
    588 #ifdef PGM_USE_RAMRANGE_SEARCH_TREES
    589     /*
    590      * Create the three balanced trees by sequentially working the linked list.
    591      */
    592 
    593     /* Count them and calculate the max depth. */
     658
     659    /*
     660     * Create the reasonably balanced tree in a sequential fashion.
     661     * For simplicity (laziness) we use standard recursion here.
     662     */
     663    int             iDepth = 0;
     664    PPGMRAMRANGE    pRam   = pVM->pgm.s.pRamRangesXR3;
     665    PPGMRAMRANGE    pRoot  = pgmR3PhysRebuildRamRangeSearchTreesRecursively(&pRam, 0);
     666    while (pRam)
     667    {
     668        PPGMRAMRANGE pLeft = pRoot;
     669
     670        pRoot = pRam;
     671        pRam = pRam->pNextR3;
     672        MAKE_LEAF(pRoot);
     673        INSERT_LEFT(pRoot, pLeft);
     674
     675        PPGMRAMRANGE pRight = pgmR3PhysRebuildRamRangeSearchTreesRecursively(&pRam, iDepth);
     676        if (pRight)
     677            INSERT_RIGHT(pRoot, pRight);
     678        /** @todo else: rotate the tree. */
     679
     680        iDepth++;
     681    }
     682
     683    pVM->pgm.s.pRamRangeTreeR3 = pRoot;
     684    pVM->pgm.s.pRamRangeTreeR0 = pRoot ? pRoot->pSelfR0 : NIL_RTR0PTR;
     685    pVM->pgm.s.pRamRangeTreeRC = pRoot ? pRoot->pSelfRC : NIL_RTRCPTR;
     686
     687#ifdef VBOX_STRICT
     688    /*
     689     * Verify that the above code works.
     690     */
    594691    unsigned cRanges = 0;
    595     for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
     692    for (pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
    596693        cRanges++;
    597 
    598     /// contine later
    599 
    600 #endif
    601 }
    602 
     694    Assert(cRanges > 0);
     695
     696    unsigned cMaxDepth = ASMBitLastSetU32(cRanges);
     697    if ((1U << cMaxDepth) < cRanges)
     698        cMaxDepth++;
     699
     700    for (pRam = pVM->pgm.s.pRamRangesXR3; pRam; pRam = pRam->pNextR3)
     701    {
     702        unsigned     cDepth = 0;
     703        PPGMRAMRANGE pRam2 = pVM->pgm.s.pRamRangeTreeR3;
     704        for (;;)
     705        {
     706            if (pRam == pRam2)
     707                break;
     708            Assert(pRam2);
     709            if (pRam->GCPhys < pRam2->GCPhys)
     710                pRam2 = pRam2->pLeftR3;
     711            else
     712                pRam2 = pRam2->pRightR3;
     713        }
     714        AssertMsg(cDepth <= cMaxDepth, ("cDepth=%d cMaxDepth=%d\n", cDepth, cMaxDepth));
     715    }
     716#endif /* VBOX_STRICT */
     717}
     718
     719#undef MAKE_LEAF
     720#undef INSERT_LEFT
     721#undef INSERT_RIGHT
     722#endif /* PGM_USE_RAMRANGE_SEARCH_TREES */
    603723
    604724/**
     
    650770    ASMAtomicIncU32(&pVM->pgm.s.idRamRangesGen);
    651771
     772#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
    652773    pgmR3PhysRebuildRamRangeSearchTrees(pVM);
    653 
     774#endif
    654775}
    655776
     
    689810    ASMAtomicIncU32(&pVM->pgm.s.idRamRangesGen);
    690811
     812#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
    691813    pgmR3PhysRebuildRamRangeSearchTrees(pVM);
     814#endif
    692815    pgmUnlock(pVM);
    693816}
     
    725848    ASMAtomicIncU32(&pVM->pgm.s.idRamRangesGen);
    726849
     850#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
    727851    pgmR3PhysRebuildRamRangeSearchTrees(pVM);
     852#endif
    728853    pgmUnlock(pVM);
    729854}
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r36897 r36902  
    12661266
    12671267
    1268 /**
    1269  * Ram range for GC Phys to HC Phys conversion.
     1268//#define PGM_USE_RAMRANGE_SEARCH_TREES
     1269
     1270/**
     1271 * RAM range for GC Phys to HC Phys conversion.
    12701272 *
    12711273 * Can be used for HC Virt to GC Phys and HC Virt to HC Phys
     
    13171319
    13181320    /** Padding to make aPage aligned on sizeof(PGMPAGE). */
     1321#ifdef PGM_USE_RAMRANGE_SEARCH_TREES
     1322    uint32_t                            au32Alignment2[HC_ARCH_BITS == 32 ? 3 : 1];
     1323#else
    13191324    uint32_t                            au32Alignment2[HC_ARCH_BITS == 32 ? 1 : 3];
     1325#endif
    13201326    /** Array of physical guest page tracking structures. */
    13211327    PGMPAGE                             aPages[1];
    13221328} PGMRAMRANGE;
    1323 /** Pointer to Ram range for GC Phys to HC Phys conversion. */
     1329/** Pointer to RAM range for GC Phys to HC Phys conversion. */
    13241330typedef PGMRAMRANGE *PPGMRAMRANGE;
    13251331
     
    29772983
    29782984
    2979     /** Ram range TLB for R3. */
     2985    /** RAM range TLB for R3. */
    29802986    R3PTRTYPE(PPGMRAMRANGE)         apRamRangesTlbR3[PGM_RAMRANGE_TLB_ENTRIES];
    29812987    /** Pointer to the list of RAM ranges (Phys GC -> Phys HC conversion) - for R3.
    29822988     * This is sorted by physical address and contains no overlapping ranges. */
    29832989    R3PTRTYPE(PPGMRAMRANGE)         pRamRangesXR3;
     2990    /** Root of the RAM range search tree for ring-3. */
     2991    R3PTRTYPE(PPGMRAMRANGE)         pRamRangeTreeR3;
    29842992    /** PGM offset based trees - R3 Ptr. */
    29852993    R3PTRTYPE(PPGMTREES)            pTreesR3;
     
    30003008     * The index into this table is made up from */
    30013009    R3PTRTYPE(PPGMMODEDATA)         paModeData;
    3002     /*RTR3PTR                         R3PtrAlignment0;*/
    3003 
    3004     /** Ram range TLB for R0. */
     3010    RTR3PTR                         R3PtrAlignment0;
     3011
     3012    /** RAM range TLB for R0. */
    30053013    R0PTRTYPE(PPGMRAMRANGE)         apRamRangesTlbR0[PGM_RAMRANGE_TLB_ENTRIES];
    30063014    /** R0 pointer corresponding to PGM::pRamRangesXR3. */
    30073015    R0PTRTYPE(PPGMRAMRANGE)         pRamRangesXR0;
     3016    /** Root of the RAM range search tree for ring-0. */
     3017    R0PTRTYPE(PPGMRAMRANGE)         pRamRangeTreeR0;
    30083018    /** PGM offset based trees - R0 Ptr. */
    30093019    R0PTRTYPE(PPGMTREES)            pTreesR0;
     
    30173027    /** R0 pointer corresponding to PGM::pRomRangesR3. */
    30183028    R0PTRTYPE(PPGMROMRANGE)         pRomRangesR0;
    3019     /*RTR0PTR                         R0PtrAlignment0;*/
    3020 
    3021 
    3022     /** Ram range TLB for RC. */
     3029    RTR0PTR                         R0PtrAlignment0;
     3030
     3031
     3032    /** RAM range TLB for RC. */
    30233033    RCPTRTYPE(PPGMRAMRANGE)         apRamRangesTlbRC[PGM_RAMRANGE_TLB_ENTRIES];
    30243034    /** RC pointer corresponding to PGM::pRamRangesXR3. */
    30253035    RCPTRTYPE(PPGMRAMRANGE)         pRamRangesXRC;
     3036    /** Root of the RAM range search tree for raw-mode context. */
     3037    RCPTRTYPE(PPGMRAMRANGE)         pRamRangeTreeRC;
    30263038    /** PGM offset based trees - RC Ptr. */
    30273039    RCPTRTYPE(PPGMTREES)            pTreesRC;
     
    30353047    /** RC pointer corresponding to PGM::pRomRangesR3. */
    30363048    RCPTRTYPE(PPGMROMRANGE)         pRomRangesRC;
    3037     /*RTRCPTR                         RCPtrAlignment0;*/
     3049    RTRCPTR                         RCPtrAlignment0;
    30383050    /** Pointer to the page table entries for the dynamic page mapping area - GCPtr. */
    30393051    RCPTRTYPE(PX86PTE)              paDynPageMap32BitPTEsGC;
Note: See TracChangeset for help on using the changeset viewer.

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