/** * Adjusts the maximum rate for the bandwidth group. * * @returns VBox status code. * @param pUVM The user mode VM handle. * @param pszBwGroup Name of the bandwidth group to attach to. * @param cbPerSecMax Maximum number of bytes per second to be transmitted. */ VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PUVM pUVM, const char *pszBwGroup, uint64_t cbPerSecMax) { UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper; LOCK_NETSHAPER_RETURN(pShaper); int rc; PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pszBwGroup); if (pBwGroup) { rc = PDMCritSectEnter(&pBwGroup->Lock, VERR_SEM_BUSY); AssertRC(rc); if (RT_SUCCESS(rc)) { pdmNsBwGroupSetLimit(pBwGroup, cbPerSecMax); /* Drop extra tokens */ if (pBwGroup->cbTokensLast > pBwGroup->cbBucket) pBwGroup->cbTokensLast = pBwGroup->cbBucket; int rc2 = PDMCritSectLeave(&pBwGroup->Lock); AssertRC(rc2); } } else rc = VERR_NOT_FOUND; UNLOCK_NETSHAPER(pShaper); return rc; }
static int pdmNsBwGroupCreate(PPDMNETSHAPER pShaper, const char *pcszBwGroup, uint64_t cbTransferPerSecMax) { LogFlowFunc(("pShaper=%#p pcszBwGroup=%#p{%s} cbTransferPerSecMax=%u\n", pShaper, pcszBwGroup, pcszBwGroup, cbTransferPerSecMax)); AssertPtrReturn(pShaper, VERR_INVALID_POINTER); AssertPtrReturn(pcszBwGroup, VERR_INVALID_POINTER); AssertReturn(*pcszBwGroup != '\0', VERR_INVALID_PARAMETER); int rc; PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pcszBwGroup); if (!pBwGroup) { rc = MMR3HeapAllocZEx(pShaper->pVM, MM_TAG_PDM_NET_SHAPER, sizeof(PDMNSBWGROUP), (void **)&pBwGroup); if (RT_SUCCESS(rc)) { rc = RTCritSectInit(&pBwGroup->cs); if (RT_SUCCESS(rc)) { pBwGroup->pszName = RTStrDup(pcszBwGroup); if (pBwGroup->pszName) { pBwGroup->pShaper = pShaper; pBwGroup->cRefs = 0; pdmNsBwGroupSetLimit(pBwGroup, cbTransferPerSecMax); ; pBwGroup->cbTokensLast = pBwGroup->cbBucketSize; pBwGroup->tsUpdatedLast = RTTimeSystemNanoTS(); LogFlowFunc(("pcszBwGroup={%s} cbBucketSize=%u\n", pcszBwGroup, pBwGroup->cbBucketSize)); pdmNsBwGroupLink(pBwGroup); return VINF_SUCCESS; } RTCritSectDelete(&pBwGroup->cs); } MMR3HeapFree(pBwGroup); } else rc = VERR_NO_MEMORY; } else rc = VERR_ALREADY_EXISTS; LogFlowFunc(("returns rc=%Rrc\n", rc)); return rc; }
static int pdmNsBwGroupCreate(PPDMNETSHAPER pShaper, const char *pszBwGroup, uint64_t cbPerSecMax) { LogFlow(("pdmNsBwGroupCreate: pShaper=%#p pszBwGroup=%#p{%s} cbPerSecMax=%llu\n", pShaper, pszBwGroup, pszBwGroup, cbPerSecMax)); AssertPtrReturn(pShaper, VERR_INVALID_POINTER); AssertPtrReturn(pszBwGroup, VERR_INVALID_POINTER); AssertReturn(*pszBwGroup != '\0', VERR_INVALID_PARAMETER); int rc; PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pszBwGroup); if (!pBwGroup) { rc = MMHyperAlloc(pShaper->pVM, sizeof(PDMNSBWGROUP), 64, MM_TAG_PDM_NET_SHAPER, (void **)&pBwGroup); if (RT_SUCCESS(rc)) { rc = PDMR3CritSectInit(pShaper->pVM, &pBwGroup->Lock, RT_SRC_POS, "BWGRP-%s", pszBwGroup); if (RT_SUCCESS(rc)) { pBwGroup->pszNameR3 = MMR3HeapStrDup(pShaper->pVM, MM_TAG_PDM_NET_SHAPER, pszBwGroup); if (pBwGroup->pszNameR3) { pBwGroup->pShaperR3 = pShaper; pBwGroup->cRefs = 0; pdmNsBwGroupSetLimit(pBwGroup, cbPerSecMax); pBwGroup->cbTokensLast = pBwGroup->cbBucket; pBwGroup->tsUpdatedLast = RTTimeSystemNanoTS(); LogFlowFunc(("pszBwGroup={%s} cbBucket=%u\n", pszBwGroup, pBwGroup->cbBucket)); pdmNsBwGroupLink(pBwGroup); return VINF_SUCCESS; } PDMR3CritSectDelete(&pBwGroup->Lock); } MMHyperFree(pShaper->pVM, pBwGroup); } else rc = VERR_NO_MEMORY; } else rc = VERR_ALREADY_EXISTS; LogFlowFunc(("returns rc=%Rrc\n", rc)); return rc; }
VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PVM pVM, const char *pcszBwGroup, uint64_t cbTransferPerSecMax) { PUVM pUVM = pVM->pUVM; PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper; int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc); if (RT_SUCCESS(rc)) { PPDMNSBWGROUP pBwGroup = pdmNsBwGroupFindById(pShaper, pcszBwGroup); if (pBwGroup) { rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc); pdmNsBwGroupSetLimit(pBwGroup, cbTransferPerSecMax); /* Drop extra tokens */ if (pBwGroup->cbTokensLast > pBwGroup->cbBucketSize) pBwGroup->cbTokensLast = pBwGroup->cbBucketSize; rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc); } rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc); } return rc; }