VirtualBox

Changeset 41029 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Apr 23, 2012 6:25:08 PM (13 years ago)
Author:
vboxsync
Message:

E1000: Fixed an infinite loop in R0, re-enabled TX descriptor cache (#5582)

File:
1 edited

Legend:

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

    r40998 r41029  
    8888 * to allocating their buffers (see #5582).
    8989 */
    90 //#define E1K_WITH_TXD_CACHE 1
     90#define E1K_WITH_TXD_CACHE 1
    9191/* End of Options ************************************************************/
    9292
     
    9898 * TSE packet.
    9999 */
    100 #define E1K_TXD_CACHE_SIZE 16u
     100#define E1K_TXD_CACHE_SIZE 18u
    101101#endif /* E1K_WITH_TXD_CACHE */
    102102
     
    132132#  define E1kLog2(a)              LogRel(a)
    133133#  define E1kLog3(a)              LogRel(a)
     134#  define E1kLogX(a)              LogRel(a)
    134135//#  define E1kLog3(a)              do {} while (0)
    135136# else
     
    137138#  define E1kLog2(a)              do {} while (0)
    138139#  define E1kLog3(a)              do {} while (0)
     140#  define E1kLogX(a)              do {} while (0)
    139141# endif
    140142#else
     
    142144#  define E1kLog2(a)              Log2(a)
    143145#  define E1kLog3(a)              Log3(a)
     146#  define E1kLogX(x, a)           LogIt(LOG_INSTANCE, x, LOG_GROUP, a)
    144147//#  define E1kLog(a)               do {} while (0)
    145148//#  define E1kLog2(a)              do {} while (0)
     
    10661069    E1KTXCTX    contextNormal;
    10671070#ifdef E1K_WITH_TXD_CACHE
    1068     /** EMT/TX: Fetched TX descriptors. */
     1071    /** TX: Fetched TX descriptors. */
    10691072    E1KTXDESC   aTxDescriptors[E1K_TXD_CACHE_SIZE];
    1070     /** EMT/TX: Actual number of fetched TX descriptors. */
     1073    /** TX: Actual number of fetched TX descriptors. */
    10711074    uint8_t     nTxDFetched;
    1072     /** EMT/TX: Index in cache of TX descriptor being processed. */
     1075    /** TX: Index in cache of TX descriptor being processed. */
    10731076    uint8_t     iTxDCurrent;
    1074     /** EMT/TX: Will this frame be sent as GSO. */
     1077    /** TX: Will this frame be sent as GSO. */
    10751078    bool        fGSO;
    1076     /** EMT/TX: Number of bytes in next packet. */
     1079    /** TX: Number of bytes in next packet. */
    10771080    uint32_t    cbTxAlloc;
    10781081
     
    16471650 * @thread  E1000_TX
    16481651 */
    1649 static void e1kPrintTDesc(E1KSTATE* pState, E1KTXDESC* pDesc, const char* cszDir)
     1652static void e1kPrintTDesc(E1KSTATE* pState, E1KTXDESC* pDesc, const char* cszDir,
     1653                          unsigned uLevel = RTLOGGRPFLAGS_LEVEL_2)
    16501654{
    16511655    switch (e1kGetDescType(pDesc))
    16521656    {
    16531657        case E1K_DTYP_CONTEXT:
    1654             E1kLog2(("%s %s Context Transmit Descriptor %s\n",
     1658            E1kLogX(uLevel, ("%s %s Context Transmit Descriptor %s\n",
    16551659                    INSTANCE(pState), cszDir, cszDir));
    1656             E1kLog2(("        IPCSS=%02X IPCSO=%02X IPCSE=%04X TUCSS=%02X TUCSO=%02X TUCSE=%04X\n",
     1660            E1kLogX(uLevel, ("        IPCSS=%02X IPCSO=%02X IPCSE=%04X TUCSS=%02X TUCSO=%02X TUCSE=%04X\n",
    16571661                    pDesc->context.ip.u8CSS, pDesc->context.ip.u8CSO, pDesc->context.ip.u16CSE,
    16581662                    pDesc->context.tu.u8CSS, pDesc->context.tu.u8CSO, pDesc->context.tu.u16CSE));
    1659             E1kLog2(("        TUCMD:%s%s%s %s %s PAYLEN=%04x HDRLEN=%04x MSS=%04x STA: %s\n",
     1663            E1kLogX(uLevel, ("        TUCMD:%s%s%s %s %s PAYLEN=%04x HDRLEN=%04x MSS=%04x STA: %s\n",
    16601664                    pDesc->context.dw2.fIDE ? " IDE":"",
    16611665                    pDesc->context.dw2.fRS  ? " RS" :"",
     
    16691673            break;
    16701674        case E1K_DTYP_DATA:
    1671             E1kLog2(("%s %s Data Transmit Descriptor (%d bytes) %s\n",
     1675            E1kLogX(uLevel, ("%s %s Data Transmit Descriptor (%d bytes) %s\n",
    16721676                    INSTANCE(pState), cszDir, pDesc->data.cmd.u20DTALEN, cszDir));
    1673             E1kLog2(("        Address=%16LX DTALEN=%05X\n",
     1677            E1kLogX(uLevel, ("        Address=%16LX DTALEN=%05X\n",
    16741678                    pDesc->data.u64BufAddr,
    16751679                    pDesc->data.cmd.u20DTALEN));
    1676             E1kLog2(("        DCMD:%s%s%s%s%s%s STA:%s%s%s POPTS:%s%s SPECIAL:%s VLAN=%03x PRI=%x\n",
     1680            E1kLogX(uLevel, ("        DCMD:%s%s%s%s%s%s STA:%s%s%s POPTS:%s%s SPECIAL:%s VLAN=%03x PRI=%x\n",
    16771681                    pDesc->data.cmd.fIDE ? " IDE" :"",
    16781682                    pDesc->data.cmd.fVLE ? " VLE" :"",
     
    16911695            break;
    16921696        case E1K_DTYP_LEGACY:
    1693             E1kLog2(("%s %s Legacy Transmit Descriptor (%d bytes) %s\n",
     1697            E1kLogX(uLevel, ("%s %s Legacy Transmit Descriptor (%d bytes) %s\n",
    16941698                    INSTANCE(pState), cszDir, pDesc->legacy.cmd.u16Length, cszDir));
    1695             E1kLog2(("        Address=%16LX DTALEN=%05X\n",
     1699            E1kLogX(uLevel, ("        Address=%16LX DTALEN=%05X\n",
    16961700                    pDesc->data.u64BufAddr,
    16971701                    pDesc->legacy.cmd.u16Length));
    1698             E1kLog2(("        CMD:%s%s%s%s%s%s STA:%s%s%s CSO=%02x CSS=%02x SPECIAL:%s VLAN=%03x PRI=%x\n",
     1702            E1kLogX(uLevel, ("        CMD:%s%s%s%s%s%s STA:%s%s%s CSO=%02x CSS=%02x SPECIAL:%s VLAN=%03x PRI=%x\n",
    16991703                    pDesc->legacy.cmd.fIDE ? " IDE" :"",
    17001704                    pDesc->legacy.cmd.fVLE ? " VLE" :"",
     
    45134517            return rc;
    45144518    }
    4515     /*
    4516      * Process all pending descriptors.
    4517      * Note! Do not process descriptors in locked state
    4518      */
    4519     while (TDH != TDT && !pState->fLocked)
    4520     {
    4521         E1KTXDESC desc;
    4522         E1kLog3(("%s About to process new TX descriptor at %08x%08x, TDLEN=%08x, TDH=%08x, TDT=%08x\n",
    4523                  INSTANCE(pState), TDBAH, TDBAL + TDH * sizeof(desc), TDLEN, TDH, TDT));
    4524 
    4525         e1kLoadDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc));
    4526         rc = e1kXmitDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc), fOnWorkerThread);
    4527         /* If we failed to transmit descriptor we will try it again later */
    4528         if (RT_FAILURE(rc))
    4529             break;
    4530         if (++TDH * sizeof(desc) >= TDLEN)
    4531             TDH = 0;
    4532 
    4533         if (e1kGetTxLen(pState) <= GET_BITS(TXDCTL, LWTHRESH)*8)
    4534         {
    4535             E1kLog2(("%s Low on transmit descriptors, raise ICR.TXD_LOW, len=%x thresh=%x\n",
    4536                      INSTANCE(pState), e1kGetTxLen(pState), GET_BITS(TXDCTL, LWTHRESH)*8));
    4537             e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_TXD_LOW);
    4538         }
    4539 
    4540         STAM_PROFILE_ADV_STOP(&pState->CTX_SUFF_Z(StatTransmit), a);
    4541     }
    4542 
    4543     /// @todo: uncomment: pState->uStatIntTXQE++;
    4544     /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE);
     4519    //rc = e1kCsTxEnter(pState, VERR_SEM_BUSY);
     4520    if (RT_LIKELY(rc == VINF_SUCCESS))
     4521    {
     4522        /*
     4523         * Process all pending descriptors.
     4524         * Note! Do not process descriptors in locked state
     4525         */
     4526        while (TDH != TDT && !pState->fLocked)
     4527        {
     4528            E1KTXDESC desc;
     4529            E1kLog3(("%s About to process new TX descriptor at %08x%08x, TDLEN=%08x, TDH=%08x, TDT=%08x\n",
     4530                     INSTANCE(pState), TDBAH, TDBAL + TDH * sizeof(desc), TDLEN, TDH, TDT));
     4531           
     4532            e1kLoadDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc));
     4533            rc = e1kXmitDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc), fOnWorkerThread);
     4534            /* If we failed to transmit descriptor we will try it again later */
     4535            if (RT_FAILURE(rc))
     4536                break;
     4537            if (++TDH * sizeof(desc) >= TDLEN)
     4538                TDH = 0;
     4539
     4540            if (e1kGetTxLen(pState) <= GET_BITS(TXDCTL, LWTHRESH)*8)
     4541            {
     4542                E1kLog2(("%s Low on transmit descriptors, raise ICR.TXD_LOW, len=%x thresh=%x\n",
     4543                         INSTANCE(pState), e1kGetTxLen(pState), GET_BITS(TXDCTL, LWTHRESH)*8));
     4544                e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_TXD_LOW);
     4545            }
     4546
     4547            STAM_PROFILE_ADV_STOP(&pState->CTX_SUFF_Z(StatTransmit), a);
     4548        }
     4549
     4550        /// @todo: uncomment: pState->uStatIntTXQE++;
     4551        /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE);
     4552        //e1kCsTxLeave(pState);
     4553    }
    45454554
    45464555    /*
     
    45524561}
    45534562#else /* E1K_WITH_TXD_CACHE */
     4563static void e1kDumpTxDCache(E1KSTATE *pState)
     4564{
     4565    for (int i = 0; i < pState->nTxDFetched; ++i)
     4566        e1kPrintTDesc(pState, &pState->aTxDescriptors[i], "***", RTLOGGRPFLAGS_LEVEL_4);
     4567}
     4568
    45544569/**
    45554570 * Transmit pending descriptors.
     
    45964611        }
    45974612        uint8_t u8Remain = pState->nTxDFetched - pState->iTxDCurrent;
     4613        if (RT_UNLIKELY(u8Remain == E1K_TXD_CACHE_SIZE))
     4614        {
     4615            /*
     4616             * The descriptor cache is full, but we were unable to find
     4617             * a complete packet in it. Drop the cache and hope that
     4618             * the guest driver can recover from network card error.
     4619             */
     4620            Log4(("%s No complete packets in full TxD cache! "
     4621                  "Fetched=%d, TX len=%d. Dump follows:\n",
     4622                  INSTANCE(pState), pState->nTxDFetched, e1kGetTxLen(pState)));
     4623            e1kDumpTxDCache(pState);
     4624            pState->nTxDFetched = 0;
     4625            rc = VERR_NET_IO_ERROR;
     4626            goto out;
     4627        }
    45984628        if (u8Remain > 0)
    45994629        {
     
    47054735    {
    47064736        E1kLogRel(("E1000: TDT write: %d descriptors to process\n", e1kGetTxLen(pState)));
    4707         E1kLog(("%s e1kRegWriteTDT: %d descriptors to process, waking up E1000_TX thread\n",
     4737        E1kLog(("%s e1kRegWriteTDT: %d descriptors to process\n",
    47084738                 INSTANCE(pState), e1kGetTxLen(pState)));
    47094739        e1kCsTxLeave(pState);
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