VirtualBox

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


Ignore:
Timestamp:
Jul 11, 2018 4:19:48 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
123634
Message:

PGM/DBG: Optimize page scanning to speed up 'detect'.

File:
1 edited

Legend:

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

    r69111 r73073  
    867867    pgmR3DbgSelectMemScanFunction(&pfnMemScan, (uint32_t)GCPtrAlign, cbNeedle);
    868868
    869     uint32_t        cYieldCountDown = 4096;
     869    VMSTATE         enmVMState              = pVM->enmVMState;
     870    uint32_t const  cYieldCountDownReload   = VMSTATE_IS_RUNNING(enmVMState) ? 4096 : 65536;
     871    uint32_t        cYieldCountDown         = cYieldCountDownReload;
     872    RTGCPHYS        GCPhysPrev              = NIL_RTGCPHYS;
     873    bool            fFullWalk               = true;
     874    PGMPTWALKGST    Walk;
     875    RT_ZERO(Walk);
     876
    870877    pgmLock(pVM);
    871878    for (;; offPage = 0)
    872879    {
    873         PGMPTWALKGST Walk;
    874         int rc = pgmGstPtWalk(pVCpu, GCPtr, &Walk);
     880        int rc;
     881        if (fFullWalk)
     882            rc = pgmGstPtWalk(pVCpu, GCPtr, &Walk);
     883        else
     884            rc = pgmGstPtWalkNext(pVCpu, GCPtr, &Walk);
    875885        if (RT_SUCCESS(rc) && Walk.u.Core.fSucceeded)
    876886        {
    877             PPGMPAGE pPage = pgmPhysGetPage(pVM, Walk.u.Core.GCPhys);
    878             if (   pPage
    879                 && (   !PGM_PAGE_IS_ZERO(pPage)
    880                     || fAllZero)
    881                 && !PGM_PAGE_IS_MMIO_OR_ALIAS(pPage)
    882                 && !PGM_PAGE_IS_BALLOONED(pPage))
     887            fFullWalk = false;
     888
     889            /* Skip if same page as previous one (W10 optimization). */
     890            if (   Walk.u.Core.GCPhys != GCPhysPrev
     891                || cbPrev != 0)
    883892            {
    884                 void const *pvPage;
    885                 PGMPAGEMAPLOCK Lock;
    886                 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, Walk.u.Core.GCPhys, &pvPage, &Lock);
    887                 if (RT_SUCCESS(rc))
     893                PPGMPAGE pPage = pgmPhysGetPage(pVM, Walk.u.Core.GCPhys);
     894                if (   pPage
     895                    && (   !PGM_PAGE_IS_ZERO(pPage)
     896                        || fAllZero)
     897                    && !PGM_PAGE_IS_MMIO_OR_ALIAS(pPage)
     898                    && !PGM_PAGE_IS_BALLOONED(pPage))
    888899                {
    889                     int32_t offHit = offPage;
    890                     bool    fRc;
    891                     if (GCPtrAlign < PAGE_SIZE)
     900                    GCPhysPrev = Walk.u.Core.GCPhys;
     901                    void const *pvPage;
     902                    PGMPAGEMAPLOCK Lock;
     903                    rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, Walk.u.Core.GCPhys, &pvPage, &Lock);
     904                    if (RT_SUCCESS(rc))
    892905                    {
    893                         uint32_t cbSearch = cPages > 0
    894                                           ? PAGE_SIZE                          - (uint32_t)offPage
    895                                           : (GCPtrLast & PAGE_OFFSET_MASK) + 1 - (uint32_t)offPage;
    896                         fRc = pgmR3DbgScanPage((uint8_t const *)pvPage, &offHit, cbSearch, (uint32_t)GCPtrAlign,
    897                                                pabNeedle, cbNeedle, pfnMemScan, &abPrev[0], &cbPrev);
     906                        int32_t offHit = offPage;
     907                        bool    fRc;
     908                        if (GCPtrAlign < PAGE_SIZE)
     909                        {
     910                            uint32_t cbSearch = cPages > 0
     911                                              ? PAGE_SIZE                          - (uint32_t)offPage
     912                                              : (GCPtrLast & PAGE_OFFSET_MASK) + 1 - (uint32_t)offPage;
     913                            fRc = pgmR3DbgScanPage((uint8_t const *)pvPage, &offHit, cbSearch, (uint32_t)GCPtrAlign,
     914                                                   pabNeedle, cbNeedle, pfnMemScan, &abPrev[0], &cbPrev);
     915                        }
     916                        else
     917                            fRc = memcmp(pvPage, pabNeedle, cbNeedle) == 0
     918                               && (GCPtrLast - GCPtr) >= cbNeedle;
     919                        PGMPhysReleasePageMappingLock(pVM, &Lock);
     920                        if (fRc)
     921                        {
     922                            *pGCPtrHit = GCPtr + offHit;
     923                            pgmUnlock(pVM);
     924                            return VINF_SUCCESS;
     925                        }
    898926                    }
    899927                    else
    900                         fRc = memcmp(pvPage, pabNeedle, cbNeedle) == 0
    901                            && (GCPtrLast - GCPtr) >= cbNeedle;
    902                     PGMPhysReleasePageMappingLock(pVM, &Lock);
    903                     if (fRc)
    904                     {
    905                         *pGCPtrHit = GCPtr + offHit;
    906                         pgmUnlock(pVM);
    907                         return VINF_SUCCESS;
    908                     }
     928                        cbPrev = 0; /* ignore error. */
    909929                }
    910930                else
    911                     cbPrev = 0; /* ignore error. */
     931                    cbPrev = 0;
    912932            }
    913933            else
     
    966986            if (cPages <= cPagesCanSkip)
    967987                break;
     988            fFullWalk = true;
    968989            if (cPagesCanSkip >= cIncPages)
    969990            {
     
    9831004        if (!--cYieldCountDown)
    9841005        {
    985             PDMR3CritSectYield(&pVM->pgm.s.CritSectX);
    986             cYieldCountDown = 4096;
     1006            fFullWalk = PDMR3CritSectYield(&pVM->pgm.s.CritSectX);
     1007            cYieldCountDown = cYieldCountDownReload;
    9871008        }
    9881009    }
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