VirtualBox

Changeset 7374 in vbox


Ignore:
Timestamp:
Mar 7, 2008 3:41:17 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
28798
Message:

pcnet: fixed tx queue mode (missing lock) + several renames

File:
1 edited

Legend:

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

    r7358 r7374  
    7171#define PCNET_GC_ENABLED
    7272
     73/* Experimental: queue TX packets */
     74//#define PCNET_QUEUE_SEND_PACKETS
     75
    7376#if defined(LOG_ENABLED)
    7477#define PCNET_DEBUG_IO
     
    9598#define MAX_FRAME                       1536
    9699
    97 /* Frame cache */
    98 typedef struct PCNETFRAME
    99 {
    100     /** The current frame size. Starts at -1. Only the top frame can be expanded. */
    101     int32_t  cb;
    102 #if HC_ARCH_BITS == 64
    103     uint32_t Alignment;
    104 #endif
    105     /** The virtual address of the frame (copied or direct pointer) */
    106     RTR3PTR  pvBuf;
    107 } PCNETFRAME;
    108 /* Pointer to PCNETFRAME */
    109 typedef PCNETFRAME *PPCNETFRAME;
    110100
    111101typedef struct PCNetState_st PCNetState;
     
    149139    uint64_t                            u64LastPoll;
    150140
    151     /** Array of frames. */
    152     PCNETFRAME                          SendFrame;
     141    /** Size of current send frame */
     142    uint32_t                            cbSendFrame;
     143    /** Buffer address of current send frame */
     144    uint8_t                             *pvSendFrame;
    153145    /** The xmit buffer. */
    154146    uint8_t                             abSendBuf[4096];
     
    239231    uint32_t                            u32LinkSpeed;
    240232
    241 //#define PCNET_QUEUE_SEND_PACKETS
    242233#ifdef PCNET_QUEUE_SEND_PACKETS
    243234    #define PCNET_MAX_XMIT_SLOTS         128
    244235    #define PCNET_MAX_XMIT_SLOTS_MASK    (PCNET_MAX_XMIT_SLOTS-1)
    245236
    246     uint32_t                            ulXmitRingBufProd;
    247     uint32_t                            ulXmitRingBufCons;
     237    uint32_t                            iXmitRingBufProd;
     238    uint32_t                            iXmitRingBufCons;
     239    /* XXX currently atomic operations on this variable are overkill */
     240    volatile int32_t                    cXmitRingBufPending;
    248241    uint16_t                            cbXmitRingBuffer[PCNET_MAX_XMIT_SLOTS];
    249     R3PTRTYPE(char *)                   pXmitRingBuffer[PCNET_MAX_XMIT_SLOTS];
     242    R3PTRTYPE(uint8_t *)                apXmitRingBuffer[PCNET_MAX_XMIT_SLOTS];
    250243#endif
    251244
     
    579572        (R)->rmd2.zeros))
    580573
    581 #ifdef PCNET_QUEUE_SEND_PACKETS
     574#if defined(PCNET_QUEUE_SEND_PACKETS) && defined(IN_RING3)
    582575static int pcnetSyncTransmit(PCNetState *pData);
    583576#endif
     
    18331826    ASMAtomicAndU32(&pData->cPendingSends, 0);
    18341827#ifdef PCNET_QUEUE_SEND_PACKETS
     1828    int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
     1829    AssertReleaseRC(rc);
    18351830    pcnetSyncTransmit(pData);
     1831    PDMCritSectLeave(&pData->CritSect);
    18361832#else
    18371833    int rc = RTSemEventSignal(pData->hSendEventSem);
     
    18481844DECLINLINE(void) pcnetXmitScrapFrame(PCNetState *pData)
    18491845{
    1850     pData->SendFrame.pvBuf = NULL;
    1851     pData->SendFrame.cb    = -1;
    1852 }
    1853 
    1854 
    1855 /**
    1856  * If we are in RING3 don't copy the frame from GC here but only store the address. We
    1857  * don't need to buffer the frames because a direct address translation was possible.
    1858  */
    1859 DECLINLINE(void) pcnetXmitZeroCopyFrame(PCNetState *pData, RTR3PTR pv, const unsigned cbFrame)
    1860 {
    1861     pData->SendFrame.pvBuf = pv;
    1862     pData->SendFrame.cb    = cbFrame;
     1846    pData->pvSendFrame = NULL;
     1847    pData->cbSendFrame = 0;
    18631848}
    18641849
     
    18691854DECLINLINE(void) pcnetXmitRead1st(PCNetState *pData, RTGCPHYS32 GCPhysFrame, const unsigned cbFrame)
    18701855{
     1856    Assert(PDMCritSectIsOwner(&pData->CritSect));
    18711857    Assert(cbFrame < sizeof(pData->abSendBuf));
    18721858
    1873     PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, &pData->abSendBuf[0], cbFrame);
    1874     pData->SendFrame.pvBuf = pData->abSendBuf;
    1875     pData->SendFrame.cb    = cbFrame;
     1859#ifdef PCNET_QUEUE_SEND_PACKETS
     1860    AssertRelease(pData->cXmitRingBufPending < PCNET_MAX_XMIT_SLOTS-1);
     1861    pData->pvSendFrame = pData->apXmitRingBuffer[pData->iXmitRingBufProd];
     1862#else
     1863    pData->pvSendFrame = pData->abSendBuf;
     1864#endif
     1865    PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, pData->pvSendFrame, cbFrame);
     1866    pData->cbSendFrame = cbFrame;
    18761867}
    18771868
     
    18821873DECLINLINE(void) pcnetXmitReadMore(PCNetState *pData, RTGCPHYS32 GCPhysFrame, const unsigned cbFrame)
    18831874{
    1884     Assert(pData->SendFrame.cb + cbFrame < sizeof(pData->abSendBuf));
    1885     PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, &pData->abSendBuf[pData->SendFrame.cb], cbFrame);
    1886     pData->SendFrame.cb += cbFrame;
     1875    Assert(pData->cbSendFrame + cbFrame <= MAX_FRAME);
     1876    PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, pData->pvSendFrame + pData->cbSendFrame, cbFrame);
     1877    pData->cbSendFrame += cbFrame;
    18871878}
    18881879
     
    18951886{
    18961887#ifdef PCNET_QUEUE_SEND_PACKETS
    1897     Assert(!pData->cbXmitRingBuffer[pData->ulXmitRingBufProd]);
    1898     memcpy(pData->pXmitRingBuffer[pData->ulXmitRingBufProd], pData->SendFrame.pvBuf, pData->SendFrame.cb);
    1899     pData->cbXmitRingBuffer[pData->ulXmitRingBufProd] = (uint16_t)pData->SendFrame.cb;
    1900     pData->ulXmitRingBufProd                          = (pData->ulXmitRingBufProd+1) & PCNET_MAX_XMIT_SLOTS_MASK;
     1888    Assert(PDMCritSectIsOwner(&pData->CritSect));
     1889    AssertRelease(pData->cXmitRingBufPending < PCNET_MAX_XMIT_SLOTS-1);
     1890    Assert(!pData->cbXmitRingBuffer[pData->iXmitRingBufProd]);
     1891
     1892    pData->cbXmitRingBuffer[pData->iXmitRingBufProd] = (uint16_t)pData->cbSendFrame;
     1893    pData->iXmitRingBufProd = (pData->iXmitRingBufProd+1) & PCNET_MAX_XMIT_SLOTS_MASK;
     1894    ASMAtomicIncS32(&pData->cXmitRingBufPending);
    19011895
    19021896    int rc = RTSemEventSignal(pData->hSendEventSem);
     
    19101904
    19111905    STAM_PROFILE_ADV_START(&pData->StatTransmitSend, a);
    1912     if (pData->SendFrame.cb > 70) /* unqualified guess */
     1906    if (pData->cbSendFrame > 70) /* unqualified guess */
    19131907        pData->Led.Asserted.s.fWriting = pData->Led.Actual.s.fWriting = 1;
    19141908
    1915     pData->pDrv->pfnSend(pData->pDrv, pData->SendFrame.pvBuf, pData->SendFrame.cb);
    1916     STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, pData->SendFrame.cb);
     1909    pData->pDrv->pfnSend(pData->pDrv, pData->pvSendFrame, pData->cbSendFrame);
     1910    STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, pData->cbSendFrame);
    19171911    pData->Led.Actual.s.fWriting = 0;
    19181912    STAM_PROFILE_ADV_STOP(&pData->StatTransmitSend, a);
     
    19601954        pcnetRdtePoll(pData);
    19611955
    1962     Assert(pData->SendFrame.pvBuf);
    1963     pcnetReceiveNoSync(pData, (const uint8_t *)pData->SendFrame.pvBuf, pData->SendFrame.cb);
     1956    Assert(pData->pvSendFrame);
     1957    pcnetReceiveNoSync(pData, (const uint8_t *)pData->pvSendFrame, pData->cbSendFrame);
    19641958    pcnetXmitScrapFrame(pData);
    19651959    pData->Led.Actual.s.fReading = 0;
     
    20312025{
    20322026    Assert(PDMCritSectIsOwner(&pData->CritSect));
    2033 
    2034     while (pData->cbXmitRingBuffer[pData->ulXmitRingBufCons])
    2035     {
     2027    size_t cb;
     2028
     2029    while ((pData->cXmitRingBufPending > 0))
     2030    {
     2031        cb = pData->cbXmitRingBuffer[pData->iXmitRingBufCons];
     2032
    20362033        /* Don't hold the critical section while transmitting data. */
    20372034        /** @note also avoids deadlocks with NAT as it can call us right back. */
     
    20392036
    20402037        STAM_PROFILE_ADV_START(&pData->StatTransmitSend, a);
    2041         if (pData->SendFrame.cb > 70) /* unqualified guess */
     2038        if (cb > 70) /* unqualified guess */
    20422039            pData->Led.Asserted.s.fWriting = pData->Led.Actual.s.fWriting = 1;
    20432040
    2044         pData->pDrv->pfnSend(pData->pDrv, pData->pXmitRingBuffer[pData->ulXmitRingBufCons], pData->cbXmitRingBuffer[pData->ulXmitRingBufCons]);
    2045         STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, pData->cbXmitRingBuffer[pData->ulXmitRingBufCons]);
     2041        pData->pDrv->pfnSend(pData->pDrv, pData->apXmitRingBuffer[pData->iXmitRingBufCons], cb);
     2042        STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, cb);
    20462043        pData->Led.Actual.s.fWriting = 0;
    20472044        STAM_PROFILE_ADV_STOP(&pData->StatTransmitSend, a);
    20482045
    2049         PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
    2050 
    2051         pData->cbXmitRingBuffer[pData->ulXmitRingBufCons] = 0;
    2052         pData->ulXmitRingBufCons                          = (pData->ulXmitRingBufCons+1) & PCNET_MAX_XMIT_SLOTS_MASK;
     2046        int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
     2047        AssertReleaseRC(rc);
     2048
     2049        pData->cbXmitRingBuffer[pData->iXmitRingBufCons] = 0;
     2050        pData->iXmitRingBufCons = (pData->iXmitRingBufCons+1) & PCNET_MAX_XMIT_SLOTS_MASK;
     2051        ASMAtomicDecS32(&pData->cXmitRingBufPending);
    20532052    }
    20542053    return VINF_SUCCESS;
     
    22062205                pcnetTmdLoad(pData, &tmd, PHYSADDR(pData, CSR_CXDA(pData)), false);
    22072206                cb = 4096 - tmd.tmd1.bcnt;
    2208                 if (    pData->SendFrame.cb + cb < MAX_FRAME
     2207                if (    pData->cbSendFrame + cb < MAX_FRAME
    22092208                    &&  !fDropFrame)
    22102209                    pcnetXmitReadMore(pData, PHYSADDR(pData, tmd.tmd0.tbadr), cb);
     
    22122211                {
    22132212                    AssertMsg(fDropFrame, ("pcnetTransmit: Frame is too big!!! %d bytes\n",
    2214                                            pData->SendFrame.cb + cb));
     2213                                           pData->cbSendFrame + cb));
    22152214                    fDropFrame = true;
    22162215                }
     
    22182217                {
    22192218                    Log(("#%d pcnetTransmit: stp: cb=%d xmtrc=%#x-%#x\n", PCNET_INST_NR,
    2220                          pData->SendFrame.cb, iStart, CSR_XMTRC(pData)));
     2219                         pData->cbSendFrame, iStart, CSR_XMTRC(pData)));
    22212220                    if (pcnetIsLinkUp(pData) && !fDropFrame)
    22222221                    {
     
    35283527
    35293528    STAM_PROFILE_ADV_START(&pData->StatTimer, a);
    3530     rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);
     3529    rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
    35313530    AssertReleaseRC(rc);
    35323531
     
    35683567{
    35693568    PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *);
    3570     int         rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);
     3569    int         rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
    35713570    AssertReleaseRC(rc);
    35723571
     
    39253924    PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *);
    39263925
    3927     PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);
     3926    int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
     3927    AssertRC(rc);
    39283928
    39293929    pData->fSaving = true;
     
    39873987    PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *);
    39883988
    3989     PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);
     3989    int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
     3990    AssertRC(rc);
    39903991    pData->fSaving = false;
    39913992    PDMCritSectLeave(&pData->CritSect);
     
    41114112    PCNetState *pData = INETWORKPORT_2_DATA(pInterface);
    41124113
    4113     rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);
     4114    rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
    41144115    AssertReleaseRC(rc);
    41154116
     
    41364137
    41374138    STAM_PROFILE_ADV_START(&pData->StatReceive, a);
    4138     rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);
     4139    rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
    41394140    AssertReleaseRC(rc);
    41404141
     
    43214322    }
    43224323#ifdef PCNET_QUEUE_SEND_PACKETS
    4323     if (pData->pXmitRingBuffer)
    4324         RTMemFree(pData->pXmitRingBuffer[0]);
     4324    if (pData->apXmitRingBuffer)
     4325        RTMemFree(pData->apXmitRingBuffer[0]);
    43254326#endif
    43264327    return VINF_SUCCESS;
     
    46184619
    46194620#ifdef PCNET_QUEUE_SEND_PACKETS
    4620     pData->ulXmitRingBufProd   = 0;
    4621     pData->ulXmitRingBufCons   = 0;
    4622     pData->pXmitRingBuffer[0]  = (char *)RTMemAlloc(PCNET_MAX_XMIT_SLOTS * MAX_FRAME);
    4623     pData->cbXmitRingBuffer[0] = 0;
     4621    pData->apXmitRingBuffer[0] = (uint8_t *)RTMemAlloc(PCNET_MAX_XMIT_SLOTS * MAX_FRAME);
    46244622    for (i = 1; i < PCNET_MAX_XMIT_SLOTS; i++)
    4625     {
    4626         pData->pXmitRingBuffer[i]  = pData->pXmitRingBuffer[i-1] + MAX_FRAME;
    4627         pData->cbXmitRingBuffer[i] = 0;
    4628     }
     4623        pData->apXmitRingBuffer[i] = pData->apXmitRingBuffer[0] + i*MAX_FRAME;
    46294624#endif
    46304625
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette