/**
 * 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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 4
0
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;
}