VirtualBox

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


Ignore:
Timestamp:
Feb 7, 2022 12:45:08 AM (3 years ago)
Author:
vboxsync
Message:

VMM/PDMNetShaper: Don't start the unchoke thread unless there are are one or more bandwidth groups configured. Make the unchoke thread wait on an event sempahore so it can be woken up when needed and stop wasting cpu cycles and battery on lots of unnecessary wakups. Use a timer (real time clock) to wake up the unchoke timer when needed. bugref:10093 bugref:5582

File:
1 edited

Legend:

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

    r93630 r93631  
    3030#include <iprt/asm.h>
    3131#include <iprt/assert.h>
     32#include <iprt/critsect.h>
     33#include <iprt/string.h>
     34#include <iprt/semaphore.h>
    3235#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>
    3836
    3937#include <VBox/vmm/pdmnetshaper.h>
     
    203201
    204202/**
    205  * This is used both by pdmR3NsTxThread and PDMR3NsBwGroupSetLimit,
     203 * This is used both by pdmR3NsUnchokeThread and PDMR3NsBwGroupSetLimit,
    206204 * the latter only when setting cbPerSecMax to zero.
    207205 *
     
    316314
    317315/**
    318  * I/O thread for pending TX.
     316 * I/O thread for pending unchoking and associating transmitting.
    319317 *
    320318 * @returns VINF_SUCCESS (ignored).
     
    322320 * @param   pThread     The PDM thread data.
    323321 */
    324 static DECLCALLBACK(int) pdmR3NsTxThread(PVM pVM, PPDMTHREAD pThread)
    325 {
    326     LogFlow(("pdmR3NsTxThread: pVM=%p\n", pVM));
     322static DECLCALLBACK(int) pdmR3NsUnchokeThread(PVM pVM, PPDMTHREAD pThread)
     323{
     324    LogFlow(("pdmR3NsUnchokeThread: pVM=%p\n", pVM));
    327325    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    328326    {
    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));
    331332
    332333        /*
     
    336337         * from taking place while we're traversing the filter lists.
    337338         */
    338         int rc = RTCritSectEnter(&pVM->pdm.s.NsLock);
     339        rc = RTCritSectEnter(&pVM->pdm.s.NsLock);
    339340        AssertRC(rc);
    340341
     
    358359 * @copydoc FNPDMTHREADWAKEUPINT
    359360 */
    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. */
     361static 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);
    367370    return VINF_SUCCESS;
     371}
     372
     373
     374/**
     375 * @callback_method_impl{FNTMTIMERINT, Wakes up pdmR3NsUnchokeThread.}
     376 */
     377static 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);
    368386}
    369387
     
    400418    LogFlow(("pdmR3NetShaperInit: pVM=%p\n", pVM));
    401419    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;
    402424
    403425    /*
     
    467489    {
    468490        /*
    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.
    470494         */
    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);
    473502        if (RT_SUCCESS(rc))
    474503        {
    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            }
    477517        }
    478518    }
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