VirtualBox

Ignore:
Timestamp:
Jan 13, 2015 12:31:52 PM (10 years ago)
Author:
vboxsync
Message:

VMSVGA: FIFO stats; wait on the work-to-do-semaphore instead of sleeping when we're short on data in the FIFO (rare); Signal the semaphore before entering the FIFO loop so we don't delay work unecessarily when resumed.

File:
1 edited

Legend:

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

    r53780 r53783  
    109109    STAMPROFILE             StatR3CmdDrawPrimitive;
    110110    STAMPROFILE             StatR3CmdSurfaceDMA;
     111
     112    STAMCOUNTER             StatFifoCommands;
     113    STAMCOUNTER             StatFifoErrors;
     114    STAMCOUNTER             StatFifoUnkCmds;
     115    STAMCOUNTER             StatFifoTodoTimeout;
     116    STAMCOUNTER             StatFifoTodoWoken;
     117    STAMPROFILE             StatFifoStalls;
     118
    111119} VMSVGASTATE, *PVMSVGASTATE;
    112120
     
    10411049
    10421050    case SVGA_REG_DEPTH:
    1043         /* @todo read-only?? */
     1051        /** @todo read-only?? */
    10441052        break;
    10451053
     
    18741882 * @retval  NULL on FIFO error.
    18751883 *
    1876  * @param   pThread         The calling PDM thread handle.
    18771884 * @param   cbPayloadReq    The number of bytes of payload requested.
    18781885 * @param   pFIFO           The FIFO.
     
    18841891 * @param   pcbAlreadyRead  How much payload we've already read into the bounce
    18851892 *                          buffer. (We will NEVER re-read anything.)
     1893 * @param   pThread         The calling PDM thread handle.
     1894 * @param   pSVGAState      Pointer to the ring-3 only SVGA state data. For
     1895 *                          statistics collection.
    18861896 */
    1887 static void *vmsvgaFIFOGetCmdPayload(PPDMTHREAD pThread, uint32_t cbPayloadReq, uint32_t volatile *pFIFO,
    1888                                     uint32_t offCurrentCmd, uint32_t offFifoMin, uint32_t offFifoMax,
    1889                                     uint8_t *pbBounceBuf, uint32_t *pcbAlreadyRead)
     1897static void *vmsvgaFIFOGetCmdPayload(uint32_t cbPayloadReq, uint32_t volatile *pFIFO,
     1898                                     uint32_t offCurrentCmd, uint32_t offFifoMin, uint32_t offFifoMax,
     1899                                     uint8_t *pbBounceBuf, uint32_t *pcbAlreadyRead,
     1900                                     PPDMTHREAD pThread, PVGASTATE pThis, PVMSVGASTATE pSVGAState)
    18901901{
    18911902    Assert(pbBounceBuf);
     
    19131924     */
    19141925    uint32_t const cbFifoCmd = offFifoMax - offFifoMin;
    1915     AssertMsgReturn(cbPayloadReq <= cbFifoCmd, ("cbPayloadReq=%#x cbFifoCmd=%#x\n", cbPayloadReq, cbFifoCmd), NULL);
     1926    AssertMsgReturnStmt(cbPayloadReq <= cbFifoCmd, ("cbPayloadReq=%#x cbFifoCmd=%#x\n", cbPayloadReq, cbFifoCmd),
     1927                        STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors),
     1928                        NULL);
    19161929
    19171930    /*
     
    19331946        else
    19341947        {
     1948            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
    19351949            LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
    19361950                           offNextCmd, offFifoMin, offFifoMax));
     
    19471961        else
    19481962        {
     1963            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
    19491964            LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
    19501965                           offNextCmd, offFifoMin, offFifoMax));
     
    19581973         * Insufficient, must wait for it to arrive.
    19591974         */
    1960         for (;;)
     1975        STAM_REL_PROFILE_START(&pSVGAState->StatFifoStalls, Stall);
     1976        for (uint32_t i = 0;; i++)
    19611977        {
    19621978            if (pThread->enmState != PDMTHREADSTATE_RUNNING)
     1979            {
     1980                STAM_REL_PROFILE_STOP(&pSVGAState->StatFifoStalls, Stall);
    19631981                return (void *)(uintptr_t)1;
    1964             Log(("Guest still copying (%x vs %x) current %x next %x stop %x; sleep a bit\n",
    1965                  cbPayloadReq, cbAfter + cbBefore, offCurrentCmd, offNextCmd, pFIFO[SVGA_FIFO_STOP]));
    1966             RTThreadSleep(1);
    1967             /** @todo release counter.   */
     1982            }
     1983            Log(("Guest still copying (%x vs %x) current %x next %x stop %x loop %u; sleep a bit\n",
     1984                 cbPayloadReq, cbAfter + cbBefore, offCurrentCmd, offNextCmd, pFIFO[SVGA_FIFO_STOP], i));
     1985
     1986            SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, i < 16 ? 1 : 2);
    19681987
    19691988            offNextCmd = pFIFO[SVGA_FIFO_NEXT_CMD];
     
    19822001                break;
    19832002        }
     2003        STAM_REL_PROFILE_STOP(&pSVGAState->StatFifoStalls, Stall);
    19842004    }
    19852005
     
    20302050
    20312051    /*
     2052     * Signal the semaphore to make sure we don't wait for 250 after a
     2053     * suspend & resume scenario (see vmsvgaFIFOGetCmdPayload).
     2054     */
     2055    SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
     2056
     2057    /*
    20322058     * Allocate a bounce buffer for command we get from the FIFO.
    20332059     * (All code must return via the end of the function to free this buffer.)
     
    20532079            if (pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
    20542080                continue;
     2081            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoTimeout);
    20552082
    20562083            Log(("vmsvgaFIFOLoop: timeout\n"));
    20572084        }
     2085        else if (pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP])
     2086            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoWoken);
     2087
    20582088        Log(("vmsvgaFIFOLoop: enabled=%d configured=%d busy=%d\n", pThis->svga.fEnabled, pThis->svga.fConfigured, pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
    20592089        Log(("vmsvgaFIFOLoop: min  %x max  %x\n", pFIFO[SVGA_FIFO_MIN], pFIFO[SVGA_FIFO_MAX]));
     
    21372167            LogRelMax(8, ("vmsvgaFIFOLoop: Bad fifo: min=%#x stop=%#x max=%#x\n", offFifoMin, offCurrentCmd, offFifoMax));
    21382168            /** @todo Should we clear SVGA_FIFO_BUSY here like we do above? */
     2169            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
    21392170            continue;
    21402171        }
     
    21562187# define VMSVGAFIFO_GET_CMD_BUFFER_BREAK(a_PtrVar, a_Type, a_cbPayloadReq) \
    21572188            if (1) { \
    2158                 (a_PtrVar) = (a_Type *)vmsvgaFIFOGetCmdPayload(pThread, (a_cbPayloadReq), pFIFO, \
    2159                                                                offCurrentCmd, offFifoMin, offFifoMax, \
    2160                                                                pbBounceBuf, &cbPayload); \
     2189                (a_PtrVar) = (a_Type *)vmsvgaFIFOGetCmdPayload((a_cbPayloadReq), pFIFO, offCurrentCmd, offFifoMin, offFifoMax, \
     2190                                                               pbBounceBuf, &cbPayload, pThread, pThis, pSVGAState); \
    21612191                if (RT_UNLIKELY((uintptr_t)(a_PtrVar) < 2)) { if ((uintptr_t)(a_PtrVar) == 1) continue; break; } \
    21622192            } else do {} while (0)
     
    24232453                PGMR pGMR = &pSVGAState->aGMR[pCmd->gmrId];
    24242454                AssertBreak(pCmd->offsetPages + pCmd->numPages <= pGMR->cMaxPages);
    2425                 AssertBreak(!pCmd->offsetPages || pGMR->paDesc); /* @todo */
     2455                AssertBreak(!pCmd->offsetPages || pGMR->paDesc); /** @todo */
    24262456
    24272457                /* Save the old page descriptors as an array of page addresses (>> PAGE_SHIFT) */
     
    26522682            }
    26532683
     2684            /** @todo SVGA_CMD_RECT_COPY  - see with ubuntu */
     2685
    26542686            default:
    26552687# ifdef VBOX_WITH_VMSVGA3D
     
    29953027                        /* context id + surface id? */
    29963028                        break;
     3029
     3030                    default:
     3031                        STAM_REL_COUNTER_INC(&pSVGAState->StatFifoUnkCmds);
     3032                        AssertFailed();
     3033                        break;
    29973034                    }
    29983035                }
    29993036                else
    30003037# endif // VBOX_WITH_VMSVGA3D
     3038                {
     3039                    STAM_REL_COUNTER_INC(&pSVGAState->StatFifoUnkCmds);
    30013040                    AssertFailed();
     3041                }
    30023042            }
    30033043
     
    30123052            }
    30133053            ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], offCurrentCmd);
     3054            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoCommands);
    30143055
    30153056            /* FIFO progress might trigger an interrupt. */
     
    37473788     * Statistics.
    37483789     */
    3749     STAM_REG(pVM, &pSVGAState->StatR3CmdPresent,       STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/Present",  STAMUNIT_TICKS_PER_CALL, "Profiling of Present.");
    3750     STAM_REG(pVM, &pSVGAState->StatR3CmdDrawPrimitive, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/DrawPrimitive",  STAMUNIT_TICKS_PER_CALL, "Profiling of DrawPrimitive.");
    3751     STAM_REG(pVM, &pSVGAState->StatR3CmdSurfaceDMA,    STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/SurfaceDMA",  STAMUNIT_TICKS_PER_CALL, "Profiling of SurfaceDMA.");
     3790    STAM_REG(pVM, &pSVGAState->StatR3CmdPresent,        STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/Present",  STAMUNIT_TICKS_PER_CALL, "Profiling of Present.");
     3791    STAM_REG(pVM, &pSVGAState->StatR3CmdDrawPrimitive,  STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/DrawPrimitive",  STAMUNIT_TICKS_PER_CALL, "Profiling of DrawPrimitive.");
     3792    STAM_REG(pVM, &pSVGAState->StatR3CmdSurfaceDMA,     STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/SurfaceDMA",  STAMUNIT_TICKS_PER_CALL, "Profiling of SurfaceDMA.");
     3793    STAM_REL_REG(pVM, &pSVGAState->StatFifoCommands,    STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCommands",  STAMUNIT_OCCURENCES, "FIFO command counter.");
     3794    STAM_REL_REG(pVM, &pSVGAState->StatFifoErrors,      STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoErrors",  STAMUNIT_OCCURENCES, "FIFO error counter.");
     3795    STAM_REL_REG(pVM, &pSVGAState->StatFifoUnkCmds,     STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoUnknownCommands",  STAMUNIT_OCCURENCES, "FIFO unknown command counter.");
     3796    STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoTimeout, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoTimeout",  STAMUNIT_OCCURENCES, "Number of times we discovered pending work after a wait timeout.");
     3797    STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoWoken,   STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoWoken",  STAMUNIT_OCCURENCES, "Number of times we discovered pending work after being woken up.");
     3798    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).");
    37523799
    37533800    return VINF_SUCCESS;
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