VirtualBox

Changeset 44355 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jan 24, 2013 1:27:28 PM (12 years ago)
Author:
vboxsync
Message:

PDMNetShaper: Cleanups & fixes (untested). PVM -> PUVM. Note: cs is a register within the VMM, not critical section. :)

Location:
trunk/src/VBox/VMM
Files:
1 deleted
4 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r43872 r44355  
    214214ifdef VBOX_WITH_NETSHAPER
    215215 VBoxVMM_SOURCES += \
    216         VMMR3/PDMNetShaper.cpp
     216        VMMR3/PDMNetShaper.cpp \
     217        VMMAll/PDMAllNetShaper.cpp
    217218endif
    218219
     
    548549 ifdef VBOX_WITH_NETSHAPER
    549550  VMMR0_SOURCES += \
    550         VMMR0/PDMNetShaperR0.cpp
     551        VMMAll/PDMAllNetShaper.cpp
    551552 endif
    552553 VMMR0_SOURCES.amd64 = \
  • trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp

    r43038 r44355  
    15611561             pDrvIns->pReg->szName, pDrvIns->iInstance, pFilter, pszBwGroup, pszBwGroup));
    15621562
    1563     int rc = PDMR3NsAttach(pDrvIns->Internal.s.pVMR3, pDrvIns, pszBwGroup, pFilter);
     1563    int rc = PDMR3NsAttach(pDrvIns->Internal.s.pVMR3->pUVM, pDrvIns, pszBwGroup, pFilter);
    15641564
    15651565    LogFlow(("pdmR3DrvHlp_NetShaperAttach: caller='%s'/%d: returns %Rrc\n", pDrvIns->pReg->szName,
     
    15761576             pDrvIns->pReg->szName, pDrvIns->iInstance, pFilter));
    15771577
    1578     int rc = PDMR3NsDetach(pDrvIns->Internal.s.pVMR3, pDrvIns, pFilter);
     1578    int rc = PDMR3NsDetach(pDrvIns->Internal.s.pVMR3->pUVM, pDrvIns, pFilter);
    15791579
    15801580    LogFlow(("pdmR3DrvHlp_NetShaperDetach: caller='%s'/%d: returns %Rrc\n", pDrvIns->pReg->szName,
  • trunk/src/VBox/VMM/VMMR3/PDMNetShaper.cpp

    r43229 r44355  
    4242
    4343#include <VBox/vmm/pdmnetshaper.h>
    44 #include <VBox/vmm/pdmnetshaperint.h>
     44#include "PDMNetShaperInternal.h"
    4545
    4646
     
    5757    PVM                      pVM;
    5858    /** Critical section protecting all members below. */
    59     RTCRITSECT               cs;
     59    RTCRITSECT               Lock;
    6060    /** Pending TX thread. */
    61     PPDMTHREAD               hTxThread;
     61    PPDMTHREAD               pTxThread;
    6262    /** Pointer to the first bandwidth group. */
    6363    PPDMNSBWGROUP            pBwGroupsHead;
     
    6565
    6666
    67 
    68 
    69 
    70 
    71 static PPDMNSBWGROUP pdmNsBwGroupFindById(PPDMNETSHAPER pShaper, const char *pcszId)
     67/** Takes the shaper lock (asserts but doesn't return or anything on
     68 *  failure). */
     69#define LOCK_NETSHAPER(a_pShaper) do { int rcShaper = RTCritSectEnter(&(a_pShaper)->Lock); AssertRC(rcShaper); } while (0)
     70
     71/** Takes the shaper lock, returns + asserts on failure. */
     72#define LOCK_NETSHAPER_RETURN(a_pShaper) \
     73    do { int rcShaper = RTCritSectEnter(&(a_pShaper)->Lock); AssertRCReturn(rcShaper, rcShaper); } while (0)
     74
     75/** Releases the shaper lock (asserts on failure). */
     76#define UNLOCK_NETSHAPER(a_pShaper) do { int rcShaper = RTCritSectLeave(&(a_pShaper)->Lock); AssertRC(rcShaper); } while (0)
     77
     78
     79
     80
     81static PPDMNSBWGROUP pdmNsBwGroupFindById(PPDMNETSHAPER pShaper, const char *pszId)
    7282{
    7383    PPDMNSBWGROUP pBwGroup = NULL;
    7484
    75     if (RT_VALID_PTR(pcszId))
    76     {
    77         int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);
     85    if (RT_VALID_PTR(pszId))
     86    {
     87        LOCK_NETSHAPER(pShaper);
    7888
    7989        pBwGroup = pShaper->pBwGroupsHead;
    8090        while (   pBwGroup
    81                && RTStrCmp(pBwGroup->pszName, pcszId))
    82             pBwGroup = pBwGroup->pNext;
    83 
    84         rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc);
     91               && RTStrCmp(pBwGroup->pszNameR3, pszId))
     92            pBwGroup = pBwGroup->pNextR3;
     93
     94        UNLOCK_NETSHAPER(pShaper);
    8595    }
    8696
     
    91101static void pdmNsBwGroupLink(PPDMNSBWGROUP pBwGroup)
    92102{
    93     PPDMNETSHAPER pShaper = pBwGroup->pShaper;
    94     int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);
    95 
    96     pBwGroup->pNext = pShaper->pBwGroupsHead;
     103    PPDMNETSHAPER pShaper = pBwGroup->pShaperR3;
     104    LOCK_NETSHAPER(pShaper);
     105
     106    pBwGroup->pNextR3 = pShaper->pBwGroupsHead;
    97107    pShaper->pBwGroupsHead = pBwGroup;
    98108
    99     rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc);
     109    UNLOCK_NETSHAPER(pShaper);
    100110}
    101111
     
    105115{
    106116    PPDMNETSHAPER pShaper = pBwGroup->pShaper;
    107     int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);
     117    LOCK_NETSHAPER(pShaper);
    108118
    109119    if (pBwGroup == pShaper->pBwGroupsHead)
     
    120130    }
    121131
    122     rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc);
     132    UNLOCK_NETSHAPER(pShaper);
    123133}
    124134#endif
    125135
    126136
    127 static void pdmNsBwGroupSetLimit(PPDMNSBWGROUP pBwGroup, uint64_t cbTransferPerSecMax)
    128 {
    129     pBwGroup->cbTransferPerSecMax = cbTransferPerSecMax;
    130     pBwGroup->cbBucketSize        = RT_MAX(PDM_NETSHAPER_MIN_BUCKET_SIZE,
    131                                            cbTransferPerSecMax * PDM_NETSHAPER_MAX_LATENCY / 1000);
    132     LogFlowFunc(("New rate limit is %llu bytes per second, adjusted bucket size to %d bytes\n",
    133                  pBwGroup->cbTransferPerSecMax, pBwGroup->cbBucketSize));
    134 }
    135 
    136 
    137 static int pdmNsBwGroupCreate(PPDMNETSHAPER pShaper, const char *pcszBwGroup, uint64_t cbTransferPerSecMax)
    138 {
    139     LogFlowFunc(("pShaper=%#p pcszBwGroup=%#p{%s} cbTransferPerSecMax=%llu\n",
    140                  pShaper, pcszBwGroup, pcszBwGroup, cbTransferPerSecMax));
     137static void pdmNsBwGroupSetLimit(PPDMNSBWGROUP pBwGroup, uint64_t cbPerSecMax)
     138{
     139    pBwGroup->cbPerSecMax = cbPerSecMax;
     140    pBwGroup->cbBucket    = RT_MAX(PDM_NETSHAPER_MIN_BUCKET_SIZE, cbPerSecMax * PDM_NETSHAPER_MAX_LATENCY / 1000);
     141    LogFlow(("pdmNsBwGroupSetLimit: New rate limit is %llu bytes per second, adjusted bucket size to %u bytes\n",
     142             pBwGroup->cbPerSecMax, pBwGroup->cbBucket));
     143}
     144
     145
     146static int pdmNsBwGroupCreate(PPDMNETSHAPER pShaper, const char *pszBwGroup, uint64_t cbPerSecMax)
     147{
     148    LogFlow(("pdmNsBwGroupCreate: pShaper=%#p pszBwGroup=%#p{%s} cbPerSecMax=%llu\n", pShaper, pszBwGroup, pszBwGroup, cbPerSecMax));
    141149
    142150    AssertPtrReturn(pShaper, VERR_INVALID_POINTER);
    143     AssertPtrReturn(pcszBwGroup, VERR_INVALID_POINTER);
    144     AssertReturn(*pcszBwGroup != '\0', VERR_INVALID_PARAMETER);
     151    AssertPtrReturn(pszBwGroup, VERR_INVALID_POINTER);
     152    AssertReturn(*pszBwGroup != '\0', VERR_INVALID_PARAMETER);
    145153
    146154    int         rc;
    147     PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pcszBwGroup);
     155    PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pszBwGroup);
    148156    if (!pBwGroup)
    149157    {
     
    152160        if (RT_SUCCESS(rc))
    153161        {
    154             rc = PDMR3CritSectInit(pShaper->pVM, &pBwGroup->cs, RT_SRC_POS, "BWGRP");
     162            rc = PDMR3CritSectInit(pShaper->pVM, &pBwGroup->Lock, RT_SRC_POS, "BWGRP");
    155163            if (RT_SUCCESS(rc))
    156164            {
    157                 pBwGroup->pszName = RTStrDup(pcszBwGroup);
    158                 if (pBwGroup->pszName)
     165                pBwGroup->pszNameR3 = MMR3HeapStrDup(pShaper->pVM, MM_TAG_PDM_NET_SHAPER, pszBwGroup);
     166                if (pBwGroup->pszNameR3)
    159167                {
    160                     pBwGroup->pShaper               = pShaper;
     168                    pBwGroup->pShaperR3             = pShaper;
    161169                    pBwGroup->cRefs                 = 0;
    162170
    163                     pdmNsBwGroupSetLimit(pBwGroup, cbTransferPerSecMax);
    164 
    165                     pBwGroup->cbTokensLast          = pBwGroup->cbBucketSize;
     171                    pdmNsBwGroupSetLimit(pBwGroup, cbPerSecMax);
     172
     173                    pBwGroup->cbTokensLast          = pBwGroup->cbBucket;
    166174                    pBwGroup->tsUpdatedLast         = RTTimeSystemNanoTS();
    167175
    168                     LogFlowFunc(("pcszBwGroup={%s} cbBucketSize=%u\n",
    169                                  pcszBwGroup, pBwGroup->cbBucketSize));
     176                    LogFlowFunc(("pszBwGroup={%s} cbBucket=%u\n",
     177                                 pszBwGroup, pBwGroup->cbBucket));
    170178                    pdmNsBwGroupLink(pBwGroup);
    171179                    return VINF_SUCCESS;
    172180                }
    173                 PDMR3CritSectDelete(&pBwGroup->cs);
     181                PDMR3CritSectDelete(&pBwGroup->Lock);
    174182            }
    175183            MMHyperFree(pShaper->pVM, pBwGroup);
     
    189197{
    190198    Assert(pBwGroup->cRefs == 0);
    191     if (PDMCritSectIsInitialized(&pBwGroup->cs))
    192         PDMR3CritSectDelete(&pBwGroup->cs);
     199    if (PDMCritSectIsInitialized(&pBwGroup->Lock))
     200        PDMR3CritSectDelete(&pBwGroup->Lock);
    193201}
    194202
     
    215223     */
    216224    AssertPtr(pBwGroup);
    217     AssertPtr(pBwGroup->pShaper);
    218     Assert(RTCritSectIsOwner(&pBwGroup->pShaper->cs));
    219     //int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);
     225    AssertPtr(pBwGroup->pShaperR3);
     226    Assert(RTCritSectIsOwner(&pBwGroup->pShaperR3->Lock));
     227    //LOCK_NETSHAPER(pShaper);
    220228
    221229    /* Check if the group is disabled. */
    222     if (pBwGroup->cbTransferPerSecMax == 0)
     230    if (pBwGroup->cbPerSecMax == 0)
    223231        return;
    224232
    225     PPDMNSFILTER pFilter = pBwGroup->pFiltersHead;
     233    PPDMNSFILTER pFilter = pBwGroup->pFiltersHeadR3;
    226234    while (pFilter)
    227235    {
    228236        bool fChoked = ASMAtomicXchgBool(&pFilter->fChoked, false);
    229237        Log3((LOG_FN_FMT ": pFilter=%#p fChoked=%RTbool\n", __PRETTY_FUNCTION__, pFilter, fChoked));
    230         if (fChoked && pFilter->pIDrvNet)
     238        if (fChoked && pFilter->pIDrvNetR3)
    231239        {
    232240            LogFlowFunc(("Calling pfnXmitPending for pFilter=%#p\n", pFilter));
    233             pFilter->pIDrvNet->pfnXmitPending(pFilter->pIDrvNet);
     241            pFilter->pIDrvNetR3->pfnXmitPending(pFilter->pIDrvNetR3);
    234242        }
    235243
    236         pFilter = pFilter->pNext;
    237     }
    238 
    239     //rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);
     244        pFilter = pFilter->pNextR3;
     245    }
     246
     247    //UNLOCK_NETSHAPER(pShaper);
    240248}
    241249
     
    244252{
    245253    PPDMNSBWGROUP pBwGroup = pFilter->pBwGroupR3;
    246     int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
    247 
    248     pFilter->pNext = pBwGroup->pFiltersHead;
    249     pBwGroup->pFiltersHead = pFilter;
    250 
    251     rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
     254    int rc = PDMCritSectEnter(&pBwGroup->Lock, VERR_SEM_BUSY); AssertRC(rc);
     255
     256    pFilter->pNextR3 = pBwGroup->pFiltersHeadR3;
     257    pBwGroup->pFiltersHeadR3 = pFilter;
     258
     259    rc = PDMCritSectLeave(&pBwGroup->Lock); AssertRC(rc);
    252260}
    253261
     
    262270     */
    263271    AssertPtr(pBwGroup);
    264     AssertPtr(pBwGroup->pShaper);
    265     Assert(RTCritSectIsOwner(&pBwGroup->pShaper->cs));
    266     int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
    267 
    268     if (pFilter == pBwGroup->pFiltersHead)
    269         pBwGroup->pFiltersHead = pFilter->pNext;
     272    AssertPtr(pBwGroup->pShaperR3);
     273    Assert(RTCritSectIsOwner(&pBwGroup->pShaperR3->Lock));
     274    int rc = PDMCritSectEnter(&pBwGroup->Lock, VERR_SEM_BUSY); AssertRC(rc);
     275
     276    if (pFilter == pBwGroup->pFiltersHeadR3)
     277        pBwGroup->pFiltersHeadR3 = pFilter->pNextR3;
    270278    else
    271279    {
    272         PPDMNSFILTER pPrev = pBwGroup->pFiltersHead;
     280        PPDMNSFILTER pPrev = pBwGroup->pFiltersHeadR3;
    273281        while (   pPrev
    274                && pPrev->pNext != pFilter)
    275             pPrev = pPrev->pNext;
     282               && pPrev->pNextR3 != pFilter)
     283            pPrev = pPrev->pNextR3;
    276284
    277285        AssertPtr(pPrev);
    278         pPrev->pNext = pFilter->pNext;
    279     }
    280 
    281     rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
    282 }
    283 
    284 
    285 VMMR3DECL(int) PDMR3NsAttach(PVM pVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup,
    286                              PPDMNSFILTER pFilter)
    287 {
    288     VM_ASSERT_EMT(pVM);
     286        pPrev->pNextR3 = pFilter->pNextR3;
     287    }
     288
     289    rc = PDMCritSectLeave(&pBwGroup->Lock); AssertRC(rc);
     290}
     291
     292
     293/**
     294 * Attach network filter driver from bandwidth group.
     295 *
     296 * @returns VBox status code.
     297 * @param   pVM             Handle of VM.
     298 * @param   pDrvIns         The driver instance.
     299 * @param   pszBwGroup     Name of the bandwidth group to attach to.
     300 * @param   pFilter         Pointer to the filter we attach.
     301 */
     302VMMR3_INT_DECL(int) PDMR3NsAttach(PUVM pUVM, PPDMDRVINS pDrvIns, const char *pszBwGroup, PPDMNSFILTER pFilter)
     303{
     304    VM_ASSERT_EMT(pUVM->pVM);
    289305    AssertPtrReturn(pFilter, VERR_INVALID_POINTER);
    290306    AssertReturn(pFilter->pBwGroupR3 == NULL, VERR_ALREADY_EXISTS);
    291307
    292 
    293     PUVM pUVM = pVM->pUVM;
    294308    PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper;
    295 
    296     PPDMNSBWGROUP pBwGroupOld = NULL;
    297     PPDMNSBWGROUP pBwGroupNew = NULL;
    298 
    299     int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);
     309    LOCK_NETSHAPER_RETURN(pShaper);
     310
     311    int             rc          = VINF_SUCCESS;
     312    PPDMNSBWGROUP   pBwGroupNew = NULL;
     313    if (pszBwGroup)
     314    {
     315        pBwGroupNew = pdmNsBwGroupFindById(pShaper, pszBwGroup);
     316        if (pBwGroupNew)
     317            pdmNsBwGroupRef(pBwGroupNew);
     318        else
     319            rc = VERR_NOT_FOUND;
     320    }
     321
    300322    if (RT_SUCCESS(rc))
    301323    {
    302         if (pcszBwGroup)
    303         {
    304             pBwGroupNew = pdmNsBwGroupFindById(pShaper, pcszBwGroup);
    305             if (pBwGroupNew)
    306                 pdmNsBwGroupRef(pBwGroupNew);
    307             else
    308                 rc = VERR_NOT_FOUND;
    309         }
    310 
     324        PPDMNSBWGROUP pBwGroupOld = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, pBwGroupNew, PPDMNSBWGROUP);
     325        ASMAtomicWritePtr(&pFilter->pBwGroupR0, MMHyperR3ToR0(pUVM->pVM, pBwGroupNew));
     326        if (pBwGroupOld)
     327            pdmNsBwGroupUnref(pBwGroupOld);
     328        pdmNsFilterLink(pFilter);
     329    }
     330
     331    UNLOCK_NETSHAPER(pShaper);
     332    return rc;
     333}
     334
     335
     336/**
     337 * Detach network filter driver from bandwidth group.
     338 *
     339 * @returns VBox status code.
     340 * @param   pUVM            The user mode VM handle.
     341 * @param   pDrvIns         The driver instance.
     342 * @param   pFilter         Pointer to the filter we detach.
     343 */
     344VMMR3_INT_DECL(int) PDMR3NsDetach(PUVM pUVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter)
     345{
     346    VM_ASSERT_EMT(pUVM->pVM);
     347    AssertPtrReturn(pFilter, VERR_INVALID_POINTER);
     348    AssertPtrReturn(pFilter->pBwGroupR3, VERR_INVALID_POINTER);
     349
     350    PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper;
     351    LOCK_NETSHAPER_RETURN(pShaper);
     352
     353    pdmNsFilterUnlink(pFilter);
     354    PPDMNSBWGROUP pBwGroup = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, NULL, PPDMNSBWGROUP);
     355    if (pBwGroup)
     356        pdmNsBwGroupUnref(pBwGroup);
     357
     358    UNLOCK_NETSHAPER(pShaper);
     359    return VINF_SUCCESS;
     360}
     361
     362
     363/**
     364 * Adjusts the maximum rate for the bandwidth group.
     365 *
     366 * @returns VBox status code.
     367 * @param   pUVM            The user mode VM handle.
     368 * @param   pszBwGroup      Name of the bandwidth group to attach to.
     369 * @param   cbPerSecMax     Maximum number of bytes per second to be transmitted.
     370 */
     371VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PUVM pUVM, const char *pszBwGroup, uint64_t cbPerSecMax)
     372{
     373    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
     374    PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper;
     375    LOCK_NETSHAPER_RETURN(pShaper);
     376
     377    int           rc;
     378    PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pszBwGroup);
     379    if (pBwGroup)
     380    {
     381        rc = PDMCritSectEnter(&pBwGroup->Lock, VERR_SEM_BUSY); AssertRC(rc);
    311382        if (RT_SUCCESS(rc))
    312383        {
    313             pBwGroupOld = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, pBwGroupNew, PPDMNSBWGROUP);
    314             ASMAtomicWritePtr(&pFilter->pBwGroupR0, MMHyperR3ToR0(pVM, pBwGroupNew));
    315             if (pBwGroupOld)
    316                 pdmNsBwGroupUnref(pBwGroupOld);
    317             pdmNsFilterLink(pFilter);
     384            pdmNsBwGroupSetLimit(pBwGroup, cbPerSecMax);
     385
     386            /* Drop extra tokens */
     387            if (pBwGroup->cbTokensLast > pBwGroup->cbBucket)
     388                pBwGroup->cbTokensLast = pBwGroup->cbBucket;
     389
     390            int rc2 = PDMCritSectLeave(&pBwGroup->Lock); AssertRC(rc2);
    318391        }
    319         int rc2 = RTCritSectLeave(&pShaper->cs); AssertRC(rc2);
    320     }
    321 
    322     return rc;
    323 }
    324 
    325 
    326 VMMR3DECL(int) PDMR3NsDetach(PVM pVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter)
    327 {
    328     VM_ASSERT_EMT(pVM);
    329     AssertPtrReturn(pFilter, VERR_INVALID_POINTER);
    330     AssertPtrReturn(pFilter->pBwGroupR3, VERR_INVALID_POINTER);
    331 
    332     PUVM pUVM = pVM->pUVM;
    333     PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper;
    334 
    335     int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);
    336     if (RT_SUCCESS(rc))
    337     {
    338         pdmNsFilterUnlink(pFilter);
    339         PPDMNSBWGROUP pBwGroup = NULL;
    340         pBwGroup = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, NULL, PPDMNSBWGROUP);
    341         if (pBwGroup)
    342             pdmNsBwGroupUnref(pBwGroup);
    343         int rc2 = RTCritSectLeave(&pShaper->cs); AssertRC(rc2);
    344     }
    345     return rc;
    346 }
    347 
    348 
    349 VMMR3DECL(bool) PDMR3NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer)
    350 {
    351     return pdmNsAllocateBandwidth(pFilter, cbTransfer);
    352 }
    353 
    354 
    355 VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PVM pVM, const char *pcszBwGroup, uint64_t cbTransferPerSecMax)
    356 {
    357     PUVM pUVM = pVM->pUVM;
    358     PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper;
    359 
    360     int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);
    361     if (RT_SUCCESS(rc))
    362     {
    363         PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pcszBwGroup);
    364         if (pBwGroup)
    365         {
    366             rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
    367             pdmNsBwGroupSetLimit(pBwGroup, cbTransferPerSecMax);
    368             /* Drop extra tokens */
    369             if (pBwGroup->cbTokensLast > pBwGroup->cbBucketSize)
    370                 pBwGroup->cbTokensLast = pBwGroup->cbBucketSize;
    371             rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
    372         }
    373         rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc);
    374     }
     392    }
     393    else
     394        rc = VERR_NOT_FOUND;
     395
     396    UNLOCK_NETSHAPER(pShaper);
    375397    return rc;
    376398}
     
    391413    {
    392414        RTThreadSleep(PDM_NETSHAPER_MAX_LATENCY);
     415
    393416        /* Go over all bandwidth groups/filters calling pfnXmitPending */
    394         int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc);
     417        LOCK_NETSHAPER(pShaper);
    395418        PPDMNSBWGROUP pBwGroup = pShaper->pBwGroupsHead;
    396419        while (pBwGroup)
    397420        {
    398421            pdmNsBwGroupXmitPending(pBwGroup);
    399             pBwGroup = pBwGroup->pNext;
     422            pBwGroup = pBwGroup->pNextR3;
    400423        }
    401         rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc);
     424        UNLOCK_NETSHAPER(pShaper);
    402425    }
    403426    return VINF_SUCCESS;
     
    437460    {
    438461        PPDMNSBWGROUP pFree = pBwGroup;
    439         pBwGroup = pBwGroup->pNext;
     462        pBwGroup = pBwGroup->pNextR3;
    440463        pdmNsBwGroupTerminate(pFree);
     464        MMR3HeapFree(pFree->pszNameR3);
    441465        MMHyperFree(pVM, pFree);
    442466    }
    443467
    444     RTCritSectDelete(&pShaper->cs);
     468    RTCritSectDelete(&pShaper->Lock);
    445469    return VINF_SUCCESS;
    446470}
     
    455479int pdmR3NetShaperInit(PVM pVM)
    456480{
    457     LogFlowFunc((": pVM=%p\n", pVM));
    458 
     481    LogFlow(("pdmR3NetShaperInit: pVM=%p\n", pVM));
    459482    VM_ASSERT_EMT(pVM);
    460 
    461     PPDMNETSHAPER pNetShaper = NULL;
    462 
    463     int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_NET_SHAPER,
    464                               sizeof(PDMNETSHAPER),
    465                               (void **)&pNetShaper);
     483    PUVM pUVM = pVM->pUVM;
     484    AssertMsgReturn(!pUVM->pdm.s.pNetShaper, ("Network shaper was already initialized\n"), VERR_WRONG_ORDER);
     485
     486    PPDMNETSHAPER pShaper;
     487    int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_NET_SHAPER, sizeof(PDMNETSHAPER), (void **)&pShaper);
    466488    if (RT_SUCCESS(rc))
    467489    {
    468         PCFGMNODE pCfgRoot      = CFGMR3GetRoot(pVM);
    469         PCFGMNODE pCfgNetShaper = CFGMR3GetChild(CFGMR3GetChild(pCfgRoot, "PDM"), "NetworkShaper");
    470 
    471         pNetShaper->pVM = pVM;
    472         rc = RTCritSectInit(&pNetShaper->cs);
     490        PCFGMNODE pCfgNetShaper = CFGMR3GetChild(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "NetworkShaper");
     491
     492        pShaper->pVM = pVM;
     493        rc = RTCritSectInit(&pShaper->Lock);
    473494        if (RT_SUCCESS(rc))
    474495        {
    475496            /* Create all bandwidth groups. */
    476497            PCFGMNODE pCfgBwGrp = CFGMR3GetChild(pCfgNetShaper, "BwGroups");
    477 
    478498            if (pCfgBwGrp)
    479499            {
     
    496516                        rc = CFGMR3QueryU64(pCur, "Max", &cbMax);
    497517                    if (RT_SUCCESS(rc))
    498                         rc = pdmNsBwGroupCreate(pNetShaper, pszBwGrpId, cbMax);
     518                        rc = pdmNsBwGroupCreate(pShaper, pszBwGrpId, cbMax);
    499519
    500520                    RTMemFree(pszBwGrpId);
     
    507527            if (RT_SUCCESS(rc))
    508528            {
    509                 PUVM pUVM = pVM->pUVM;
    510                 AssertMsg(!pUVM->pdm.s.pNetShaper, ("Network shaper was already initialized\n"));
    511 
    512                 char szDesc[64];
    513                 static unsigned s_iThread;
    514 
    515                 RTStrPrintf(szDesc, sizeof(szDesc), "PDMNsTx-%d", ++s_iThread);
    516                 rc = PDMR3ThreadCreate(pVM, &pNetShaper->hTxThread, pNetShaper,
    517                                        pdmR3NsTxThread, pdmR3NsTxWakeUp, 0,
    518                                        RTTHREADTYPE_IO, szDesc);
     529                rc = PDMR3ThreadCreate(pVM, &pShaper->pTxThread, pShaper, pdmR3NsTxThread, pdmR3NsTxWakeUp,
     530                                       0 /*cbStack*/, RTTHREADTYPE_IO, "PDMNsTx");
    519531                if (RT_SUCCESS(rc))
    520532                {
    521                     pUVM->pdm.s.pNetShaper = pNetShaper;
     533                    pUVM->pdm.s.pNetShaper = pShaper;
    522534                    return VINF_SUCCESS;
    523535                }
    524536            }
    525537
    526             RTCritSectDelete(&pNetShaper->cs);
     538            RTCritSectDelete(&pShaper->Lock);
    527539        }
    528         MMR3HeapFree(pNetShaper);
    529     }
    530 
    531     LogFlowFunc((": pVM=%p rc=%Rrc\n", pVM, rc));
     540
     541        MMR3HeapFree(pShaper);
     542    }
     543
     544    LogFlow(("pdmR3NetShaperInit: pVM=%p rc=%Rrc\n", pVM, rc));
    532545    return rc;
    533546}
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r43657 r44355  
    10861086    R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pAsyncCompletionTemplates;
    10871087    /** @} */
     1088
     1089    /** Global block cache data. */
     1090    R3PTRTYPE(PPDMBLKCACHEGLOBAL)   pBlkCacheGlobal;
    10881091#ifdef VBOX_WITH_NETSHAPER
    10891092    /** Pointer to network shaper instance. */
    10901093    R3PTRTYPE(PPDMNETSHAPER)        pNetShaper;
    10911094#endif /* VBOX_WITH_NETSHAPER */
    1092 
    1093     R3PTRTYPE(PPDMBLKCACHEGLOBAL)   pBlkCacheGlobal;
    10941095
    10951096} PDMUSERPERVM;
  • trunk/src/VBox/VMM/include/PDMNetShaperInternal.h

    r44346 r44355  
    11/* $Id$ */
    22/** @file
    3  * PDM Network Shaper - Internal data structures and functions common for both
    4  * R0 and R3 parts.
     3 * PDM Network Shaper - Internal data structures and functions common for both R0 and R3 parts.
    54 */
    65
    76/*
    8  * Copyright (C) 2011-2012 Oracle Corporation
     7 * Copyright (C) 2011-2013 Oracle Corporation
    98 *
    109 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3231{
    3332    /** Pointer to the next group in the list. */
    34     struct PDMNSBWGROUP                        *pNext;
     33    R3PTRTYPE(struct PDMNSBWGROUP *)            pNextR3;
    3534    /** Pointer to the shared UVM structure. */
    36     struct PDMNETSHAPER                        *pShaper;
     35    R3PTRTYPE(struct PDMNETSHAPER *)            pShaperR3;
    3736    /** Critical section protecting all members below. */
    38     PDMCRITSECT               cs;
     37    PDMCRITSECT                                 Lock;
    3938    /** Pointer to the first filter attached to this group. */
    40     struct PDMNSFILTER                         *pFiltersHead;
     39    R3PTRTYPE(struct PDMNSFILTER *)             pFiltersHeadR3;
    4140    /** Bandwidth group name. */
    42     char                                       *pszName;
     41    R3PTRTYPE(char *)                           pszNameR3;
    4342    /** Maximum number of bytes filters are allowed to transfer. */
    44     volatile uint64_t                           cbTransferPerSecMax;
     43    volatile uint64_t                           cbPerSecMax;
    4544    /** Number of bytes we are allowed to transfer in one burst. */
    46     volatile uint32_t                           cbBucketSize;
     45    volatile uint32_t                           cbBucket;
    4746    /** Number of bytes we were allowed to transfer at the last update. */
    4847    volatile uint32_t                           cbTokensLast;
     
    5554typedef PDMNSBWGROUP *PPDMNSBWGROUP;
    5655
    57 DECLINLINE(bool) pdmNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer)
    58 {
    59     AssertPtrReturn(pFilter, true);
    60     if (!VALID_PTR(pFilter->CTX_SUFF(pBwGroup)))
    61         return true;
    6256
    63     PPDMNSBWGROUP pBwGroup = ASMAtomicReadPtrT(&pFilter->CTX_SUFF(pBwGroup), PPDMNSBWGROUP);
    64     int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
    65     if (RT_UNLIKELY(rc == VERR_SEM_BUSY))
    66         return true;
    67     bool fAllowed = true;
    68     if (pBwGroup->cbTransferPerSecMax)
    69     {
    70         /* Re-fill the bucket first */
    71         uint64_t tsNow = RTTimeSystemNanoTS();
    72         uint32_t uTokensAdded = (tsNow - pBwGroup->tsUpdatedLast)*pBwGroup->cbTransferPerSecMax/(1000*1000*1000);
    73         uint32_t uTokens = RT_MIN(pBwGroup->cbBucketSize, uTokensAdded + pBwGroup->cbTokensLast);
    74 
    75         if (cbTransfer > uTokens)
    76         {
    77             fAllowed = false;
    78             ASMAtomicWriteBool(&pFilter->fChoked, true);
    79         }
    80         else
    81         {
    82             pBwGroup->tsUpdatedLast = tsNow;
    83             pBwGroup->cbTokensLast = uTokens - (uint32_t)cbTransfer;
    84         }
    85         Log2((LOG_FN_FMT "BwGroup=%#p{%s} cbTransfer=%u uTokens=%u uTokensAdded=%u fAllowed=%RTbool\n",
    86               __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, cbTransfer, uTokens, uTokensAdded, fAllowed));
    87     }
    88     else
    89         Log2((LOG_FN_FMT "BwGroup=%#p{%s} disabled fAllowed=%RTbool\n",
    90               __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, fAllowed));
    91 
    92     rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
    93     return fAllowed;
    94 }
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