VirtualBox

Changeset 42932 in vbox for trunk/src


Ignore:
Timestamp:
Aug 23, 2012 8:57:53 AM (12 years ago)
Author:
vboxsync
Message:

Network/e1000: Tx delay timer, ITR fix, more stats (#4807)

File:
1 edited

Legend:

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

    r41808 r42932  
    5151 * Ethernet Controllers Software Developer’s Manual").
    5252 */
    53 #define E1K_ITR_ENABLED
     53//#define E1K_ITR_ENABLED
     54/*
     55 * E1K_TX_DELAY aims to improve guest-host transfer rate for TCP streams by
     56 * preventing packets to be sent immediately. It allows to send several
     57 * packets in a batch reducing the number of acknowledgments. Note that it
     58 * effectively disables R0 TX path, forcing sending in R3.
     59 */
     60#define E1K_TX_DELAY 150
    5461/*
    5562 * E1K_USE_TX_TIMERS aims to reduce the number of generated TX interrupts if a
     
    126133#include <iprt/semaphore.h>
    127134#include <iprt/string.h>
     135#include <iprt/time.h>
    128136#include <iprt/uuid.h>
    129137#include <VBox/vmm/pdmdev.h>
     
    10001008    PTMTIMERR3              pTIDTimerR3;  /**< Transmit Interrupt Delay Timer - R3. */
    10011009    PTMTIMERR3              pTADTimerR3;   /**< Transmit Absolute Delay Timer - R3. */
     1010    PTMTIMERR3              pTXDTimerR3;            /**< Transmit Delay Timer - R3. */
    10021011    PTMTIMERR3              pIntTimerR3;            /**< Late Interrupt Timer - R3. */
    10031012    PTMTIMERR3              pLUTimerR3;               /**< Link Up(/Restore) Timer. */
     
    10131022    PTMTIMERR0              pTIDTimerR0;  /**< Transmit Interrupt Delay Timer - R0. */
    10141023    PTMTIMERR0              pTADTimerR0;   /**< Transmit Absolute Delay Timer - R0. */
     1024    PTMTIMERR0              pTXDTimerR0;            /**< Transmit Delay Timer - R0. */
    10151025    PTMTIMERR0              pIntTimerR0;            /**< Late Interrupt Timer - R0. */
    10161026    PTMTIMERR0              pLUTimerR0;          /**< Link Up(/Restore) Timer - R0. */
     
    10261036    PTMTIMERRC              pTIDTimerRC;  /**< Transmit Interrupt Delay Timer - RC. */
    10271037    PTMTIMERRC              pTADTimerRC;   /**< Transmit Absolute Delay Timer - RC. */
     1038    PTMTIMERRC              pTXDTimerRC;            /**< Transmit Delay Timer - RC. */
    10281039    PTMTIMERRC              pIntTimerRC;            /**< Late Interrupt Timer - RC. */
    10291040    PTMTIMERRC              pLUTimerRC;          /**< Link Up(/Restore) Timer - RC. */
     
    10321043    RTRCPTR                 RCPtrAlignment;
    10331044
    1034 #if HC_ARCH_BITS == 32
     1045//#if HC_ARCH_BITS == 32
    10351046    uint32_t                Alignment1;
    1036 #endif
     1047//#endif
    10371048    PDMCRITSECT cs;                  /**< Critical section - what is it protecting? */
    10381049    PDMCRITSECT csRx;                                     /**< RX Critical section. */
     
    12031214#ifdef E1K_INT_STATS
    12041215    /* Internal stats */
     1216    uint64_t    u64ArmedAt;
     1217    uint64_t    uStatMaxTxDelay;
    12051218    uint32_t    uStatInt;
    12061219    uint32_t    uStatIntTry;
     
    12221235    uint32_t    uStatTxNoRS;
    12231236    uint32_t    uStatTxIDE;
     1237    uint32_t    uStatTxDelayed;
     1238    uint32_t    uStatTxDelayExp;
    12241239    uint32_t    uStatTAD;
    12251240    uint32_t    uStatTID;
     
    12311246    uint32_t    uStatDescDat;
    12321247    uint32_t    uStatDescLeg;
     1248    uint32_t    uStatTx1514;
     1249    uint32_t    uStatTx2962;
     1250    uint32_t    uStatTx4410;
     1251    uint32_t    uStatTx5858;
     1252    uint32_t    uStatTx7306;
     1253    uint32_t    uStatTx8754;
     1254    uint32_t    uStatTx16384;
     1255    uint32_t    uStatTx32768;
     1256    uint32_t    uStatTxLarge;
     1257    uint32_t    uStatAlign;
    12331258#endif /* E1K_INT_STATS */
    12341259};
     
    14791504    if (pTimer == pState->CTX_SUFF(pIntTimer))
    14801505        return "Int";
     1506    if (pTimer == pState->CTX_SUFF(pTXDTimer))
     1507        return "TXD";
    14811508    return "unknown";
    14821509}
     
    14981525    E1kLog2(("%s Arming %s timer to fire in %d usec...\n",
    14991526             INSTANCE(pState), e1kGetTimerName(pState, pTimer), uExpireIn));
    1500     TMTimerSet(pTimer, TMTimerFromMicro(pTimer, uExpireIn) +
    1501             TMTimerGet(pTimer));
     1527    TMTimerSetMicro(pTimer, uExpireIn);
    15021528}
    15031529
     
    15271553
    15281554#ifndef E1K_WITH_TX_CS
    1529 #define e1kCsTxEnter(ps, rc) VINF_SUCCESS
    1530 #define e1kCsTxLeave(ps) do { } while (0)
     1555# define e1kCsTxEnter(ps, rc) VINF_SUCCESS
     1556# define e1kCsTxLeave(ps) do { } while (0)
     1557# define e1kCsIsOwner(cs) true
    15311558#else /* E1K_WITH_TX_CS */
    15321559# define e1kCsTxEnter(ps, rc) PDMCritSectEnter(&ps->csTx, rc)
    15331560# define e1kCsTxLeave(ps) PDMCritSectLeave(&ps->csTx)
     1561# define e1kCsIsOwner(cs) PDMCritSectIsOwner(cs)
    15341562#endif /* E1K_WITH_TX_CS */
    15351563
     
    18331861            E1kLog2(("%s e1kRaiseInterrupt: tstamp - pState->u64AckedAt = %d, ITR * 256 = %d\n",
    18341862                        INSTANCE(pState), (uint32_t)(tstamp - pState->u64AckedAt), ITR * 256));
    1835             if (!!ITR && pState->fIntMaskUsed && tstamp - pState->u64AckedAt < ITR * 256)
     1863            //if (!!ITR && pState->fIntMaskUsed && tstamp - pState->u64AckedAt < ITR * 256)
     1864            if (!!ITR && tstamp - pState->u64AckedAt < ITR * 256 && !(ICR & ICR_RXT0))
    18361865            {
    18371866                E1K_INC_ISTAT_CNT(pState->uStatIntEarly);
     
    29913020
    29923021#ifdef IN_RING3
     3022#ifdef E1K_TX_DELAY
     3023
     3024/**
     3025 * Transmit Delay Timer handler.
     3026 *
     3027 * @remarks We only get here when the timer expires.
     3028 *
     3029 * @param   pDevIns     Pointer to device instance structure.
     3030 * @param   pTimer      Pointer to the timer.
     3031 * @param   pvUser      NULL.
     3032 * @thread  EMT
     3033 */
     3034static DECLCALLBACK(void) e1kTxDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     3035{
     3036    E1KSTATE *pState = (E1KSTATE *)pvUser;
     3037    Assert(e1kCsIsOwner(&pState->csTx));
     3038
     3039    E1K_INC_ISTAT_CNT(pState->uStatTxDelayExp);
     3040#ifdef E1K_INT_STATS
     3041    uint64_t u64Elapsed = RTTimeNanoTS() - pState->u64ArmedAt;
     3042    if (u64Elapsed > pState->uStatMaxTxDelay)
     3043        pState->uStatMaxTxDelay = u64Elapsed;
     3044#endif /* E1K_INT_STATS */
     3045    int rc = e1kXmitPending(pState, false /*fOnWorkerThread*/);
     3046    AssertMsg(RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN, ("%Rrc\n", rc));
     3047}
     3048#endif /* E1K_TX_DELAY */
     3049
    29933050#ifdef E1K_USE_TX_TIMERS
    29943051
     
    35793636    if (cbFrame > 70) /* unqualified guess */
    35803637        pState->led.Asserted.s.fWriting = pState->led.Actual.s.fWriting = 1;
     3638
     3639#ifdef E1K_INT_STATS
     3640    if (cbFrame <= 1514)
     3641        E1K_INC_ISTAT_CNT(pState->uStatTx1514);
     3642    else if (cbFrame <= 2962)
     3643        E1K_INC_ISTAT_CNT(pState->uStatTx2962);
     3644    else if (cbFrame <= 4410)
     3645        E1K_INC_ISTAT_CNT(pState->uStatTx4410);
     3646    else if (cbFrame <= 5858)
     3647        E1K_INC_ISTAT_CNT(pState->uStatTx5858);
     3648    else if (cbFrame <= 7306)
     3649        E1K_INC_ISTAT_CNT(pState->uStatTx7306);
     3650    else if (cbFrame <= 8754)
     3651        E1K_INC_ISTAT_CNT(pState->uStatTx8754);
     3652    else if (cbFrame <= 16384)
     3653        E1K_INC_ISTAT_CNT(pState->uStatTx16384);
     3654    else if (cbFrame <= 32768)
     3655        E1K_INC_ISTAT_CNT(pState->uStatTx32768);
     3656    else
     3657        E1K_INC_ISTAT_CNT(pState->uStatTxLarge);
     3658#endif /* E1K_INT_STATS */
    35813659
    35823660    /* Add VLAN tag */
     
    48074885     * Grab the xmit lock of the driver as well as the E1K device state.
    48084886     */
    4809     PPDMINETWORKUP pDrv = pState->CTX_SUFF(pDrv);
    4810     if (pDrv)
    4811     {
    4812         rc = pDrv->pfnBeginXmit(pDrv, fOnWorkerThread);
    4813         if (RT_FAILURE(rc))
    4814             return rc;
    4815     }
    48164887    rc = e1kCsTxEnter(pState, VERR_SEM_BUSY);
    48174888    if (RT_LIKELY(rc == VINF_SUCCESS))
    48184889    {
     4890        PPDMINETWORKUP pDrv = pState->CTX_SUFF(pDrv);
     4891        if (pDrv)
     4892        {
     4893            rc = pDrv->pfnBeginXmit(pDrv, fOnWorkerThread);
     4894            if (RT_FAILURE(rc))
     4895            {
     4896                e1kCsTxLeave(pState);
     4897                return rc;
     4898            }
     4899        }
    48194900        /*
    48204901         * Process all pending descriptors.
     
    48474928        /// @todo: uncomment: pState->uStatIntTXQE++;
    48484929        /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE);
     4930        /*
     4931         * Release the lock.
     4932         */
     4933        if (pDrv)
     4934            pDrv->pfnEndXmit(pDrv);
    48494935        e1kCsTxLeave(pState);
    48504936    }
    48514937
    4852     /*
    4853      * Release the lock.
    4854      */
    4855     if (pDrv)
    4856         pDrv->pfnEndXmit(pDrv);
    48574938    return rc;
    48584939}
     
    50675148        /* Transmit pending packets if possible, defer it if we cannot do it
    50685149           in the current context. */
     5150#ifdef E1K_TX_DELAY
     5151        rc = e1kCsTxEnter(pState, VERR_SEM_BUSY);
     5152        if (RT_LIKELY(rc == VINF_SUCCESS))
     5153        {
     5154            if (!TMTimerIsActive(pState->CTX_SUFF(pTXDTimer)))
     5155            {
     5156#ifdef E1K_INT_STATS
     5157                pState->u64ArmedAt = RTTimeNanoTS();
     5158#endif /* E1K_INT_STATS */
     5159                e1kArmTimer(pState, pState->CTX_SUFF(pTXDTimer), E1K_TX_DELAY);
     5160            }
     5161            E1K_INC_ISTAT_CNT(pState->uStatTxDelayed);
     5162            e1kCsTxLeave(pState);
     5163            return rc;
     5164        }
     5165        /* We failed to enter the TX critical section -- transmit as usual. */
     5166#endif /* E1K_TX_DELAY */
    50695167# ifndef IN_RING3
    50705168        if (!pState->CTX_SUFF(pDrv))
     
    56975795    LogRel(("%s Interrupts by TXQE: %d\n", INSTANCE(pState), pState->uStatIntTXQE));
    56985796    LogRel(("%s TX int delay asked: %d\n", INSTANCE(pState), pState->uStatTxIDE));
     5797    LogRel(("%s TX delayed:         %d\n", INSTANCE(pState), pState->uStatTxDelayed));
     5798    LogRel(("%s TX delay expired:   %d\n", INSTANCE(pState), pState->uStatTxDelayExp));
    56995799    LogRel(("%s TX no report asked: %d\n", INSTANCE(pState), pState->uStatTxNoRS));
    57005800    LogRel(("%s TX abs timer expd : %d\n", INSTANCE(pState), pState->uStatTAD));
     
    57075807    LogRel(("%s Received frames   : %d\n", INSTANCE(pState), pState->uStatRxFrm));
    57085808    LogRel(("%s Transmitted frames: %d\n", INSTANCE(pState), pState->uStatTxFrm));
     5809    LogRel(("%s TX frames up to 1514: %d\n", INSTANCE(pState), pState->uStatTx1514));
     5810    LogRel(("%s TX frames up to 2962: %d\n", INSTANCE(pState), pState->uStatTx2962));
     5811    LogRel(("%s TX frames up to 4410: %d\n", INSTANCE(pState), pState->uStatTx4410));
     5812    LogRel(("%s TX frames up to 5858: %d\n", INSTANCE(pState), pState->uStatTx5858));
     5813    LogRel(("%s TX frames up to 7306: %d\n", INSTANCE(pState), pState->uStatTx7306));
     5814    LogRel(("%s TX frames up to 8754: %d\n", INSTANCE(pState), pState->uStatTx8754));
     5815    LogRel(("%s TX frames up to 16384: %d\n", INSTANCE(pState), pState->uStatTx16384));
     5816    LogRel(("%s TX frames up to 32768: %d\n", INSTANCE(pState), pState->uStatTx32768));
     5817    LogRel(("%s Larger TX frames    : %d\n", INSTANCE(pState), pState->uStatTxLarge));
     5818    LogRel(("%s Max TX Delay        : %lld\n", INSTANCE(pState), pState->uStatMaxTxDelay));
    57095819#endif /* E1K_INT_STATS */
    57105820}
     
    62786388    //pState->fLocked = true;
    62796389    /* 2) Cancel all timers */
     6390#ifdef E1K_TX_DELAY
     6391    e1kCancelTimer(pState, pState->CTX_SUFF(pTXDTimer));
     6392#endif /* E1K_TX_DELAY */
    62806393#ifdef E1K_USE_TX_TIMERS
    62816394    e1kCancelTimer(pState, pState->CTX_SUFF(pTIDTimer));
     
    66526765{
    66536766    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     6767    e1kCancelTimer(pState, pState->CTX_SUFF(pTXDTimer));
    66546768    e1kCancelTimer(pState, pState->CTX_SUFF(pIntTimer));
    66556769    e1kCancelTimer(pState, pState->CTX_SUFF(pLUTimer));
     
    67066820# endif /* E1K_NO_TAD */
    67076821#endif /* E1K_USE_TX_TIMERS */
     6822#ifdef E1K_TX_DELAY
     6823    pState->pTXDTimerRC   = TMTimerRCPtr(pState->pTXDTimerR3);
     6824#endif /* E1K_TX_DELAY */
    67086825    pState->pIntTimerRC   = TMTimerRCPtr(pState->pIntTimerR3);
    67096826    pState->pLUTimerRC    = TMTimerRCPtr(pState->pLUTimerR3);
     
    69397056    pHlp->pfnPrintf(pHlp, "Interrupts by TXQE: %d\n", pState->uStatIntTXQE);
    69407057    pHlp->pfnPrintf(pHlp, "TX int delay asked: %d\n", pState->uStatTxIDE);
     7058    pHlp->pfnPrintf(pHlp, "TX delayed:         %d\n", pState->uStatTxDelayed);
     7059    pHlp->pfnPrintf(pHlp, "TX delayed expired: %d\n", pState->uStatTxDelayExp);
    69417060    pHlp->pfnPrintf(pHlp, "TX no report asked: %d\n", pState->uStatTxNoRS);
    69427061    pHlp->pfnPrintf(pHlp, "TX abs timer expd : %d\n", pState->uStatTAD);
     
    69497068    pHlp->pfnPrintf(pHlp, "Received frames   : %d\n", pState->uStatRxFrm);
    69507069    pHlp->pfnPrintf(pHlp, "Transmitted frames: %d\n", pState->uStatTxFrm);
     7070    pHlp->pfnPrintf(pHlp, "TX frames up to 1514: %d\n", pState->uStatTx1514);
     7071    pHlp->pfnPrintf(pHlp, "TX frames up to 2962: %d\n", pState->uStatTx2962);
     7072    pHlp->pfnPrintf(pHlp, "TX frames up to 4410: %d\n", pState->uStatTx4410);
     7073    pHlp->pfnPrintf(pHlp, "TX frames up to 5858: %d\n", pState->uStatTx5858);
     7074    pHlp->pfnPrintf(pHlp, "TX frames up to 7306: %d\n", pState->uStatTx7306);
     7075    pHlp->pfnPrintf(pHlp, "TX frames up to 8754: %d\n", pState->uStatTx8754);
     7076    pHlp->pfnPrintf(pHlp, "TX frames up to 16384: %d\n", pState->uStatTx16384);
     7077    pHlp->pfnPrintf(pHlp, "TX frames up to 32768: %d\n", pState->uStatTx32768);
     7078    pHlp->pfnPrintf(pHlp, "Larger TX frames    : %d\n", pState->uStatTxLarge);
    69517079#endif /* E1K_INT_STATS */
    69527080
     
    71397267    }
    71407268
    7141     E1kLog(("%s Chip=%s LinkUpDelay=%ums\n", INSTANCE(pState),
    7142             g_Chips[pState->eChip].pcszName, pState->cMsLinkUpDelay));
     7269    E1kLog(("%s Chip=%s LinkUpDelay=%ums EthernetCRC=%s\n", INSTANCE(pState),
     7270            g_Chips[pState->eChip].pcszName, pState->cMsLinkUpDelay,
     7271            pState->fEthernetCRC ? "on" : "off"));
    71437272
    71447273    /* Initialize state structure */
     
    71757304    pState->uStatTxNoRS = 0;
    71767305    pState->uStatTxIDE = 0;
     7306    pState->uStatTxDelayed = 0;
     7307    pState->uStatTxDelayExp = 0;
    71777308    pState->uStatTAD = 0;
    71787309    pState->uStatTID = 0;
     
    71847315    pState->uStatDescDat = 0;
    71857316    pState->uStatDescLeg = 0;
     7317    pState->uStatTx1514 = 0;
     7318    pState->uStatTx2962 = 0;
     7319    pState->uStatTx4410 = 0;
     7320    pState->uStatTx5858 = 0;
     7321    pState->uStatTx7306 = 0;
     7322    pState->uStatTx8754 = 0;
     7323    pState->uStatTx16384 = 0;
     7324    pState->uStatTx32768 = 0;
     7325    pState->uStatTxLarge = 0;
     7326    pState->uStatMaxTxDelay = 0;
    71867327#endif /* E1K_INT_STATS */
    71877328
     
    72747415    pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
    72757416    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     7417
     7418#ifdef E1K_TX_DELAY
     7419    /* Create Transmit Delay Timer */
     7420    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxDelayTimer, pState,
     7421                                TMTIMER_FLAGS_NO_CRIT_SECT,
     7422                                "E1000 Transmit Delay Timer", &pState->pTXDTimerR3);
     7423    if (RT_FAILURE(rc))
     7424        return rc;
     7425    pState->pTXDTimerR0 = TMTimerR0Ptr(pState->pTXDTimerR3);
     7426    pState->pTXDTimerRC = TMTimerRCPtr(pState->pTXDTimerR3);
     7427    TMR3TimerSetCritSect(pState->pTXDTimerR3, &pState->csTx);
     7428#endif /* E1K_TX_DELAY */
    72767429
    72777430#ifdef E1K_USE_TX_TIMERS
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