VirtualBox

Changeset 77287 in vbox


Ignore:
Timestamp:
Feb 12, 2019 4:47:16 PM (6 years ago)
Author:
vboxsync
Message:

DevVGA-SVGA: Use the VGA refresh timer to babysit the FIFO thread and make sure it's woken up when needed. Disabled the access handler based babysitter with #ifdef VMSVGA_USE_FIFO_ACCESS_HANDLER. bugref:9376

Location:
trunk/src/VBox/Devices/Graphics
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp

    r77282 r77287  
    246246    VMSVGASCREENOBJECT aScreens[64];
    247247
    248 # ifdef VBOX_STRICT
    249     /** The time the access handler for the FIFO last triggered.  This should
    250      *  never happen less than a certain interval from the last access, and we
    251      *  assert this. */
    252     uint64_t                TimeLastFIFOIntercept;
    253 # endif
    254 
    255248    /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */
    256249    STAMPROFILE             StatBusyDelayEmts;
     
    324317    STAMCOUNTER             StatFifoTodoWoken;
    325318    STAMPROFILE             StatFifoStalls;
    326     STAMPROFILE             StatFifoSleepOnHandler;
     319    STAMPROFILE             StatFifoExtendedSleep;
     320# ifdef VMSVGA_USE_FIFO_ACCESS_HANDLER
    327321    STAMCOUNTER             StatFifoAccessHandler;
     322# endif
    328323    STAMCOUNTER             StatFifoCursorFetchAgain;
    329324    STAMCOUNTER             StatFifoCursorNoChange;
    330325    STAMCOUNTER             StatFifoCursorPosition;
    331326    STAMCOUNTER             StatFifoCursorVisiblity;
    332 
     327    STAMCOUNTER             StatFifoWatchdogWakeUps;
    333328} VMSVGAR3STATE, *PVMSVGAR3STATE;
    334329#endif /* IN_RING3 */
     
    412407#else
    413408    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, hBusyDelayedEmts),
    414 #endif
    415 #ifdef VBOX_STRICT
    416     SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, TimeLastFIFOIntercept),
    417409#endif
    418410    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatBusyDelayEmts),
     
    485477    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoTodoWoken),
    486478    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoStalls),
    487     SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoSleepOnHandler),
     479    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoExtendedSleep),
     480# if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS)
    488481    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoAccessHandler),
     482# endif
    489483    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoCursorFetchAgain),
    490484    SSMFIELD_ENTRY_IGNORE(      VMSVGAR3STATE, StatFifoCursorNoChange),
     
    528522    SSMFIELD_ENTRY_IGNORE(          VMSVGAState, FIFOExtCmdSem),
    529523    SSMFIELD_ENTRY_IGN_HCPTR(       VMSVGAState, pFIFOIOThread),
     524    SSMFIELD_ENTRY_IGNORE(          VMSVGAState, uLastCursorUpdateCount),
     525    SSMFIELD_ENTRY_IGNORE(          VMSVGAState, fFIFOThreadSleeping),
    530526    SSMFIELD_ENTRY_VER(             VMSVGAState, fGFBRegisters, VGA_SAVEDSTATE_VERSION_VMSVGA_SCREENS),
    531527    SSMFIELD_ENTRY(                 VMSVGAState, uWidth),
     
    23622358# endif /* DEBUG_FIFO_ACCESS */
    23632359
     2360# if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS)
    23642361/**
    23652362 * HC access handler for the FIFO.
     
    23852382    AssertPtr(pThis);
    23862383
     2384# ifdef VMSVGA_USE_FIFO_ACCESS_HANDLER
    23872385    /*
    23882386     * Wake up the FIFO thread as it might have work to do now.
     
    23902388    int rc = SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
    23912389    AssertLogRelRC(rc);
     2390# endif
    23922391
    23932392# ifdef DEBUG_FIFO_ACCESS
     
    23982397    Assert(GCPhys >= pThis->svga.GCPhysFIFO);
    23992398    rc = vmsvgaDebugFIFOAccess(pVM, pThis, GCPhys, enmAccessType == PGMACCESSTYPE_WRITE);
    2400 # else
     2399# elif defined(VMSVGA_USE_FIFO_ACCESS_HANDLER)
    24012400    /*
    24022401     * Temporarily disable the access handler now that we've kicked the FIFO thread.
    24032402     */
    2404 
    24052403    STAM_REL_COUNTER_INC(&pThis->svga.pSvgaR3State->StatFifoAccessHandler);
    24062404    rc = PGMHandlerPhysicalPageTempOff(pVM, pThis->svga.GCPhysFIFO, pThis->svga.GCPhysFIFO);
     
    24112409    return rc;
    24122410}
     2411# endif /* VMSVGA_USE_FIFO_ACCESS_HANDLER || DEBUG_FIFO_ACCESS */
    24132412
    24142413#endif /* IN_RING3 */
     
    33163315
    33173316
     3317/**
     3318 * Called by the VGA refresh timer to wake up the FIFO thread when needed.
     3319 *
     3320 * @param   pThis   The VGA state.
     3321 */
     3322void vmsvgaFIFOWatchdogTimer(PVGASTATE pThis)
     3323{
     3324    /* Caller already checked pThis->svga.fFIFOThreadSleeping, so we only have
     3325       to recheck it before doing the signalling. */
     3326    uint32_t RT_UNTRUSTED_VOLATILE_GUEST * const pFIFO = pThis->svga.pFIFOR3;
     3327    AssertReturnVoid(pThis->svga.pFIFOR3);
     3328    if (   vmsvgaFIFOHasWork(pFIFO, pThis->svga.uLastCursorUpdateCount)
     3329        && pThis->svga.fFIFOThreadSleeping)
     3330    {
     3331        int rc = SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
     3332        AssertRC(rc);
     3333        STAM_REL_COUNTER_INC(&pThis->svga.pSvgaR3State->StatFifoWatchdogWakeUps);
     3334    }
     3335}
     3336
     3337
    33183338/* The async FIFO handling thread. */
    33193339static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
     
    33603380     *
    33613381     * We wait for an a short interval if the guest has recently given us work
    3362      * to do, but the interval increases the longer we're kept idle.  After
    3363      * about a second we'll switch to long sleeps and using an access handler
    3364      * monitoring writes to the first FIFO page to wake us up.  Should the FIFO
    3365      * not be mapped, we will continue increasing the wait interval till it
    3366      * reaches the 250ms max after about 16 seconds.
     3382     * to do, but the interval increases the longer we're kept idle.  Once we've
     3383     * reached the refresh timer interval, we'll switch to extended waits,
     3384     * depending on it or the guest to kick us into action when needed.
     3385     *
     3386     * Should the refresh time go fishing, we'll just continue increasing the
     3387     * sleep length till we reaches the 250 ms max after about 16 seconds.
    33673388     */
    33683389    RTMSINTERVAL const  cMsMinSleep           = 16;
    33693390    RTMSINTERVAL const  cMsIncSleep           = 2;
    33703391    RTMSINTERVAL const  cMsMaxSleep           = 250;
    3371     RTMSINTERVAL const  cMsAccessHandlerThres = 66;
    3372     RTMSINTERVAL const  cMsAccessHandlerSleep = 15 * RT_MS_1SEC; /* Regular paranoia dictates that this cannot be indefinite. */
     3392    RTMSINTERVAL const  cMsExtendedSleep      = 15 * RT_MS_1SEC; /* Regular paranoia dictates that this cannot be indefinite. */
    33733393    RTMSINTERVAL        cMsSleep              = cMsMaxSleep;
    33743394
     
    33783398     */
    33793399    uint32_t RT_UNTRUSTED_VOLATILE_GUEST * const pFIFO = pThis->svga.pFIFOR3;
    3380     uint32_t uLastCursorCount   = ~pFIFO[SVGA_FIFO_CURSOR_COUNT];
     3400    uint32_t uLastCursorCount   = pThis->svga.uLastCursorUpdateCount = ~pFIFO[SVGA_FIFO_CURSOR_COUNT];
    33813401    uint32_t xLastCursor        = ~pFIFO[SVGA_FIFO_CURSOR_X];
    33823402    uint32_t yLastCursor        = ~pFIFO[SVGA_FIFO_CURSOR_Y];
     
    34053425            || !vmsvgaFIFOHasWork(pFIFO, uLastCursorCount))
    34063426        {
    3407             if (    cMsSleep < cMsAccessHandlerThres
    3408                 || !pThis->svga.GCPhysFIFO /* yeah, really zero rather than NIL when unmapped. */)
     3427            ASMAtomicWriteBool(&pThis->svga.fFIFOThreadSleeping, true);
     3428            Assert(pThis->cMilliesRefreshInterval > 0);
     3429            if (cMsSleep < pThis->cMilliesRefreshInterval)
    34093430                rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, cMsSleep);
    34103431            else
    34113432            {
    3412 # if 0 /* Still doesn't work. The trouble is on line 3424 and 3425. */
    3413 # ifdef VBOX_STRICT
    3414                 /* Invariant: The access handler should never be reset twice within
    3415                    a certain time span; calling it 500ms here for simplicity. */
    3416                 uint64_t TimeNow = RTTimeMilliTS();
    3417                 Assert(TimeNow - pSVGAState->TimeLastFIFOIntercept > 500);
    3418                 pSVGAState->TimeLastFIFOIntercept = TimeNow;
    3419 # endif
    3420 # endif
     3433# ifdef VMSVGA_USE_FIFO_ACCESS_HANDLER
    34213434                int rc2 = PGMHandlerPhysicalReset(PDMDevHlpGetVM(pDevIns), pThis->svga.GCPhysFIFO);
    34223435                AssertRC(rc2); /* No break. Racing EMTs unmapping and remapping the region. */
    3423 
    3424                 if (   fBadOrDisabledFifo
    3425                     || !vmsvgaFIFOHasWork(pFIFO, uLastCursorCount))
     3436# endif
     3437                if (   !fBadOrDisabledFifo
     3438                    && vmsvgaFIFOHasWork(pFIFO, uLastCursorCount))
     3439                    rc = VINF_SUCCESS;
     3440                else
    34263441                {
    3427                     STAM_REL_PROFILE_START(&pSVGAState->StatFifoSleepOnHandler, Acc);
    3428                     rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, cMsAccessHandlerSleep);
    3429                     STAM_REL_PROFILE_STOP(&pSVGAState->StatFifoSleepOnHandler, Acc);
     3442                    STAM_REL_PROFILE_START(&pSVGAState->StatFifoExtendedSleep, Acc);
     3443                    rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, cMsExtendedSleep);
     3444                    STAM_REL_PROFILE_STOP(&pSVGAState->StatFifoExtendedSleep, Acc);
    34303445                }
    3431                 else
    3432                     rc = VINF_SUCCESS;
    34333446            }
     3447            ASMAtomicWriteBool(&pThis->svga.fFIFOThreadSleeping, false);
    34343448            AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED);
    34353449            if (pThread->enmState != PDMTHREADSTATE_RUNNING)
     
    35243538            { /* halfways likely */ }
    35253539            else
     3540            {
    35263541                uLastCursorCount = vmsvgaFIFOUpdateCursor(pThis, pSVGAState, pFIFO, offFifoMin, uCursorUpdateCount,
    35273542                                                          &xLastCursor, &yLastCursor, &fLastCursorVisible);
     3543                ASMAtomicWriteU32(&pThis->svga.uLastCursorUpdateCount, uLastCursorCount);
     3544            }
    35283545        }
    35293546
     
    52445261            AssertRC(rc);
    52455262
     5263# if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS)
    52465264            if (RT_SUCCESS(rc))
    52475265            {
    52485266                rc = PGMHandlerPhysicalRegister(PDMDevHlpGetVM(pDevIns), GCPhysAddress,
    5249 # ifdef DEBUG_FIFO_ACCESS
     5267#  ifdef DEBUG_FIFO_ACCESS
    52505268                                                GCPhysAddress + (pThis->svga.cbFIFO - 1),
    5251 # else
     5269#  else
    52525270                                                GCPhysAddress + PAGE_SIZE - 1,
    5253 # endif
     5271#  endif
    52545272                                                pThis->svga.hFifoAccessHandlerType, pThis, NIL_RTR0PTR, NIL_RTRCPTR,
    52555273                                                "VMSVGA FIFO");
    52565274                AssertRC(rc);
    52575275            }
     5276# endif
    52585277            if (RT_SUCCESS(rc))
    52595278            {
     
    52655284        {
    52665285            Assert(pThis->svga.GCPhysFIFO);
     5286# if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS)
    52675287            rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pDevIns), pThis->svga.GCPhysFIFO);
    52685288            AssertRC(rc);
     5289# endif
    52695290            pThis->svga.GCPhysFIFO = 0;
    52705291        }
     
    59705991# endif
    59715992
     5993# if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS)
    59725994    /* Register the FIFO access handler type.  In addition to
    59735995       debugging FIFO access, this is also used to facilitate
    59745996       extended fifo thread sleeps. */
    59755997    rc = PGMR3HandlerPhysicalTypeRegister(PDMDevHlpGetVM(pThis->pDevInsR3),
    5976 # ifdef DEBUG_FIFO_ACCESS
     5998#  ifdef DEBUG_FIFO_ACCESS
    59775999                                          PGMPHYSHANDLERKIND_ALL,
    5978 # else
     6000#  else
    59796001                                          PGMPHYSHANDLERKIND_WRITE,
    5980 # endif
     6002#  endif
    59816003                                          vmsvgaR3FIFOAccessHandler,
    59826004                                          NULL, NULL, NULL,
     
    59846006                                          "VMSVGA FIFO", &pThis->svga.hFifoAccessHandlerType);
    59856007    AssertRCReturn(rc, rc);
     6008# endif
    59866009
    59876010    /* Create the async IO thread. */
     
    61446167    STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoWoken,               STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoWoken",                  STAMUNIT_OCCURENCES, "Number of times we discovered pending work after being woken up.");
    61456168    STAM_REL_REG(pVM, &pSVGAState->StatFifoStalls,                  STAMTYPE_PROFILE, "/Devices/VMSVGA/FifoStalls",                     STAMUNIT_TICKS_PER_CALL, "Profiling of FIFO stalls (waiting for guest to finish copying data).");
    6146     STAM_REL_REG(pVM, &pSVGAState->StatFifoSleepOnHandler,          STAMTYPE_PROFILE, "/Devices/VMSVGA/FifoSleepOnHandler",             STAMUNIT_TICKS_PER_CALL, "Profiling FIFO sleeps relying on the access handler.");
     6169    STAM_REL_REG(pVM, &pSVGAState->StatFifoExtendedSleep,           STAMTYPE_PROFILE, "/Devices/VMSVGA/FifoExtendedSleep",              STAMUNIT_TICKS_PER_CALL, "Profiling FIFO sleeps relying on the refresh timer and/or access handler.");
     6170# if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS)
    61476171    STAM_REL_REG(pVM, &pSVGAState->StatFifoAccessHandler,           STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoAccessHandler",              STAMUNIT_OCCURENCES, "Number of times the FIFO access handler triggered.");
     6172# endif
    61486173    STAM_REL_REG(pVM, &pSVGAState->StatFifoCursorFetchAgain,        STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCursorFetchAgain",           STAMUNIT_OCCURENCES, "Times the cursor update counter changed while reading.");
    61496174    STAM_REL_REG(pVM, &pSVGAState->StatFifoCursorNoChange,          STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCursorNoChange",             STAMUNIT_OCCURENCES, "No cursor position change event though the update counter was modified.");
    61506175    STAM_REL_REG(pVM, &pSVGAState->StatFifoCursorPosition,          STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCursorPosition",             STAMUNIT_OCCURENCES, "Cursor position and visibility changes.");
    61516176    STAM_REL_REG(pVM, &pSVGAState->StatFifoCursorVisiblity,         STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCursorVisiblity",            STAMUNIT_OCCURENCES, "Cursor visibility changes.");
     6177    STAM_REL_REG(pVM, &pSVGAState->StatFifoWatchdogWakeUps,         STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoWatchdogWakeUps",            STAMUNIT_OCCURENCES, "Number of times the FIFO refresh poller/watchdog woke up the FIFO thread.");
    61526178
    61536179    /*
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h

    r77206 r77287  
    232232    /** FIFO IO Thread. */
    233233    R3PTRTYPE(PPDMTHREAD)       pFIFOIOThread;
     234    /** The last seen SVGA_FIFO_CURSOR_COUNT value.
     235     * Used by the FIFO thread and its watchdog. */
     236    uint32_t                    uLastCursorUpdateCount;
     237    /** Indicates that the FIFO thread is sleeping and might need waking up. */
     238    bool volatile               fFIFOThreadSleeping;
    234239    /** The legacy GFB mode registers. If used, they correspond to screen 0. */
    235240    /** True when the guest modifies the GFB mode registers. */
    236241    bool                        fGFBRegisters;
    237     bool                        afPadding[7];
     242    bool                        afPadding[2];
    238243    uint32_t                    uWidth;
    239244    uint32_t                    uHeight;
     
    262267    /** GMR debug access handler type handle. */
    263268    PGMPHYSHANDLERTYPE          hGmrAccessHandlerType;
    264 #else
    265     uint32_t                    uPadding1;
    266 #endif
     269#endif
     270#if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS)
    267271    /** FIFO debug access handler type handle. */
    268272    PGMPHYSHANDLERTYPE          hFifoAccessHandlerType;
     273#elif defined(DEBUG_GMR_ACCESS)
     274    uint32_t                    uPadding1;
     275#endif
    269276    /** Number of GMRs. */
    270277    uint32_t                    cGMR;
     
    355362} VMSVGAState;
    356363
     364typedef struct VGAState *PVGASTATE;
    357365
    358366DECLCALLBACK(int) vmsvgaR3IORegionMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
     
    370378DECLCALLBACK(void) vmsvgaR3PowerOn(PPDMDEVINS pDevIns);
    371379DECLCALLBACK(void) vmsvgaR3PowerOff(PPDMDEVINS pDevIns);
    372 
    373 typedef struct VGAState *PVGASTATE;
     380void vmsvgaFIFOWatchdogTimer(PVGASTATE pThis);
    374381
    375382#ifdef IN_RING3
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r77283 r77287  
    54275427#ifdef VBOX_WITH_CRHGSMI
    54285428    vboxCmdVBVATimerRefresh(pThis);
     5429#endif
     5430
     5431#ifdef VBOX_WITH_VMSVGA
     5432    /*
     5433     * Call the VMSVGA FIFO poller/watchdog so we can wake up the thread if
     5434     * there is work to be done.
     5435     */
     5436    if (pThis->svga.fFIFOThreadSleeping && pThis->svga.fEnabled && pThis->svga.fConfigured)
     5437        vmsvgaFIFOWatchdogTimer(pThis);
    54295438#endif
    54305439}
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