Changeset 77287 in vbox
- Timestamp:
- Feb 12, 2019 4:47:16 PM (6 years ago)
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
r77282 r77287 246 246 VMSVGASCREENOBJECT aScreens[64]; 247 247 248 # ifdef VBOX_STRICT249 /** The time the access handler for the FIFO last triggered. This should250 * never happen less than a certain interval from the last access, and we251 * assert this. */252 uint64_t TimeLastFIFOIntercept;253 # endif254 255 248 /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */ 256 249 STAMPROFILE StatBusyDelayEmts; … … 324 317 STAMCOUNTER StatFifoTodoWoken; 325 318 STAMPROFILE StatFifoStalls; 326 STAMPROFILE StatFifoSleepOnHandler; 319 STAMPROFILE StatFifoExtendedSleep; 320 # ifdef VMSVGA_USE_FIFO_ACCESS_HANDLER 327 321 STAMCOUNTER StatFifoAccessHandler; 322 # endif 328 323 STAMCOUNTER StatFifoCursorFetchAgain; 329 324 STAMCOUNTER StatFifoCursorNoChange; 330 325 STAMCOUNTER StatFifoCursorPosition; 331 326 STAMCOUNTER StatFifoCursorVisiblity; 332 327 STAMCOUNTER StatFifoWatchdogWakeUps; 333 328 } VMSVGAR3STATE, *PVMSVGAR3STATE; 334 329 #endif /* IN_RING3 */ … … 412 407 #else 413 408 SSMFIELD_ENTRY_IGNORE( VMSVGAR3STATE, hBusyDelayedEmts), 414 #endif415 #ifdef VBOX_STRICT416 SSMFIELD_ENTRY_IGNORE( VMSVGAR3STATE, TimeLastFIFOIntercept),417 409 #endif 418 410 SSMFIELD_ENTRY_IGNORE( VMSVGAR3STATE, StatBusyDelayEmts), … … 485 477 SSMFIELD_ENTRY_IGNORE( VMSVGAR3STATE, StatFifoTodoWoken), 486 478 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) 488 481 SSMFIELD_ENTRY_IGNORE( VMSVGAR3STATE, StatFifoAccessHandler), 482 # endif 489 483 SSMFIELD_ENTRY_IGNORE( VMSVGAR3STATE, StatFifoCursorFetchAgain), 490 484 SSMFIELD_ENTRY_IGNORE( VMSVGAR3STATE, StatFifoCursorNoChange), … … 528 522 SSMFIELD_ENTRY_IGNORE( VMSVGAState, FIFOExtCmdSem), 529 523 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGAState, pFIFOIOThread), 524 SSMFIELD_ENTRY_IGNORE( VMSVGAState, uLastCursorUpdateCount), 525 SSMFIELD_ENTRY_IGNORE( VMSVGAState, fFIFOThreadSleeping), 530 526 SSMFIELD_ENTRY_VER( VMSVGAState, fGFBRegisters, VGA_SAVEDSTATE_VERSION_VMSVGA_SCREENS), 531 527 SSMFIELD_ENTRY( VMSVGAState, uWidth), … … 2362 2358 # endif /* DEBUG_FIFO_ACCESS */ 2363 2359 2360 # if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS) 2364 2361 /** 2365 2362 * HC access handler for the FIFO. … … 2385 2382 AssertPtr(pThis); 2386 2383 2384 # ifdef VMSVGA_USE_FIFO_ACCESS_HANDLER 2387 2385 /* 2388 2386 * Wake up the FIFO thread as it might have work to do now. … … 2390 2388 int rc = SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem); 2391 2389 AssertLogRelRC(rc); 2390 # endif 2392 2391 2393 2392 # ifdef DEBUG_FIFO_ACCESS … … 2398 2397 Assert(GCPhys >= pThis->svga.GCPhysFIFO); 2399 2398 rc = vmsvgaDebugFIFOAccess(pVM, pThis, GCPhys, enmAccessType == PGMACCESSTYPE_WRITE); 2400 # el se2399 # elif defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) 2401 2400 /* 2402 2401 * Temporarily disable the access handler now that we've kicked the FIFO thread. 2403 2402 */ 2404 2405 2403 STAM_REL_COUNTER_INC(&pThis->svga.pSvgaR3State->StatFifoAccessHandler); 2406 2404 rc = PGMHandlerPhysicalPageTempOff(pVM, pThis->svga.GCPhysFIFO, pThis->svga.GCPhysFIFO); … … 2411 2409 return rc; 2412 2410 } 2411 # endif /* VMSVGA_USE_FIFO_ACCESS_HANDLER || DEBUG_FIFO_ACCESS */ 2413 2412 2414 2413 #endif /* IN_RING3 */ … … 3316 3315 3317 3316 3317 /** 3318 * Called by the VGA refresh timer to wake up the FIFO thread when needed. 3319 * 3320 * @param pThis The VGA state. 3321 */ 3322 void 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 3318 3338 /* The async FIFO handling thread. */ 3319 3339 static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread) … … 3360 3380 * 3361 3381 * 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. 3367 3388 */ 3368 3389 RTMSINTERVAL const cMsMinSleep = 16; 3369 3390 RTMSINTERVAL const cMsIncSleep = 2; 3370 3391 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. */ 3373 3393 RTMSINTERVAL cMsSleep = cMsMaxSleep; 3374 3394 … … 3378 3398 */ 3379 3399 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]; 3381 3401 uint32_t xLastCursor = ~pFIFO[SVGA_FIFO_CURSOR_X]; 3382 3402 uint32_t yLastCursor = ~pFIFO[SVGA_FIFO_CURSOR_Y]; … … 3405 3425 || !vmsvgaFIFOHasWork(pFIFO, uLastCursorCount)) 3406 3426 { 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) 3409 3430 rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, cMsSleep); 3410 3431 else 3411 3432 { 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 3421 3434 int rc2 = PGMHandlerPhysicalReset(PDMDevHlpGetVM(pDevIns), pThis->svga.GCPhysFIFO); 3422 3435 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 3426 3441 { 3427 STAM_REL_PROFILE_START(&pSVGAState->StatFifo SleepOnHandler, Acc);3428 rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, cMs AccessHandlerSleep);3429 STAM_REL_PROFILE_STOP(&pSVGAState->StatFifo SleepOnHandler, 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); 3430 3445 } 3431 else3432 rc = VINF_SUCCESS;3433 3446 } 3447 ASMAtomicWriteBool(&pThis->svga.fFIFOThreadSleeping, false); 3434 3448 AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED); 3435 3449 if (pThread->enmState != PDMTHREADSTATE_RUNNING) … … 3524 3538 { /* halfways likely */ } 3525 3539 else 3540 { 3526 3541 uLastCursorCount = vmsvgaFIFOUpdateCursor(pThis, pSVGAState, pFIFO, offFifoMin, uCursorUpdateCount, 3527 3542 &xLastCursor, &yLastCursor, &fLastCursorVisible); 3543 ASMAtomicWriteU32(&pThis->svga.uLastCursorUpdateCount, uLastCursorCount); 3544 } 3528 3545 } 3529 3546 … … 5244 5261 AssertRC(rc); 5245 5262 5263 # if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS) 5246 5264 if (RT_SUCCESS(rc)) 5247 5265 { 5248 5266 rc = PGMHandlerPhysicalRegister(PDMDevHlpGetVM(pDevIns), GCPhysAddress, 5249 # ifdef DEBUG_FIFO_ACCESS5267 # ifdef DEBUG_FIFO_ACCESS 5250 5268 GCPhysAddress + (pThis->svga.cbFIFO - 1), 5251 # else5269 # else 5252 5270 GCPhysAddress + PAGE_SIZE - 1, 5253 # endif5271 # endif 5254 5272 pThis->svga.hFifoAccessHandlerType, pThis, NIL_RTR0PTR, NIL_RTRCPTR, 5255 5273 "VMSVGA FIFO"); 5256 5274 AssertRC(rc); 5257 5275 } 5276 # endif 5258 5277 if (RT_SUCCESS(rc)) 5259 5278 { … … 5265 5284 { 5266 5285 Assert(pThis->svga.GCPhysFIFO); 5286 # if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS) 5267 5287 rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pDevIns), pThis->svga.GCPhysFIFO); 5268 5288 AssertRC(rc); 5289 # endif 5269 5290 pThis->svga.GCPhysFIFO = 0; 5270 5291 } … … 5970 5991 # endif 5971 5992 5993 # if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS) 5972 5994 /* Register the FIFO access handler type. In addition to 5973 5995 debugging FIFO access, this is also used to facilitate 5974 5996 extended fifo thread sleeps. */ 5975 5997 rc = PGMR3HandlerPhysicalTypeRegister(PDMDevHlpGetVM(pThis->pDevInsR3), 5976 # ifdef DEBUG_FIFO_ACCESS5998 # ifdef DEBUG_FIFO_ACCESS 5977 5999 PGMPHYSHANDLERKIND_ALL, 5978 # else6000 # else 5979 6001 PGMPHYSHANDLERKIND_WRITE, 5980 # endif6002 # endif 5981 6003 vmsvgaR3FIFOAccessHandler, 5982 6004 NULL, NULL, NULL, … … 5984 6006 "VMSVGA FIFO", &pThis->svga.hFifoAccessHandlerType); 5985 6007 AssertRCReturn(rc, rc); 6008 # endif 5986 6009 5987 6010 /* Create the async IO thread. */ … … 6144 6167 STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoWoken, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoWoken", STAMUNIT_OCCURENCES, "Number of times we discovered pending work after being woken up."); 6145 6168 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) 6147 6171 STAM_REL_REG(pVM, &pSVGAState->StatFifoAccessHandler, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoAccessHandler", STAMUNIT_OCCURENCES, "Number of times the FIFO access handler triggered."); 6172 # endif 6148 6173 STAM_REL_REG(pVM, &pSVGAState->StatFifoCursorFetchAgain, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCursorFetchAgain", STAMUNIT_OCCURENCES, "Times the cursor update counter changed while reading."); 6149 6174 STAM_REL_REG(pVM, &pSVGAState->StatFifoCursorNoChange, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCursorNoChange", STAMUNIT_OCCURENCES, "No cursor position change event though the update counter was modified."); 6150 6175 STAM_REL_REG(pVM, &pSVGAState->StatFifoCursorPosition, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCursorPosition", STAMUNIT_OCCURENCES, "Cursor position and visibility changes."); 6151 6176 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."); 6152 6178 6153 6179 /* -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h
r77206 r77287 232 232 /** FIFO IO Thread. */ 233 233 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; 234 239 /** The legacy GFB mode registers. If used, they correspond to screen 0. */ 235 240 /** True when the guest modifies the GFB mode registers. */ 236 241 bool fGFBRegisters; 237 bool afPadding[ 7];242 bool afPadding[2]; 238 243 uint32_t uWidth; 239 244 uint32_t uHeight; … … 262 267 /** GMR debug access handler type handle. */ 263 268 PGMPHYSHANDLERTYPE hGmrAccessHandlerType; 264 #else 265 uint32_t uPadding1; 266 #endif 269 #endif 270 #if defined(VMSVGA_USE_FIFO_ACCESS_HANDLER) || defined(DEBUG_FIFO_ACCESS) 267 271 /** FIFO debug access handler type handle. */ 268 272 PGMPHYSHANDLERTYPE hFifoAccessHandlerType; 273 #elif defined(DEBUG_GMR_ACCESS) 274 uint32_t uPadding1; 275 #endif 269 276 /** Number of GMRs. */ 270 277 uint32_t cGMR; … … 355 362 } VMSVGAState; 356 363 364 typedef struct VGAState *PVGASTATE; 357 365 358 366 DECLCALLBACK(int) vmsvgaR3IORegionMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, … … 370 378 DECLCALLBACK(void) vmsvgaR3PowerOn(PPDMDEVINS pDevIns); 371 379 DECLCALLBACK(void) vmsvgaR3PowerOff(PPDMDEVINS pDevIns); 372 373 typedef struct VGAState *PVGASTATE; 380 void vmsvgaFIFOWatchdogTimer(PVGASTATE pThis); 374 381 375 382 #ifdef IN_RING3 -
trunk/src/VBox/Devices/Graphics/DevVGA.cpp
r77283 r77287 5427 5427 #ifdef VBOX_WITH_CRHGSMI 5428 5428 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); 5429 5438 #endif 5430 5439 }
Note:
See TracChangeset
for help on using the changeset viewer.