VirtualBox

Changeset 42062 in vbox


Ignore:
Timestamp:
Jul 9, 2012 3:10:00 PM (13 years ago)
Author:
vboxsync
Message:

NetShaper: R0 support (#5582)

Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmnetshaper.h

    r41891 r42062  
    44
    55/*
    6  * Copyright (C) 2007-2012 Oracle Corporation
     6 * Copyright (C) 2011-2012 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4242{
    4343    /** [R3] Pointer to the next group in the list. */
    44     struct PDMNSFILTER      *pNext;
     44    struct PDMNSFILTER              *pNext;
    4545    /** [R3] Pointer to the bandwidth group. */
    46     struct PDMNSBWGROUP     *pBwGroupR3;
     46    struct PDMNSBWGROUP             *pBwGroupR3;
     47    /** [R0] Pointer to the bandwidth group. */
     48    R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0;
    4749    /** Becomes true when filter fails to obtain bandwidth. */
    48     bool                     fChoked;
    49     /** The driver this filter is aggregated into. */
    50     PPDMINETWORKDOWN         pIDrvNet;
     50    bool                             fChoked;
     51    /** [R3] The driver this filter is aggregated into. */
     52    PPDMINETWORKDOWN                 pIDrvNet;
    5153} PDMNSFILTER;
    5254
     
    6163typedef struct PDMNETSHAPER *PPDMNETSHAPER;
    6264
     65
     66/**
     67 * Obtain bandwidth in a bandwidth group (R0 version).
     68 *
     69 * @returns VBox status code.
     70 * @param   pFilter         Pointer to the filter that allocates bandwidth.
     71 * @param   cbTransfer      Number of bytes to allocate.
     72 */
     73VMMR0DECL(bool) PDMR0NsAllocateBandwidth(PPDMNSFILTER pFilter, uint32_t cbTransfer);
    6374
    6475/**
  • trunk/src/VBox/Devices/Makefile.kmk

    r42057 r42062  
    973973 endif
    974974
     975 ifdef VBOX_WITH_NETSHAPER
     976  VBoxDDR0_DEFS         += VBOX_WITH_NETSHAPER
     977  VBoxDDR0_SOURCES      += \
     978        Network/DrvNetShaper.cpp
     979 endif
     980
    975981 ifdef VBOX_WITH_HGSMI
    976982  VBoxDDR0_DEFS         += VBOX_WITH_HGSMI
  • trunk/src/VBox/Devices/Network/DrvNetShaper.cpp

    r40706 r42062  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2011-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4646typedef struct DRVNETSHAPER
    4747{
     48    /** Pointer to the driver instance. */
     49    PPDMDRVINS              pDrvInsR3;
    4850    /** The network interface. */
    49     PDMINETWORKUP           INetworkUp;
     51    PDMINETWORKUP           INetworkUpR3;
     52    /** The connector that's attached to us. */
     53    PPDMINETWORKUP          pIBelowNetR3;
     54
     55    /** Pointer to the driver instance. */
     56    PPDMDRVINSR0            pDrvInsR0;
     57    /** The network interface. */
     58    PDMINETWORKUPR0         INetworkUpR0;
     59    /** The connector that's attached to us. */
     60    PPDMINETWORKUPR0        pIBelowNetR0;
     61
     62    /** Ring-3 base interface for the ring-0 context. */
     63    PDMIBASER0              IBaseR0;
     64    /** Ring-3 base interface for the raw-mode context. */
     65    PDMIBASERC              IBaseRC;
     66
     67    /** For when we're the leaf driver. */
     68    PDMCRITSECT             XmitLock;
     69
    5070    /** The network interface. */
    5171    PDMINETWORKDOWN         INetworkDown;
     
    5777    /** The config port interface we're attached to. */
    5878    PPDMINETWORKCONFIG      pIAboveConfig;
    59     /** The connector that's attached to us. */
    60     PPDMINETWORKUP          pIBelowNet;
     79    /** The filter that represents us at bandwidth group. */
     80    PDMNSFILTER             Filter;
    6181    /** The name of bandwidth group we are attached to. */
    6282    char *                  pszBwGroup;
    63     /** The filter that represents us at bandwidth group. */
    64     PDMNSFILTER             Filter;
    65     /** Pointer to the driver instance. */
    66     PPDMDRVINS              pDrvIns;
    67     /** For when we're the leaf driver. */
    68     RTCRITSECT              XmitLock;
    6983
    7084    /** TX: Total number of bytes to allocate. */
     
    88102 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
    89103 */
    90 static DECLCALLBACK(int) drvNetShaperUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
    91 {
    92     PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkUp);
    93     if (RT_UNLIKELY(!pThis->pIBelowNet))
    94     {
    95         int rc = RTCritSectTryEnter(&pThis->XmitLock);
     104PDMBOTHCBDECL(int) drvNetShaperUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
     105{
     106    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
     107    if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
     108    {
     109        int rc = PDMCritSectTryEnter(&pThis->XmitLock);
    96110        if (RT_UNLIKELY(rc == VERR_SEM_BUSY))
    97111            rc = VERR_TRY_AGAIN;
    98112        return rc;
    99113    }
    100     return pThis->pIBelowNet->pfnBeginXmit(pThis->pIBelowNet, fOnWorkerThread);
     114    return pThis->CTX_SUFF(pIBelowNet)->pfnBeginXmit(pThis->CTX_SUFF(pIBelowNet), fOnWorkerThread);
    101115}
    102116
     
    105119 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
    106120 */
    107 static DECLCALLBACK(int) drvNetShaperUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
     121PDMBOTHCBDECL(int) drvNetShaperUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
    108122                                                  PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
    109123{
    110     PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkUp);
    111     if (RT_UNLIKELY(!pThis->pIBelowNet))
     124    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
     125    if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
    112126        return VERR_NET_DOWN;
    113127    //LogFlow(("drvNetShaperUp_AllocBuf: cb=%d\n", cbMin));
    114128    STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesRequested, cbMin);
    115129    STAM_REL_COUNTER_INC(&pThis->StatXmitPktsRequested);
     130#ifdef IN_RING3
    116131    if (!PDMR3NsAllocateBandwidth(&pThis->Filter, cbMin))
    117132    {
     
    120135        return VERR_TRY_AGAIN;
    121136    }
     137#endif
     138#ifdef IN_RING0
     139    if (!PDMR0NsAllocateBandwidth(&pThis->Filter, cbMin))
     140    {
     141        STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesDenied, cbMin);
     142        STAM_REL_COUNTER_INC(&pThis->StatXmitPktsDenied);
     143        return VERR_TRY_AGAIN;
     144    }
     145#endif
    122146    STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesGranted, cbMin);
    123147    STAM_REL_COUNTER_INC(&pThis->StatXmitPktsGranted);
    124148    //LogFlow(("drvNetShaperUp_AllocBuf: got cb=%d\n", cbMin));
    125     return pThis->pIBelowNet->pfnAllocBuf(pThis->pIBelowNet, cbMin, pGso, ppSgBuf);
     149    return pThis->CTX_SUFF(pIBelowNet)->pfnAllocBuf(pThis->CTX_SUFF(pIBelowNet), cbMin, pGso, ppSgBuf);
    126150}
    127151
     
    130154 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
    131155 */
    132 static DECLCALLBACK(int) drvNetShaperUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
    133 {
    134     PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkUp);
    135     if (RT_UNLIKELY(!pThis->pIBelowNet))
     156PDMBOTHCBDECL(int) drvNetShaperUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
     157{
     158    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
     159    if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
    136160        return VERR_NET_DOWN;
    137     return pThis->pIBelowNet->pfnFreeBuf(pThis->pIBelowNet, pSgBuf);
     161    return pThis->CTX_SUFF(pIBelowNet)->pfnFreeBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf);
    138162}
    139163
     
    142166 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
    143167 */
    144 static DECLCALLBACK(int) drvNetShaperUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
    145 {
    146     PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkUp);
    147     if (RT_UNLIKELY(!pThis->pIBelowNet))
     168PDMBOTHCBDECL(int) drvNetShaperUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
     169{
     170    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
     171    if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
    148172        return VERR_NET_DOWN;
    149173
    150     return pThis->pIBelowNet->pfnSendBuf(pThis->pIBelowNet, pSgBuf, fOnWorkerThread);
     174    return pThis->CTX_SUFF(pIBelowNet)->pfnSendBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf, fOnWorkerThread);
    151175}
    152176
     
    155179 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
    156180 */
    157 static DECLCALLBACK(void) drvNetShaperUp_EndXmit(PPDMINETWORKUP pInterface)
     181PDMBOTHCBDECL(void) drvNetShaperUp_EndXmit(PPDMINETWORKUP pInterface)
    158182{
    159183    //LogFlow(("drvNetShaperUp_EndXmit:\n"));
    160     PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkUp);
    161     if (RT_LIKELY(pThis->pIBelowNet))
    162         pThis->pIBelowNet->pfnEndXmit(pThis->pIBelowNet);
     184    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
     185    if (RT_LIKELY(pThis->CTX_SUFF(pIBelowNet)))
     186        pThis->CTX_SUFF(pIBelowNet)->pfnEndXmit(pThis->CTX_SUFF(pIBelowNet));
    163187    else
    164         RTCritSectLeave(&pThis->XmitLock);
     188        PDMCritSectLeave(&pThis->XmitLock);
    165189}
    166190
     
    169193 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
    170194 */
    171 static DECLCALLBACK(void) drvNetShaperUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
     195PDMBOTHCBDECL(void) drvNetShaperUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
    172196{
    173197    LogFlow(("drvNetShaperUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
    174     PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkUp);
    175     if (pThis->pIBelowNet)
    176         pThis->pIBelowNet->pfnSetPromiscuousMode(pThis->pIBelowNet, fPromiscuous);
    177 }
    178 
    179 
     198    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
     199    if (pThis->CTX_SUFF(pIBelowNet))
     200        pThis->CTX_SUFF(pIBelowNet)->pfnSetPromiscuousMode(pThis->CTX_SUFF(pIBelowNet), fPromiscuous);
     201}
     202
     203
     204#ifdef IN_RING3
    180205/**
    181206 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged}
    182207 */
    183 static DECLCALLBACK(void) drvNetShaperUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
     208static DECLCALLBACK(void) drvR3NetShaperUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
    184209{
    185210    LogFlow(("drvNetShaperUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
    186     PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkUp);
    187     if (pThis->pIBelowNet)
    188         pThis->pIBelowNet->pfnNotifyLinkChanged(pThis->pIBelowNet, enmLinkState);
    189 }
    190 
     211    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
     212    if (pThis->pIBelowNetR3)
     213        pThis->pIBelowNetR3->pfnNotifyLinkChanged(pThis->pIBelowNetR3, enmLinkState);
     214}
    191215
    192216/**
    193217 * @interface_method_impl{PDMINETWORKDOWN,pfnWaitReceiveAvail}
    194218 */
    195 static DECLCALLBACK(int) drvNetShaperDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)
     219static DECLCALLBACK(int) drvR3NetShaperDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)
    196220{
    197221    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
     
    203227 * @interface_method_impl{PDMINETWORKDOWN,pfnReceive}
    204228 */
    205 static DECLCALLBACK(int) drvNetShaperDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb)
     229static DECLCALLBACK(int) drvR3NetShaperDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb)
    206230{
    207231    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
     
    213237 * @interface_method_impl{PDMINETWORKDOWN,pfnXmitPending}
    214238 */
    215 static DECLCALLBACK(void) drvNetShaperDown_XmitPending(PPDMINETWORKDOWN pInterface)
     239static DECLCALLBACK(void) drvR3NetShaperDown_XmitPending(PPDMINETWORKDOWN pInterface)
    216240{
    217241    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown);
     
    229253 * @thread  EMT
    230254 */
    231 static DECLCALLBACK(int) drvNetShaperDownCfg_GetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)
     255static DECLCALLBACK(int) drvR3NetShaperDownCfg_GetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)
    232256{
    233257    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
     
    242266 * @thread  EMT
    243267 */
    244 static DECLCALLBACK(PDMNETWORKLINKSTATE) drvNetShaperDownCfg_GetLinkState(PPDMINETWORKCONFIG pInterface)
     268static DECLCALLBACK(PDMNETWORKLINKSTATE) drvR3NetShaperDownCfg_GetLinkState(PPDMINETWORKCONFIG pInterface)
    245269{
    246270    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
     
    256280 * @thread  EMT
    257281 */
    258 static DECLCALLBACK(int) drvNetShaperDownCfg_SetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)
     282static DECLCALLBACK(int) drvR3NetShaperDownCfg_SetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)
    259283{
    260284    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig);
     
    264288
    265289/**
     290 * @interface_method_impl{PDMIBASER0,pfnQueryInterface}
     291 */
     292static DECLCALLBACK(RTR0PTR) drvR3NetShaperIBaseR0_QueryInterface(PPDMIBASER0 pInterface, const char *pszIID)
     293{
     294    PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, IBaseR0);
     295    PDMIBASER0_RETURN_INTERFACE(pThis->pDrvInsR3, pszIID, PDMINETWORKUP, &pThis->INetworkUpR0);
     296    return NIL_RTR0PTR;
     297}
     298
     299/**
     300 * @interface_method_impl{PDMIBASERC,pfnQueryInterface}
     301 */
     302static DECLCALLBACK(RTRCPTR) drvR3NetShaperIBaseRC_QueryInterface(PPDMIBASERC pInterface, const char *pszIID)
     303{
     304    return NIL_RTRCPTR;
     305}
     306
     307/**
    266308 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
    267309 */
    268 static DECLCALLBACK(void *) drvNetShaperQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     310static DECLCALLBACK(void *) drvR3NetShaperIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
    269311{
    270312    PPDMDRVINS     pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    271313    PDRVNETSHAPER  pThis   = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
    272314    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
    273     PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUp);
     315    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASER0, &pThis->IBaseR0);
     316    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASERC, &pThis->IBaseRC);
     317    PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUpR3);
    274318    PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKDOWN, &pThis->INetworkDown);
    275319    PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig);
     
    281325 * @interface_method_impl{PDMDRVREG,pfnDetach}
    282326 */
    283 static DECLCALLBACK(void) drvNetShaperDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
     327static DECLCALLBACK(void) drvR3NetShaperDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
    284328{
    285329    PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
    286330
    287331    LogFlow(("drvNetShaperDetach: pDrvIns: %p, fFlags: %u\n", pDrvIns, fFlags));
    288     RTCritSectEnter(&pThis->XmitLock);
    289     pThis->pIBelowNet = NULL;
    290     RTCritSectLeave(&pThis->XmitLock);
     332    PDMCritSectEnter(&pThis->XmitLock, VERR_IGNORED);
     333    pThis->pIBelowNetR3 = NULL;
     334    pThis->pIBelowNetR0 = NIL_RTR0PTR;
     335    PDMCritSectLeave(&pThis->XmitLock);
    291336}
    292337
     
    295340 * @interface_method_impl{PDMDRVREG,pfnAttach}
    296341 */
    297 static DECLCALLBACK(int) drvNetShaperAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)
     342static DECLCALLBACK(int) drvR3NetShaperAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)
    298343{
    299344    PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
    300345    LogFlow(("drvNetShaperAttach/#%#x: fFlags=%#x\n", pDrvIns->iInstance, fFlags));
    301     RTCritSectEnter(&pThis->XmitLock);
     346    PDMCritSectEnter(&pThis->XmitLock, VERR_IGNORED);
    302347
    303348    /*
     
    309354        || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
    310355    {
    311         pThis->pIBelowNet = NULL;
     356        pThis->pIBelowNetR3 = NULL;
     357        pThis->pIBelowNetR0 = NIL_RTR0PTR;
    312358        rc = VINF_SUCCESS;
    313359    }
    314360    else if (RT_SUCCESS(rc))
    315361    {
    316         pThis->pIBelowNet = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
    317         if (pThis->pIBelowNet)
     362        pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
     363        if (pThis->pIBelowNetR3)
     364        {
     365            PPDMIBASER0 pBaseR0  = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0);
     366            pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR;
    318367            rc = VINF_SUCCESS;
     368        }
    319369        else
    320370        {
     
    326376        AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
    327377
    328     RTCritSectLeave(&pThis->XmitLock);
     378    PDMCritSectLeave(&pThis->XmitLock);
    329379    return VINF_SUCCESS;
    330380}
     
    334384 * @interface_method_impl{PDMDRVREG,pfnDestruct}
    335385 */
    336 static DECLCALLBACK(void) drvNetShaperDestruct(PPDMDRVINS pDrvIns)
     386static DECLCALLBACK(void) drvR3NetShaperDestruct(PPDMDRVINS pDrvIns)
    337387{
    338388    PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
     
    341391    PDMDrvHlpNetShaperDetach(pDrvIns, &pThis->Filter);
    342392
    343     if (RTCritSectIsInitialized(&pThis->XmitLock))
    344         RTCritSectDelete(&pThis->XmitLock);
     393    if (PDMCritSectIsInitialized(&pThis->XmitLock))
     394        PDMR3CritSectDelete(&pThis->XmitLock);
    345395}
    346396
     
    350400 *                       PDMDRVREG,pfnDestruct}
    351401 */
    352 static DECLCALLBACK(int) drvNetShaperConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
     402static DECLCALLBACK(int) drvR3NetShaperConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    353403{
    354404    PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER);
     
    359409     * Init the static parts.
    360410     */
     411    pThis->pDrvInsR3                                = pDrvIns;
     412    pThis->pDrvInsR0                                = PDMDRVINS_2_R0PTR(pDrvIns);
    361413    /* IBase */
    362     pDrvIns->IBase.pfnQueryInterface                = drvNetShaperQueryInterface;
     414    pDrvIns->IBase.pfnQueryInterface                = drvR3NetShaperIBase_QueryInterface;
     415    pThis->IBaseR0.pfnQueryInterface                = drvR3NetShaperIBaseR0_QueryInterface;
     416    pThis->IBaseRC.pfnQueryInterface                = drvR3NetShaperIBaseRC_QueryInterface;
    363417    /* INetworkUp */
    364     pThis->INetworkUp.pfnBeginXmit                  = drvNetShaperUp_BeginXmit;
    365     pThis->INetworkUp.pfnAllocBuf                   = drvNetShaperUp_AllocBuf;
    366     pThis->INetworkUp.pfnFreeBuf                    = drvNetShaperUp_FreeBuf;
    367     pThis->INetworkUp.pfnSendBuf                    = drvNetShaperUp_SendBuf;
    368     pThis->INetworkUp.pfnEndXmit                    = drvNetShaperUp_EndXmit;
    369     pThis->INetworkUp.pfnSetPromiscuousMode         = drvNetShaperUp_SetPromiscuousMode;
    370     pThis->INetworkUp.pfnNotifyLinkChanged          = drvNetShaperUp_NotifyLinkChanged;
     418    pThis->INetworkUpR3.pfnBeginXmit                = drvNetShaperUp_BeginXmit;
     419    pThis->INetworkUpR3.pfnAllocBuf                 = drvNetShaperUp_AllocBuf;
     420    pThis->INetworkUpR3.pfnFreeBuf                  = drvNetShaperUp_FreeBuf;
     421    pThis->INetworkUpR3.pfnSendBuf                  = drvNetShaperUp_SendBuf;
     422    pThis->INetworkUpR3.pfnEndXmit                  = drvNetShaperUp_EndXmit;
     423    pThis->INetworkUpR3.pfnSetPromiscuousMode       = drvNetShaperUp_SetPromiscuousMode;
     424    pThis->INetworkUpR3.pfnNotifyLinkChanged        = drvR3NetShaperUp_NotifyLinkChanged;
     425    /*
     426     * Resolve the ring-0 context interface addresses.
     427     */
     428    int rc = pDrvIns->pHlpR3->pfnLdrGetR0InterfaceSymbols(pDrvIns, &pThis->INetworkUpR0,
     429                                                          sizeof(pThis->INetworkUpR0),
     430                                                          "drvNetShaperUp_", PDMINETWORKUP_SYM_LIST);
     431    AssertLogRelRCReturn(rc, rc);
    371432    /* INetworkDown */
    372     pThis->INetworkDown.pfnWaitReceiveAvail         = drvNetShaperDown_WaitReceiveAvail;
    373     pThis->INetworkDown.pfnReceive                  = drvNetShaperDown_Receive;
    374     pThis->INetworkDown.pfnXmitPending              = drvNetShaperDown_XmitPending;
     433    pThis->INetworkDown.pfnWaitReceiveAvail         = drvR3NetShaperDown_WaitReceiveAvail;
     434    pThis->INetworkDown.pfnReceive                  = drvR3NetShaperDown_Receive;
     435    pThis->INetworkDown.pfnXmitPending              = drvR3NetShaperDown_XmitPending;
    375436    /* INetworkConfig */
    376     pThis->INetworkConfig.pfnGetMac                 = drvNetShaperDownCfg_GetMac;
    377     pThis->INetworkConfig.pfnGetLinkState           = drvNetShaperDownCfg_GetLinkState;
    378     pThis->INetworkConfig.pfnSetLinkState           = drvNetShaperDownCfg_SetLinkState;
     437    pThis->INetworkConfig.pfnGetMac                 = drvR3NetShaperDownCfg_GetMac;
     438    pThis->INetworkConfig.pfnGetLinkState           = drvR3NetShaperDownCfg_GetLinkState;
     439    pThis->INetworkConfig.pfnSetLinkState           = drvR3NetShaperDownCfg_SetLinkState;
    379440
    380441    /*
    381442     * Create the locks.
    382443     */
    383     int rc = RTCritSectInit(&pThis->XmitLock);
     444    rc = PDMDrvHlpCritSectInit(pDrvIns, &pThis->XmitLock, RT_SRC_POS, "NetShaper");
    384445    AssertRCReturn(rc, rc);
    385446
     
    439500    if (   rc == VERR_PDM_NO_ATTACHED_DRIVER
    440501        || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
    441         pThis->pIBelowNet = NULL;
     502    {
     503        pThis->pIBelowNetR3 = NULL;
     504        pThis->pIBelowNetR0 = NIL_RTR0PTR;
     505    }
    442506    else if (RT_SUCCESS(rc))
    443507    {
    444         pThis->pIBelowNet = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
    445         if (!pThis->pIBelowNet)
     508        pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
     509        if (!pThis->pIBelowNetR3)
    446510        {
    447511            AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
    448512            return VERR_PDM_MISSING_INTERFACE_BELOW;
    449513        }
     514        PPDMIBASER0 pBaseR0  = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0);
     515        pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR;
    450516    }
    451517    else
     
    484550    "",
    485551    /* szR0Mod */
    486     "",
     552    "VBoxDDR0.r0",
    487553    /* pszDescription */
    488554    "Network Shaper Filter Driver",
    489555    /* fFlags */
    490     PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
     556    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DRVREG_FLAGS_R0,
    491557    /* fClass. */
    492558    PDM_DRVREG_CLASS_NETWORK,
     
    496562    sizeof(DRVNETSHAPER),
    497563    /* pfnConstruct */
    498     drvNetShaperConstruct,
     564    drvR3NetShaperConstruct,
    499565    /* pfnDestruct */
    500     drvNetShaperDestruct,
     566    drvR3NetShaperDestruct,
    501567    /* pfnRelocate */
    502568    NULL,
     
    512578    NULL,
    513579    /* pfnAttach */
    514     drvNetShaperAttach,
     580    drvR3NetShaperAttach,
    515581    /* pfnDetach */
    516     drvNetShaperDetach,
     582    drvR3NetShaperDetach,
    517583    /* pfnPowerOff */
    518584    NULL,
     
    522588    PDM_DRVREG_VERSION
    523589};
    524 
     590#endif /* IN_RING3 */
  • trunk/src/VBox/VMM/Makefile.kmk

    r41906 r42062  
    543543        VMMAll/IEMAllAImplC.cpp
    544544 endif
     545 ifdef VBOX_WITH_NETSHAPER
     546  VMMR0_SOURCES += \
     547        VMMR0/PDMNetShaperR0.cpp
     548 endif
    545549 VMMR0_SOURCES.amd64 = \
    546550        VMMR0/VMMR0JmpA-amd64.asm
  • trunk/src/VBox/VMM/VMMR3/PDMNetShaper.cpp

    r41891 r42062  
    66
    77/*
    8  * Copyright (C) 2006-2012 Oracle Corporation
     8 * Copyright (C) 2011-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4343
    4444#include <VBox/vmm/pdmnetshaper.h>
     45#include <VBox/vmm/pdmnetshaperint.h>
    4546
    4647
     
    4849*   Structures and Typedefs                                                    *
    4950*******************************************************************************/
    50 
    51 /**
    52  * Bandwidth group instance data
    53  */
    54 typedef struct PDMNSBWGROUP
    55 {
    56     /** Pointer to the next group in the list. */
    57     struct PDMNSBWGROUP                        *pNext;
    58     /** Pointer to the shared UVM structure. */
    59     struct PDMNETSHAPER                        *pShaper;
    60     /** Critical section protecting all members below. */
    61     RTCRITSECT               cs;
    62     /** Pointer to the first filter attached to this group. */
    63     struct PDMNSFILTER                         *pFiltersHead;
    64     /** Bandwidth group name. */
    65     char                                       *pszName;
    66     /** Maximum number of bytes filters are allowed to transfer. */
    67     volatile uint64_t                           cbTransferPerSecMax;
    68     /** Number of bytes we are allowed to transfer in one burst. */
    69     volatile uint32_t                           cbBucketSize;
    70     /** Number of bytes we were allowed to transfer at the last update. */
    71     volatile uint32_t                           cbTokensLast;
    72     /** Timestamp of the last update */
    73     volatile uint64_t                           tsUpdatedLast;
    74     /** Reference counter - How many filters are associated with this group. */
    75     volatile uint32_t                           cRefs;
    76 } PDMNSBWGROUP;
    77 /** Pointer to a bandwidth group. */
    78 typedef PDMNSBWGROUP *PPDMNSBWGROUP;
    7951
    8052/**
     
    157129    pBwGroup->cbBucketSize        = RT_MAX(PDM_NETSHAPER_MIN_BUCKET_SIZE,
    158130                                           cbTransferPerSecMax * PDM_NETSHAPER_MAX_LATENCY / 1000);
    159     LogFlowFunc(("New rate limit is %d bytes per second, adjusted bucket size to %d bytes\n",
     131    LogFlowFunc(("New rate limit is %llu bytes per second, adjusted bucket size to %d bytes\n",
    160132                 pBwGroup->cbTransferPerSecMax, pBwGroup->cbBucketSize));
    161133}
     
    163135static int pdmNsBwGroupCreate(PPDMNETSHAPER pShaper, const char *pcszBwGroup, uint64_t cbTransferPerSecMax)
    164136{
    165     LogFlowFunc(("pShaper=%#p pcszBwGroup=%#p{%s} cbTransferPerSecMax=%u\n",
     137    LogFlowFunc(("pShaper=%#p pcszBwGroup=%#p{%s} cbTransferPerSecMax=%llu\n",
    166138                 pShaper, pcszBwGroup, pcszBwGroup, cbTransferPerSecMax));
    167139
     
    174146    if (!pBwGroup)
    175147    {
    176         rc = MMR3HeapAllocZEx(pShaper->pVM, MM_TAG_PDM_NET_SHAPER,
    177                               sizeof(PDMNSBWGROUP),
    178                               (void **)&pBwGroup);
     148        rc = MMHyperAlloc(pShaper->pVM, sizeof(PDMNSBWGROUP), 64,
     149                          MM_TAG_PDM_NET_SHAPER, (void **)&pBwGroup);
    179150        if (RT_SUCCESS(rc))
    180151        {
    181             rc = RTCritSectInit(&pBwGroup->cs);
     152            rc = PDMR3CritSectInit(pShaper->pVM, &pBwGroup->cs, RT_SRC_POS, "BWGRP");
    182153            if (RT_SUCCESS(rc))
    183154            {
     
    198169                    return VINF_SUCCESS;
    199170                }
    200                 RTCritSectDelete(&pBwGroup->cs);
     171                PDMR3CritSectDelete(&pBwGroup->cs);
    201172            }
    202             MMR3HeapFree(pBwGroup);
     173            MMHyperFree(pShaper->pVM, pBwGroup);
    203174        }
    204175        else
     
    215186{
    216187    Assert(pBwGroup->cRefs == 0);
    217     if (RTCritSectIsInitialized(&pBwGroup->cs))
    218         RTCritSectDelete(&pBwGroup->cs);
     188    if (PDMCritSectIsInitialized(&pBwGroup->cs))
     189        PDMR3CritSectDelete(&pBwGroup->cs);
    219190}
    220191
     
    267238{
    268239    PPDMNSBWGROUP pBwGroup = pFilter->pBwGroupR3;
    269     int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);
     240    int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
    270241
    271242    pFilter->pNext = pBwGroup->pFiltersHead;
    272243    pBwGroup->pFiltersHead = pFilter;
    273244
    274     rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);
     245    rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
    275246}
    276247
     
    286257    AssertPtr(pBwGroup->pShaper);
    287258    Assert(RTCritSectIsOwner(&pBwGroup->pShaper->cs));
    288     int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);
     259    int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
    289260
    290261    if (pFilter == pBwGroup->pFiltersHead)
     
    301272    }
    302273
    303     rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);
     274    rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
    304275}
    305276
     
    333304        {
    334305            pBwGroupOld = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, pBwGroupNew, PPDMNSBWGROUP);
     306            ASMAtomicWritePtr(&pFilter->pBwGroupR0, MMHyperR3ToR0(pVM, pBwGroupNew));
    335307            if (pBwGroupOld)
    336308                pdmNsBwGroupUnref(pBwGroupOld);
     
    367339VMMR3DECL(bool) PDMR3NsAllocateBandwidth(PPDMNSFILTER pFilter, uint32_t cbTransfer)
    368340{
    369     AssertPtrReturn(pFilter, true);
    370     if (!VALID_PTR(pFilter->pBwGroupR3))
    371         return true;
    372 
    373     PPDMNSBWGROUP pBwGroup = ASMAtomicReadPtrT(&pFilter->pBwGroupR3, PPDMNSBWGROUP);
    374     int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);
    375     bool fAllowed = true;
    376     if (pBwGroup->cbTransferPerSecMax)
    377     {
    378         /* Re-fill the bucket first */
    379         uint64_t tsNow = RTTimeSystemNanoTS();
    380         uint32_t uTokensAdded = (tsNow - pBwGroup->tsUpdatedLast)*pBwGroup->cbTransferPerSecMax/(1000*1000*1000);
    381         uint32_t uTokens = RT_MIN(pBwGroup->cbBucketSize, uTokensAdded + pBwGroup->cbTokensLast);
    382 
    383         if (cbTransfer > uTokens)
    384         {
    385             fAllowed = false;
    386             ASMAtomicWriteBool(&pFilter->fChoked, true);
    387         }
    388         else
    389         {
    390             pBwGroup->tsUpdatedLast = tsNow;
    391             pBwGroup->cbTokensLast = uTokens - cbTransfer;
    392         }
    393         Log2((LOG_FN_FMT "BwGroup=%#p{%s} cbTransfer=%u uTokens=%u uTokensAdded=%u fAllowed=%RTbool\n",
    394               __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, cbTransfer, uTokens, uTokensAdded, fAllowed));
    395     }
    396     else
    397         Log2((LOG_FN_FMT "BwGroup=%#p{%s} disabled fAllowed=%RTbool\n",
    398               __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, fAllowed));
    399 
    400     rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);
    401     return fAllowed;
     341    return pdmNsAllocateBandwidth(pFilter, cbTransfer);
    402342}
    403343
     
    413353        if (pBwGroup)
    414354        {
    415             rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);
     355            rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
    416356            pdmNsBwGroupSetLimit(pBwGroup, cbTransferPerSecMax);
    417357            /* Drop extra tokens */
    418358            if (pBwGroup->cbTokensLast > pBwGroup->cbBucketSize)
    419359                pBwGroup->cbTokensLast = pBwGroup->cbBucketSize;
    420             rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);
     360            rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
    421361        }
    422362        rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc);
     
    486426        pBwGroup = pBwGroup->pNext;
    487427        pdmNsBwGroupTerminate(pFree);
    488         MMR3HeapFree(pFree);
     428        MMHyperFree(pVM, pFree);
    489429    }
    490430
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