VirtualBox

Changeset 25830 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Jan 14, 2010 3:06:13 PM (15 years ago)
Author:
vboxsync
Message:

#3987: Virtio minor cs optimizations + timer stats.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevVirtioNet.cpp

    r25728 r25830  
    140140    /**< Transmit Delay Timer - GC. */
    141141    PTMTIMERRC              pTxTimerRC;
     142
    142143#if HC_ARCH_BITS == 64
    143144    uint32_t    padding2;
    144145#endif
    145146
     147    uint32_t   u32i;
     148    uint32_t   u32AvgDiff;
     149    uint32_t   u32MinDiff;
     150    uint32_t   u32MaxDiff;
     151    uint64_t   u64NanoTS;
     152
    146153#endif /* VNET_TX_DELAY */
     154    /** Indicates transmission in progress -- only one thread is allowed. */
     155    uint32_t                uIsTransmitting;
    147156
    148157    /** PCI config area holding MAC address as well as TBD. */
     
    170179    uint8_t                 aVlanFilter[VNET_MAX_VID / sizeof(uint8_t)];
    171180
    172 #if HC_ARCH_BITS == 64
     181#if HC_ARCH_BITS != 64
    173182    uint32_t    padding3;
    174183#endif
     
    266275    // PDMCritSectLeave(&pState->csRx);
    267276}
     277
     278/**
     279 * Dump a packet to debug log.
     280 *
     281 * @param   pState      The device state structure.
     282 * @param   cpPacket    The packet.
     283 * @param   cb          The size of the packet.
     284 * @param   cszText     A string denoting direction of packet transfer.
     285 */
     286DECLINLINE(void) vnetPacketDump(PVNETSTATE pState, const uint8_t *cpPacket, size_t cb, const char *cszText)
     287{
     288#ifdef DEBUG
     289    Log(("%s %s packet #%d (%d bytes):\n",
     290         INSTANCE(pState), cszText, ++pState->u32PktNo, cb));
     291    //Log3(("%.*Rhxd\n", cb, cpPacket));
     292#endif
     293}
     294
    268295
    269296
     
    354381    memset(pState->aMacFilter,  0, VNET_MAC_FILTER_LEN * sizeof(RTMAC));
    355382    memset(pState->aVlanFilter, 0, sizeof(pState->aVlanFilter));
     383    pState->uIsTransmitting   = 0;
    356384}
    357385
     
    650678    hdr.u8GSOType = VNETHDR_GSO_NONE;
    651679
     680    vnetPacketDump(pState, (const uint8_t*)pvBuf, cb, "<-- Incoming");
     681
    652682    unsigned int uOffset = 0;
    653683    for (unsigned int nElem = 0; uOffset < cb; nElem++)
     
    812842static DECLCALLBACK(void) vnetTransmitPendingPackets(PVNETSTATE pState, PVQUEUE pQueue)
    813843{
     844    /*
     845     * Only one thread is allowed to transmit at a time, others should skip
     846     * transmission as the packets will be picked up by the transmitting
     847     * thread.
     848     */
     849    if (!ASMAtomicCmpXchgU32(&pState->uIsTransmitting, 1, 0))
     850        return;
     851
    814852    if ((pState->VPCI.uStatus & VPCI_STATUS_DRV_OK) == 0)
    815853    {
     
    818856        return;
    819857    }
     858
     859    Log3(("%s vnetTransmitPendingPackets: About to trasmit %d pending packets\n", INSTANCE(pState),
     860          vringReadAvailIndex(&pState->VPCI, &pState->pTxQueue->VRing) - pState->pTxQueue->uNextAvailIndex));
    820861
    821862    vpciSetWriteLed(&pState->VPCI, true);
     
    849890            if (pState->pDrv)
    850891            {
     892                vnetPacketDump(pState, pState->pTxBuf, uOffset, "--> Outgoing");
     893
    851894                STAM_PROFILE_START(&pState->StatTransmitSend, a);
    852895                int rc = pState->pDrv->pfnSend(pState->pDrv, pState->pTxBuf, uOffset);
     
    860903    }
    861904    vpciSetWriteLed(&pState->VPCI, false);
     905
     906    ASMAtomicWriteU32(&pState->uIsTransmitting, 0);
    862907}
    863908
     
    873918              "re-enable notification and flush TX queue\n", INSTANCE(pState)));
    874919        vnetTransmitPendingPackets(pState, pQueue);
    875         vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true);
     920        if (RT_FAILURE(vnetCsEnter(pState, VERR_SEM_BUSY)))
     921            LogRel(("vnetQueueTransmit: Failed to enter critical section!/n"));
     922        else
     923        {
     924            vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true);
     925            vnetCsLeave(pState);
     926        }
    876927    }
    877928    else
    878929    {
    879         vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, false);
    880         TMTimerSetMicro(pState->CTX_SUFF(pTxTimer), VNET_TX_DELAY);
     930        if (RT_FAILURE(vnetCsEnter(pState, VERR_SEM_BUSY)))
     931            LogRel(("vnetQueueTransmit: Failed to enter critical section!/n"));
     932        else
     933        {
     934            vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, false);
     935            TMTimerSetMicro(pState->CTX_SUFF(pTxTimer), VNET_TX_DELAY);
     936            pState->u64NanoTS = RTTimeNanoTS();
     937            vnetCsLeave(pState);
     938        }
    881939    }
    882940}
     
    896954    VNETSTATE *pState = (VNETSTATE*)pvUser;
    897955
    898     int rc = vnetCsEnter(pState, VERR_SEM_BUSY);
    899     if (RT_UNLIKELY(rc != VINF_SUCCESS))
     956    uint32_t u32MicroDiff = (uint32_t)((RTTimeNanoTS() - pState->u64NanoTS)/1000);
     957    if (u32MicroDiff < pState->u32MinDiff)
     958        pState->u32MinDiff = u32MicroDiff;
     959    if (u32MicroDiff > pState->u32MaxDiff)
     960        pState->u32MaxDiff = u32MicroDiff;
     961    pState->u32AvgDiff = (pState->u32AvgDiff * pState->u32i + u32MicroDiff) / (pState->u32i + 1);
     962    pState->u32i++;
     963    Log3(("vnetTxTimer: Expired, diff %9d usec, avg %9d usec, min %9d usec, max %9d usec\n",
     964            u32MicroDiff, pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
     965
     966//    Log3(("%s vnetTxTimer: Expired\n", INSTANCE(pState)));
     967    vnetTransmitPendingPackets(pState, pState->pTxQueue);
     968    if (RT_FAILURE(vnetCsEnter(pState, VERR_SEM_BUSY)))
     969    {
     970        LogRel(("vnetTxTimer: Failed to enter critical section!/n"));
    900971        return;
     972    }
    901973    vringSetNotification(&pState->VPCI, &pState->pTxQueue->VRing, true);
    902     Log3(("%s vnetTxTimer: Expired, %d packets pending\n", INSTANCE(pState),
    903           vringReadAvailIndex(&pState->VPCI, &pState->pTxQueue->VRing) - pState->pTxQueue->uNextAvailIndex));
    904     vnetTransmitPendingPackets(pState, pState->pTxQueue);
    905974    vnetCsLeave(pState);
    906975}
     
    14861555    pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
    14871556    pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
     1557
     1558    pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0;
     1559    pState->u32MinDiff = ~0;
    14881560#endif /* VNET_TX_DELAY */
    14891561
     
    15441616    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
    15451617
     1618    LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n",
     1619            pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
    15461620    Log(("%s Destroying instance\n", INSTANCE(pState)));
    15471621    if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
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