Changeset 42062 in vbox
- Timestamp:
- Jul 9, 2012 3:10:00 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmnetshaper.h
r41891 r42062 4 4 5 5 /* 6 * Copyright (C) 20 07-2012 Oracle Corporation6 * Copyright (C) 2011-2012 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 42 42 { 43 43 /** [R3] Pointer to the next group in the list. */ 44 struct PDMNSFILTER *pNext;44 struct PDMNSFILTER *pNext; 45 45 /** [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; 47 49 /** 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; 51 53 } PDMNSFILTER; 52 54 … … 61 63 typedef struct PDMNETSHAPER *PPDMNETSHAPER; 62 64 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 */ 73 VMMR0DECL(bool) PDMR0NsAllocateBandwidth(PPDMNSFILTER pFilter, uint32_t cbTransfer); 63 74 64 75 /** -
trunk/src/VBox/Devices/Makefile.kmk
r42057 r42062 973 973 endif 974 974 975 ifdef VBOX_WITH_NETSHAPER 976 VBoxDDR0_DEFS += VBOX_WITH_NETSHAPER 977 VBoxDDR0_SOURCES += \ 978 Network/DrvNetShaper.cpp 979 endif 980 975 981 ifdef VBOX_WITH_HGSMI 976 982 VBoxDDR0_DEFS += VBOX_WITH_HGSMI -
trunk/src/VBox/Devices/Network/DrvNetShaper.cpp
r40706 r42062 5 5 6 6 /* 7 * Copyright (C) 20 06-2012 Oracle Corporation7 * Copyright (C) 2011-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 46 46 typedef struct DRVNETSHAPER 47 47 { 48 /** Pointer to the driver instance. */ 49 PPDMDRVINS pDrvInsR3; 48 50 /** 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 50 70 /** The network interface. */ 51 71 PDMINETWORKDOWN INetworkDown; … … 57 77 /** The config port interface we're attached to. */ 58 78 PPDMINETWORKCONFIG pIAboveConfig; 59 /** The connector that's attached to us. */60 P PDMINETWORKUP pIBelowNet;79 /** The filter that represents us at bandwidth group. */ 80 PDMNSFILTER Filter; 61 81 /** The name of bandwidth group we are attached to. */ 62 82 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;69 83 70 84 /** TX: Total number of bytes to allocate. */ … … 88 102 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit} 89 103 */ 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);104 PDMBOTHCBDECL(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); 96 110 if (RT_UNLIKELY(rc == VERR_SEM_BUSY)) 97 111 rc = VERR_TRY_AGAIN; 98 112 return rc; 99 113 } 100 return pThis-> pIBelowNet->pfnBeginXmit(pThis->pIBelowNet, fOnWorkerThread);114 return pThis->CTX_SUFF(pIBelowNet)->pfnBeginXmit(pThis->CTX_SUFF(pIBelowNet), fOnWorkerThread); 101 115 } 102 116 … … 105 119 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf} 106 120 */ 107 static DECLCALLBACK(int) drvNetShaperUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,121 PDMBOTHCBDECL(int) drvNetShaperUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin, 108 122 PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf) 109 123 { 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))) 112 126 return VERR_NET_DOWN; 113 127 //LogFlow(("drvNetShaperUp_AllocBuf: cb=%d\n", cbMin)); 114 128 STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesRequested, cbMin); 115 129 STAM_REL_COUNTER_INC(&pThis->StatXmitPktsRequested); 130 #ifdef IN_RING3 116 131 if (!PDMR3NsAllocateBandwidth(&pThis->Filter, cbMin)) 117 132 { … … 120 135 return VERR_TRY_AGAIN; 121 136 } 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 122 146 STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesGranted, cbMin); 123 147 STAM_REL_COUNTER_INC(&pThis->StatXmitPktsGranted); 124 148 //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); 126 150 } 127 151 … … 130 154 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf} 131 155 */ 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))156 PDMBOTHCBDECL(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))) 136 160 return VERR_NET_DOWN; 137 return pThis-> pIBelowNet->pfnFreeBuf(pThis->pIBelowNet, pSgBuf);161 return pThis->CTX_SUFF(pIBelowNet)->pfnFreeBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf); 138 162 } 139 163 … … 142 166 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf} 143 167 */ 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))168 PDMBOTHCBDECL(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))) 148 172 return VERR_NET_DOWN; 149 173 150 return pThis-> pIBelowNet->pfnSendBuf(pThis->pIBelowNet, pSgBuf, fOnWorkerThread);174 return pThis->CTX_SUFF(pIBelowNet)->pfnSendBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf, fOnWorkerThread); 151 175 } 152 176 … … 155 179 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit} 156 180 */ 157 static DECLCALLBACK(void) drvNetShaperUp_EndXmit(PPDMINETWORKUP pInterface)181 PDMBOTHCBDECL(void) drvNetShaperUp_EndXmit(PPDMINETWORKUP pInterface) 158 182 { 159 183 //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)); 163 187 else 164 RTCritSectLeave(&pThis->XmitLock);188 PDMCritSectLeave(&pThis->XmitLock); 165 189 } 166 190 … … 169 193 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode} 170 194 */ 171 static DECLCALLBACK(void) drvNetShaperUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)195 PDMBOTHCBDECL(void) drvNetShaperUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous) 172 196 { 173 197 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 180 205 /** 181 206 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged} 182 207 */ 183 static DECLCALLBACK(void) drv NetShaperUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)208 static DECLCALLBACK(void) drvR3NetShaperUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState) 184 209 { 185 210 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 } 191 215 192 216 /** 193 217 * @interface_method_impl{PDMINETWORKDOWN,pfnWaitReceiveAvail} 194 218 */ 195 static DECLCALLBACK(int) drv NetShaperDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)219 static DECLCALLBACK(int) drvR3NetShaperDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies) 196 220 { 197 221 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown); … … 203 227 * @interface_method_impl{PDMINETWORKDOWN,pfnReceive} 204 228 */ 205 static DECLCALLBACK(int) drv NetShaperDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb)229 static DECLCALLBACK(int) drvR3NetShaperDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb) 206 230 { 207 231 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown); … … 213 237 * @interface_method_impl{PDMINETWORKDOWN,pfnXmitPending} 214 238 */ 215 static DECLCALLBACK(void) drv NetShaperDown_XmitPending(PPDMINETWORKDOWN pInterface)239 static DECLCALLBACK(void) drvR3NetShaperDown_XmitPending(PPDMINETWORKDOWN pInterface) 216 240 { 217 241 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown); … … 229 253 * @thread EMT 230 254 */ 231 static DECLCALLBACK(int) drv NetShaperDownCfg_GetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)255 static DECLCALLBACK(int) drvR3NetShaperDownCfg_GetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac) 232 256 { 233 257 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig); … … 242 266 * @thread EMT 243 267 */ 244 static DECLCALLBACK(PDMNETWORKLINKSTATE) drv NetShaperDownCfg_GetLinkState(PPDMINETWORKCONFIG pInterface)268 static DECLCALLBACK(PDMNETWORKLINKSTATE) drvR3NetShaperDownCfg_GetLinkState(PPDMINETWORKCONFIG pInterface) 245 269 { 246 270 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig); … … 256 280 * @thread EMT 257 281 */ 258 static DECLCALLBACK(int) drv NetShaperDownCfg_SetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)282 static DECLCALLBACK(int) drvR3NetShaperDownCfg_SetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState) 259 283 { 260 284 PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkConfig); … … 264 288 265 289 /** 290 * @interface_method_impl{PDMIBASER0,pfnQueryInterface} 291 */ 292 static 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 */ 302 static DECLCALLBACK(RTRCPTR) drvR3NetShaperIBaseRC_QueryInterface(PPDMIBASERC pInterface, const char *pszIID) 303 { 304 return NIL_RTRCPTR; 305 } 306 307 /** 266 308 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 267 309 */ 268 static DECLCALLBACK(void *) drv NetShaperQueryInterface(PPDMIBASE pInterface, const char *pszIID)310 static DECLCALLBACK(void *) drvR3NetShaperIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID) 269 311 { 270 312 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface); 271 313 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER); 272 314 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); 274 318 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKDOWN, &pThis->INetworkDown); 275 319 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig); … … 281 325 * @interface_method_impl{PDMDRVREG,pfnDetach} 282 326 */ 283 static DECLCALLBACK(void) drv NetShaperDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)327 static DECLCALLBACK(void) drvR3NetShaperDetach(PPDMDRVINS pDrvIns, uint32_t fFlags) 284 328 { 285 329 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER); 286 330 287 331 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); 291 336 } 292 337 … … 295 340 * @interface_method_impl{PDMDRVREG,pfnAttach} 296 341 */ 297 static DECLCALLBACK(int) drv NetShaperAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)342 static DECLCALLBACK(int) drvR3NetShaperAttach(PPDMDRVINS pDrvIns, uint32_t fFlags) 298 343 { 299 344 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER); 300 345 LogFlow(("drvNetShaperAttach/#%#x: fFlags=%#x\n", pDrvIns->iInstance, fFlags)); 301 RTCritSectEnter(&pThis->XmitLock);346 PDMCritSectEnter(&pThis->XmitLock, VERR_IGNORED); 302 347 303 348 /* … … 309 354 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME) 310 355 { 311 pThis->pIBelowNet = NULL; 356 pThis->pIBelowNetR3 = NULL; 357 pThis->pIBelowNetR0 = NIL_RTR0PTR; 312 358 rc = VINF_SUCCESS; 313 359 } 314 360 else if (RT_SUCCESS(rc)) 315 361 { 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; 318 367 rc = VINF_SUCCESS; 368 } 319 369 else 320 370 { … … 326 376 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc)); 327 377 328 RTCritSectLeave(&pThis->XmitLock);378 PDMCritSectLeave(&pThis->XmitLock); 329 379 return VINF_SUCCESS; 330 380 } … … 334 384 * @interface_method_impl{PDMDRVREG,pfnDestruct} 335 385 */ 336 static DECLCALLBACK(void) drv NetShaperDestruct(PPDMDRVINS pDrvIns)386 static DECLCALLBACK(void) drvR3NetShaperDestruct(PPDMDRVINS pDrvIns) 337 387 { 338 388 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER); … … 341 391 PDMDrvHlpNetShaperDetach(pDrvIns, &pThis->Filter); 342 392 343 if ( RTCritSectIsInitialized(&pThis->XmitLock))344 RTCritSectDelete(&pThis->XmitLock);393 if (PDMCritSectIsInitialized(&pThis->XmitLock)) 394 PDMR3CritSectDelete(&pThis->XmitLock); 345 395 } 346 396 … … 350 400 * PDMDRVREG,pfnDestruct} 351 401 */ 352 static DECLCALLBACK(int) drv NetShaperConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)402 static DECLCALLBACK(int) drvR3NetShaperConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 353 403 { 354 404 PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER); … … 359 409 * Init the static parts. 360 410 */ 411 pThis->pDrvInsR3 = pDrvIns; 412 pThis->pDrvInsR0 = PDMDRVINS_2_R0PTR(pDrvIns); 361 413 /* IBase */ 362 pDrvIns->IBase.pfnQueryInterface = drvNetShaperQueryInterface; 414 pDrvIns->IBase.pfnQueryInterface = drvR3NetShaperIBase_QueryInterface; 415 pThis->IBaseR0.pfnQueryInterface = drvR3NetShaperIBaseR0_QueryInterface; 416 pThis->IBaseRC.pfnQueryInterface = drvR3NetShaperIBaseRC_QueryInterface; 363 417 /* 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); 371 432 /* INetworkDown */ 372 pThis->INetworkDown.pfnWaitReceiveAvail = drv NetShaperDown_WaitReceiveAvail;373 pThis->INetworkDown.pfnReceive = drv NetShaperDown_Receive;374 pThis->INetworkDown.pfnXmitPending = drv NetShaperDown_XmitPending;433 pThis->INetworkDown.pfnWaitReceiveAvail = drvR3NetShaperDown_WaitReceiveAvail; 434 pThis->INetworkDown.pfnReceive = drvR3NetShaperDown_Receive; 435 pThis->INetworkDown.pfnXmitPending = drvR3NetShaperDown_XmitPending; 375 436 /* INetworkConfig */ 376 pThis->INetworkConfig.pfnGetMac = drv NetShaperDownCfg_GetMac;377 pThis->INetworkConfig.pfnGetLinkState = drv NetShaperDownCfg_GetLinkState;378 pThis->INetworkConfig.pfnSetLinkState = drv NetShaperDownCfg_SetLinkState;437 pThis->INetworkConfig.pfnGetMac = drvR3NetShaperDownCfg_GetMac; 438 pThis->INetworkConfig.pfnGetLinkState = drvR3NetShaperDownCfg_GetLinkState; 439 pThis->INetworkConfig.pfnSetLinkState = drvR3NetShaperDownCfg_SetLinkState; 379 440 380 441 /* 381 442 * Create the locks. 382 443 */ 383 int rc = RTCritSectInit(&pThis->XmitLock);444 rc = PDMDrvHlpCritSectInit(pDrvIns, &pThis->XmitLock, RT_SRC_POS, "NetShaper"); 384 445 AssertRCReturn(rc, rc); 385 446 … … 439 500 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER 440 501 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME) 441 pThis->pIBelowNet = NULL; 502 { 503 pThis->pIBelowNetR3 = NULL; 504 pThis->pIBelowNetR0 = NIL_RTR0PTR; 505 } 442 506 else if (RT_SUCCESS(rc)) 443 507 { 444 pThis->pIBelowNet = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);445 if (!pThis->pIBelowNet )508 pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP); 509 if (!pThis->pIBelowNetR3) 446 510 { 447 511 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n")); 448 512 return VERR_PDM_MISSING_INTERFACE_BELOW; 449 513 } 514 PPDMIBASER0 pBaseR0 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0); 515 pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR; 450 516 } 451 517 else … … 484 550 "", 485 551 /* szR0Mod */ 486 " ",552 "VBoxDDR0.r0", 487 553 /* pszDescription */ 488 554 "Network Shaper Filter Driver", 489 555 /* fFlags */ 490 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT ,556 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DRVREG_FLAGS_R0, 491 557 /* fClass. */ 492 558 PDM_DRVREG_CLASS_NETWORK, … … 496 562 sizeof(DRVNETSHAPER), 497 563 /* pfnConstruct */ 498 drv NetShaperConstruct,564 drvR3NetShaperConstruct, 499 565 /* pfnDestruct */ 500 drv NetShaperDestruct,566 drvR3NetShaperDestruct, 501 567 /* pfnRelocate */ 502 568 NULL, … … 512 578 NULL, 513 579 /* pfnAttach */ 514 drv NetShaperAttach,580 drvR3NetShaperAttach, 515 581 /* pfnDetach */ 516 drv NetShaperDetach,582 drvR3NetShaperDetach, 517 583 /* pfnPowerOff */ 518 584 NULL, … … 522 588 PDM_DRVREG_VERSION 523 589 }; 524 590 #endif /* IN_RING3 */ -
trunk/src/VBox/VMM/Makefile.kmk
r41906 r42062 543 543 VMMAll/IEMAllAImplC.cpp 544 544 endif 545 ifdef VBOX_WITH_NETSHAPER 546 VMMR0_SOURCES += \ 547 VMMR0/PDMNetShaperR0.cpp 548 endif 545 549 VMMR0_SOURCES.amd64 = \ 546 550 VMMR0/VMMR0JmpA-amd64.asm -
trunk/src/VBox/VMM/VMMR3/PDMNetShaper.cpp
r41891 r42062 6 6 7 7 /* 8 * Copyright (C) 20 06-2012 Oracle Corporation8 * Copyright (C) 2011-2012 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 43 43 44 44 #include <VBox/vmm/pdmnetshaper.h> 45 #include <VBox/vmm/pdmnetshaperint.h> 45 46 46 47 … … 48 49 * Structures and Typedefs * 49 50 *******************************************************************************/ 50 51 /**52 * Bandwidth group instance data53 */54 typedef struct PDMNSBWGROUP55 {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;79 51 80 52 /** … … 157 129 pBwGroup->cbBucketSize = RT_MAX(PDM_NETSHAPER_MIN_BUCKET_SIZE, 158 130 cbTransferPerSecMax * PDM_NETSHAPER_MAX_LATENCY / 1000); 159 LogFlowFunc(("New rate limit is % dbytes 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", 160 132 pBwGroup->cbTransferPerSecMax, pBwGroup->cbBucketSize)); 161 133 } … … 163 135 static int pdmNsBwGroupCreate(PPDMNETSHAPER pShaper, const char *pcszBwGroup, uint64_t cbTransferPerSecMax) 164 136 { 165 LogFlowFunc(("pShaper=%#p pcszBwGroup=%#p{%s} cbTransferPerSecMax=% u\n",137 LogFlowFunc(("pShaper=%#p pcszBwGroup=%#p{%s} cbTransferPerSecMax=%llu\n", 166 138 pShaper, pcszBwGroup, pcszBwGroup, cbTransferPerSecMax)); 167 139 … … 174 146 if (!pBwGroup) 175 147 { 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); 179 150 if (RT_SUCCESS(rc)) 180 151 { 181 rc = RTCritSectInit(&pBwGroup->cs);152 rc = PDMR3CritSectInit(pShaper->pVM, &pBwGroup->cs, RT_SRC_POS, "BWGRP"); 182 153 if (RT_SUCCESS(rc)) 183 154 { … … 198 169 return VINF_SUCCESS; 199 170 } 200 RTCritSectDelete(&pBwGroup->cs);171 PDMR3CritSectDelete(&pBwGroup->cs); 201 172 } 202 MM R3HeapFree(pBwGroup);173 MMHyperFree(pShaper->pVM, pBwGroup); 203 174 } 204 175 else … … 215 186 { 216 187 Assert(pBwGroup->cRefs == 0); 217 if ( RTCritSectIsInitialized(&pBwGroup->cs))218 RTCritSectDelete(&pBwGroup->cs);188 if (PDMCritSectIsInitialized(&pBwGroup->cs)) 189 PDMR3CritSectDelete(&pBwGroup->cs); 219 190 } 220 191 … … 267 238 { 268 239 PPDMNSBWGROUP pBwGroup = pFilter->pBwGroupR3; 269 int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);240 int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc); 270 241 271 242 pFilter->pNext = pBwGroup->pFiltersHead; 272 243 pBwGroup->pFiltersHead = pFilter; 273 244 274 rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);245 rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc); 275 246 } 276 247 … … 286 257 AssertPtr(pBwGroup->pShaper); 287 258 Assert(RTCritSectIsOwner(&pBwGroup->pShaper->cs)); 288 int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);259 int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc); 289 260 290 261 if (pFilter == pBwGroup->pFiltersHead) … … 301 272 } 302 273 303 rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);274 rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc); 304 275 } 305 276 … … 333 304 { 334 305 pBwGroupOld = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, pBwGroupNew, PPDMNSBWGROUP); 306 ASMAtomicWritePtr(&pFilter->pBwGroupR0, MMHyperR3ToR0(pVM, pBwGroupNew)); 335 307 if (pBwGroupOld) 336 308 pdmNsBwGroupUnref(pBwGroupOld); … … 367 339 VMMR3DECL(bool) PDMR3NsAllocateBandwidth(PPDMNSFILTER pFilter, uint32_t cbTransfer) 368 340 { 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); 402 342 } 403 343 … … 413 353 if (pBwGroup) 414 354 { 415 rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc);355 rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc); 416 356 pdmNsBwGroupSetLimit(pBwGroup, cbTransferPerSecMax); 417 357 /* Drop extra tokens */ 418 358 if (pBwGroup->cbTokensLast > pBwGroup->cbBucketSize) 419 359 pBwGroup->cbTokensLast = pBwGroup->cbBucketSize; 420 rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc);360 rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc); 421 361 } 422 362 rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc); … … 486 426 pBwGroup = pBwGroup->pNext; 487 427 pdmNsBwGroupTerminate(pFree); 488 MM R3HeapFree(pFree);428 MMHyperFree(pVM, pFree); 489 429 } 490 430
Note:
See TracChangeset
for help on using the changeset viewer.