Changeset 93631 in vbox
- Timestamp:
- Feb 7, 2022 12:45:08 AM (3 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PDMAllNetShaper.cpp
r93628 r93631 60 60 * Re-fill the bucket first 61 61 */ 62 uint64_t const tsNow = RTTimeSystemNanoTS();63 uint64_t const cNsDelta = tsNow - pGroup->tsUpdatedLast;62 uint64_t const nsNow = RTTimeSystemNanoTS(); 63 uint64_t const cNsDelta = nsNow - pGroup->tsUpdatedLast; 64 64 /** @todo r=bird: there might be an overflow issue here if the gap 65 65 * between two transfers is too large. */ … … 76 76 { 77 77 pGroup->cbTokensLast = cTokens - (uint32_t)cbTransfer; 78 pGroup->tsUpdatedLast = tsNow;78 pGroup->tsUpdatedLast = nsNow; 79 79 Log2(("pdmNsAllocateBandwidth/%s: allowed - cbTransfer=%#zx cTokens=%#x cTokensAdded=%#x\n", 80 80 pGroup->szName, cbTransfer, cTokens, cTokensAdded)); … … 82 82 else 83 83 { 84 /* 85 * No, we're choked. Arm the unchoke timer for the next period. 86 * Just do this on a simple PDM_NETSHAPER_MAX_LATENCY clock granularity. 87 * ASSUMES the timer uses millisecond resolution clock. 88 */ 84 89 ASMAtomicWriteBool(&pFilter->fChoked, true); 85 Log2(("pdmNsAllocateBandwidth/%s: refused - cbTransfer=%#zx cTokens=%#x cTokensAdded=%#x\n", 86 pGroup->szName, cbTransfer, cTokens, cTokensAdded)); 90 if (ASMAtomicCmpXchgBool(&pVM->pdm.s.fNsUnchokeTimerArmed, true, false)) 91 { 92 Assert(TMTimerGetFreq(pVM, pVM->pdm.s.hNsUnchokeTimer) == RT_MS_1SEC); 93 uint64_t const msNow = TMTimerGet(pVM, pVM->pdm.s.hNsUnchokeTimer); 94 uint64_t const msExpire = (msNow / PDM_NETSHAPER_MAX_LATENCY + 1) * PDM_NETSHAPER_MAX_LATENCY; 95 rc = TMTimerSet(pVM, pVM->pdm.s.hNsUnchokeTimer, msExpire); 96 AssertRC(rc); 97 98 Log2(("pdmNsAllocateBandwidth/%s: refused - cbTransfer=%#zx cTokens=%#x cTokensAdded=%#x cMsExpire=%u\n", 99 pGroup->szName, cbTransfer, cTokens, cTokensAdded, msExpire - msNow)); 100 } 101 else 102 Log2(("pdmNsAllocateBandwidth/%s: refused - cbTransfer=%#zx cTokens=%#x cTokensAdded=%#x\n", 103 pGroup->szName, cbTransfer, cTokens, cTokensAdded)); 87 104 fAllowed = false; 88 105 } -
trunk/src/VBox/VMM/VMMR3/PDMNetShaper.cpp
r93630 r93631 30 30 #include <iprt/asm.h> 31 31 #include <iprt/assert.h> 32 #include <iprt/critsect.h> 33 #include <iprt/string.h> 34 #include <iprt/semaphore.h> 32 35 #include <iprt/thread.h> 33 #include <iprt/mem.h>34 #include <iprt/critsect.h>35 #include <iprt/tcp.h>36 #include <iprt/path.h>37 #include <iprt/string.h>38 36 39 37 #include <VBox/vmm/pdmnetshaper.h> … … 203 201 204 202 /** 205 * This is used both by pdmR3Ns TxThread and PDMR3NsBwGroupSetLimit,203 * This is used both by pdmR3NsUnchokeThread and PDMR3NsBwGroupSetLimit, 206 204 * the latter only when setting cbPerSecMax to zero. 207 205 * … … 316 314 317 315 /** 318 * I/O thread for pending TX.316 * I/O thread for pending unchoking and associating transmitting. 319 317 * 320 318 * @returns VINF_SUCCESS (ignored). … … 322 320 * @param pThread The PDM thread data. 323 321 */ 324 static DECLCALLBACK(int) pdmR3Ns TxThread(PVM pVM, PPDMTHREAD pThread)325 { 326 LogFlow(("pdmR3Ns TxThread: pVM=%p\n", pVM));322 static DECLCALLBACK(int) pdmR3NsUnchokeThread(PVM pVM, PPDMTHREAD pThread) 323 { 324 LogFlow(("pdmR3NsUnchokeThread: pVM=%p\n", pVM)); 327 325 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 328 326 { 329 /** @todo r=bird: This sleep is horribly crude and wasteful! (Michael would go nuts if he knew) */ 330 RTThreadSleep(PDM_NETSHAPER_MAX_LATENCY); 327 int rc = RTSemEventWait(pVM->pdm.s.hNsUnchokeEvt, RT_INDEFINITE_WAIT); 328 if (pThread->enmState != PDMTHREADSTATE_RUNNING) 329 break; 330 AssertMsgStmt(RT_SUCCESS(rc) || rc == VERR_TIMEOUT /* paranioa*/, ("%Rrc\n", rc), 331 RTThreadSleep(PDM_NETSHAPER_MAX_LATENCY)); 331 332 332 333 /* … … 336 337 * from taking place while we're traversing the filter lists. 337 338 */ 338 intrc = RTCritSectEnter(&pVM->pdm.s.NsLock);339 rc = RTCritSectEnter(&pVM->pdm.s.NsLock); 339 340 AssertRC(rc); 340 341 … … 358 359 * @copydoc FNPDMTHREADWAKEUPINT 359 360 */ 360 static DECLCALLBACK(int) pdmR3NsTxWakeUp(PVM pVM, PPDMTHREAD pThread) 361 { 362 RT_NOREF2(pVM, pThread); 363 LogFlow(("pdmR3NsTxWakeUp: pShaper=%p\n", pThread->pvUser)); 364 /* Nothing to do */ 365 /** @todo r=bird: use a semaphore, this'll cause a PDM_NETSHAPER_MAX_LATENCY/2 366 * delay every time we pause the VM! Stupid stupid stupid. */ 361 static DECLCALLBACK(int) pdmR3NsUnchokeWakeUp(PVM pVM, PPDMTHREAD pThread) 362 { 363 LogFlow(("pdmR3NsUnchokeWakeUp:\n")); 364 365 /* Wake up the thread. */ 366 int rc = RTSemEventSignal(pVM->pdm.s.hNsUnchokeEvt); 367 AssertRC(rc); 368 369 RT_NOREF(pThread); 367 370 return VINF_SUCCESS; 371 } 372 373 374 /** 375 * @callback_method_impl{FNTMTIMERINT, Wakes up pdmR3NsUnchokeThread.} 376 */ 377 static DECLCALLBACK(void) pdmR3NsUnchokeTimer(PVM pVM, TMTIMERHANDLE hTimer, void *pvUser) 378 { 379 ASMAtomicWriteBool(&pVM->pdm.s.fNsUnchokeTimerArmed, false); 380 381 /* Wake up the thread. */ 382 int rc = RTSemEventSignal(pVM->pdm.s.hNsUnchokeEvt); 383 AssertRC(rc); 384 385 RT_NOREF(hTimer, pvUser); 368 386 } 369 387 … … 400 418 LogFlow(("pdmR3NetShaperInit: pVM=%p\n", pVM)); 401 419 VM_ASSERT_EMT(pVM); 420 421 Assert(pVM->pdm.s.cNsGroups == 0); 422 pVM->pdm.s.hNsUnchokeEvt = NIL_RTSEMEVENT; 423 pVM->pdm.s.hNsUnchokeTimer = NIL_TMTIMERHANDLE; 402 424 403 425 /* … … 467 489 { 468 490 /* 469 * Create the transmit thread. 491 * If there are any groups configured, create a unchoke thread and an 492 * associated timer for waking it up when needed. The timer runs on 493 * the real time clock. 470 494 */ 471 rc = PDMR3ThreadCreate(pVM, &pVM->pdm.s.pNsTxThread, NULL, pdmR3NsTxThread, pdmR3NsTxWakeUp, 472 0 /*cbStack*/, RTTHREADTYPE_IO, "PDMNsTx"); 495 if (pVM->pdm.s.cNsGroups == 0) 496 { 497 LogFlowFunc(("returns VINF_SUCCESS - no groups\n")); 498 return VINF_SUCCESS; 499 } 500 501 rc = RTSemEventCreate(&pVM->pdm.s.hNsUnchokeEvt); 473 502 if (RT_SUCCESS(rc)) 474 503 { 475 LogFlowFunc(("returns VINF_SUCCESS\n")); 476 return VINF_SUCCESS; 504 rc = TMR3TimerCreate(pVM, TMCLOCK_REAL, pdmR3NsUnchokeTimer, NULL, TMTIMER_FLAGS_NO_RING0, 505 "PDMNetShaperUnchoke", &pVM->pdm.s.hNsUnchokeTimer); 506 if (RT_SUCCESS(rc)) 507 { 508 rc = PDMR3ThreadCreate(pVM, &pVM->pdm.s.pNsUnchokeThread, NULL, pdmR3NsUnchokeThread, pdmR3NsUnchokeWakeUp, 509 0 /*cbStack*/, RTTHREADTYPE_IO, "PDMNsUnchoke"); 510 if (RT_SUCCESS(rc)) 511 { 512 513 LogFlowFunc(("returns VINF_SUCCESS (%u groups)\n", pVM->pdm.s.cNsGroups)); 514 return VINF_SUCCESS; 515 } 516 } 477 517 } 478 518 } -
trunk/src/VBox/VMM/include/PDMInternal.h
r93628 r93631 1514 1514 bool fStateLoaded; 1515 1515 /** Alignment padding. */ 1516 bool afPadding [3];1516 bool afPadding1[3]; 1517 1517 1518 1518 /** The tracing ID of the next device instance. … … 1544 1544 /** @name Network Shaper 1545 1545 * @{ */ 1546 /** Pending TX thread. */ 1547 PPDMTHREAD pNsTxThread; 1548 uint32_t au32Padding[1+8]; 1546 /** Thread that processes choked filter drivers after 1547 * the a PDM_NETSHAPER_MAX_LATENCY period has elapsed. */ 1548 PPDMTHREAD pNsUnchokeThread; 1549 /** Semaphore that the TX thread waits on. */ 1550 RTSEMEVENT hNsUnchokeEvt; 1551 /** Timer handle for waking up pNsUnchokeThread. */ 1552 TMTIMERHANDLE hNsUnchokeTimer; 1553 /** Indicates whether the unchoke timer has been armed already or not. */ 1554 bool volatile fNsUnchokeTimerArmed; 1555 /** Align aNsGroups on a cacheline. */ 1556 bool afPadding2[19]; 1549 1557 /** Number of network shaper groups. 1550 1558 * @note Marked volatile to prevent re-reading after validation. */
Note:
See TracChangeset
for help on using the changeset viewer.