VirtualBox

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


Ignore:
Timestamp:
May 9, 2022 5:06:17 PM (3 years ago)
Author:
vboxsync
Message:

Devices/Virtio|ai: Fixes and performance improvements for the 1.0 virtio-net implementation, bugref:8651

File:
1 edited

Legend:

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

    r93165 r94969  
    19001900    /* Cache address of uNumBuffers field of pkthdr to update ex post facto */
    19011901    RTGCPHYS GCPhysNumBuffers = pVirtqBuf->pSgPhysReturn->paSegs[0].GCPhys + RT_UOFFSETOF(VIRTIONETPKTHDR, uNumBuffers);
    1902     uint16_t cVirtqBufsUsed = 1;
     1902    uint16_t cVirtqBufsUsed = 0;
    19031903    cbBufRemaining -= cbPktHdr;
    19041904    /*
     
    19151915        ++cVirtqBufsUsed;
    19161916        cbBufRemaining -= cbBounded;
    1917         uPktOffset -= cbBounded;
     1917        uPktOffset += cbBounded;
    19181918        if (uPktOffset < cb)
    19191919        {
    19201920            cbHdrEnqueued = cbPktHdr;
     1921#ifdef VIRTIO_VBUF_ON_STACK
     1922            int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pRxVirtq->uIdx, pVirtqBuf, true);
     1923#else /* !VIRTIO_VBUF_ON_STACK */
     1924            virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
    19211925            int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pRxVirtq->uIdx, &pVirtqBuf, true);
     1926#endif /* !VIRTIO_VBUF_ON_STACK */
    19221927
    19231928            AssertMsgReturn(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE, ("%Rrc\n", rc), rc);
    19241929
     1930#ifdef VIRTIO_VBUF_ON_STACK
     1931            AssertMsgReturn(rc == VINF_SUCCESS && pVirtqBuf->cbPhysReturn,
     1932                            ("Not enough Rx buffers in queue to accomodate ethernet packet\n"),
     1933                            VERR_INTERNAL_ERROR);
     1934#else /* !VIRTIO_VBUF_ON_STACK */
    19251935            AssertMsgReturnStmt(rc == VINF_SUCCESS && pVirtqBuf->cbPhysReturn,
    19261936                                ("Not enough Rx buffers in queue to accomodate ethernet packet\n"),
    19271937                                virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf),
    19281938                                VERR_INTERNAL_ERROR);
     1939#endif /* !VIRTIO_VBUF_ON_STACK */
     1940            cbBufRemaining = pVirtqBuf->cbPhysReturn;
    19291941        }
    19301942    }
     
    19341946    AssertMsgRCReturn(rc, ("Failure updating descriptor count in pkt hdr in guest physical memory\n"), rc);
    19351947
     1948#ifndef VIRTIO_VBUF_ON_STACK
    19361949    virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
     1950#endif /* !VIRTIO_VBUF_ON_STACK */
    19371951    virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, pRxVirtq->uIdx);
    19381952    Log7(("\n"));
     
    19601974{
    19611975    RT_NOREF(pThisCC);
     1976#ifdef VIRTIO_VBUF_ON_STACK
     1977    VIRTQBUF_T VirtqBuf;
     1978    PVIRTQBUF pVirtqBuf = &VirtqBuf;
     1979    int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pRxVirtq->uIdx, pVirtqBuf, true);
     1980#else /* !VIRTIO_VBUF_ON_STACK */
    19621981    PVIRTQBUF pVirtqBuf;
    19631982    int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pRxVirtq->uIdx, &pVirtqBuf, true);
     1983#endif /* !VIRTIO_VBUF_ON_STACK */
    19641984
    19651985    AssertMsgReturn(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE, ("%Rrc\n", rc), rc);
    19661986
     1987#ifdef VIRTIO_VBUF_ON_STACK
     1988    AssertMsgReturn(rc == VINF_SUCCESS && pVirtqBuf->cbPhysReturn,
     1989                    ("Not enough Rx buffers or capacity to accommodate ethernet packet\n"),
     1990                    VERR_INTERNAL_ERROR);
     1991#else /* !VIRTIO_VBUF_ON_STACK */
    19671992    AssertMsgReturnStmt(rc == VINF_SUCCESS && pVirtqBuf->cbPhysReturn,
    19681993                        ("Not enough Rx buffers or capacity to accommodate ethernet packet\n"),
    19691994                        virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf),
    19701995                        VERR_INTERNAL_ERROR);
     1996#endif /* !VIRTIO_VBUF_ON_STACK */
    19711997    /*
    19721998     * Try to do fast (e.g. single-buffer) copy to guest, even if MRG_RXBUF feature is enabled
     
    19812007        if (rc == VINF_SUCCESS)
    19822008            rc = virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, pRxVirtq->uIdx, cb, pvBuf, pVirtqBuf, cbPktHdr + cb /* cbEnqueue */);
     2009#ifndef VIRTIO_VBUF_ON_STACK
    19832010        virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
     2011#endif /* !VIRTIO_VBUF_ON_STACK */
    19842012        virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, pRxVirtq->uIdx);
    19852013        AssertMsgReturn(rc == VINF_SUCCESS, ("%Rrc\n", rc), rc);
     
    26742702    virtioNetR3SetWriteLed(pThisCC, true);
    26752703
     2704    /* Disable notifications until all available descriptors have been processed */
     2705    if (!(pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX))
     2706        virtioCoreVirtqEnableNotify(&pThis->Virtio, pTxVirtq->uIdx, false /* fEnable */);
     2707
    26762708    int rc;
     2709#ifdef VIRTIO_VBUF_ON_STACK
     2710    VIRTQBUF_T VirtqBuf;
     2711    PVIRTQBUF pVirtqBuf = &VirtqBuf;
     2712    while ((rc = virtioCoreR3VirtqAvailBufPeek(pVirtio->pDevInsR3, pVirtio, pTxVirtq->uIdx, pVirtqBuf)) == VINF_SUCCESS)
     2713#else /* !VIRTIO_VBUF_ON_STACK */
    26772714    PVIRTQBUF pVirtqBuf = NULL;
    26782715    while ((rc = virtioCoreR3VirtqAvailBufPeek(pVirtio->pDevInsR3, pVirtio, pTxVirtq->uIdx, &pVirtqBuf)) == VINF_SUCCESS)
     2716#endif /* !VIRTIO_VBUF_ON_STACK */
    26792717    {
    26802718        Log10Func(("[%s] fetched descriptor chain from %s\n", pThis->szInst, pTxVirtq->szName));
     
    26892727                        VERR_INTERNAL_ERROR);
    26902728
     2729#ifdef VIRTIO_VBUF_ON_STACK
     2730        VIRTIONETPKTHDR PktHdr;
     2731        PVIRTIONETPKTHDR pPktHdr = &PktHdr;
     2732#else /* !VIRTIO_VBUF_ON_STACK */
    26912733        PVIRTIONETPKTHDR pPktHdr = (PVIRTIONETPKTHDR)RTMemAllocZ(pThis->cbPktHdr);
    26922734        AssertMsgReturn(pPktHdr, ("Out of Memory\n"), VERR_NO_MEMORY);
     2735#endif /* !VIRTIO_VBUF_ON_STACK */
    26932736
    26942737        /* Compute total frame size from guest (including virtio-net pkt hdr) */
     
    27652808                Log4Func(("Failed to allocate S/G buffer: frame size=%u rc=%Rrc\n", uFrameSize, rc));
    27662809                /* Stop trying to fetch TX descriptors until we get more bandwidth. */
     2810#ifndef VIRTIO_VBUF_ON_STACK
    27672811                virtioCoreR3VirtqBufRelease(pVirtio, pVirtqBuf);
     2812#endif /* !VIRTIO_VBUF_ON_STACK */
    27682813                break;
    27692814            }
     
    27762821        }
    27772822
     2823#ifndef VIRTIO_VBUF_ON_STACK
    27782824        virtioCoreR3VirtqBufRelease(pVirtio, pVirtqBuf);
    27792825        pVirtqBuf = NULL;
     2826#endif /* !VIRTIO_VBUF_ON_STACK */
     2827        /* Before we break the loop we need to check if the queue is empty,
     2828         * re-enable notifications, and then re-check again to avoid missing
     2829         * a notification for the descriptor that is added to the queue
     2830         * after we have checked it on being empty, but before we re-enabled
     2831         * notifications.
     2832         */
     2833        if (!(pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX)
     2834            && IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, pTxVirtq->uIdx))
     2835            virtioCoreVirtqEnableNotify(&pThis->Virtio, pTxVirtq->uIdx, true /* fEnable */);
    27802836    }
    27812837    virtioNetR3SetWriteLed(pThisCC, false);
     
    31083164         {
    31093165             Log10Func(("[%s] %s worker woken. Fetching desc chain\n", pThis->szInst, pVirtq->szName));
     3166#ifdef VIRTIO_VBUF_ON_STACK
     3167            VIRTQBUF_T VirtqBuf;
     3168            PVIRTQBUF pVirtqBuf = &VirtqBuf;
     3169            int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pVirtq->uIdx, pVirtqBuf, true);
     3170#else /* !VIRTIO_VBUF_ON_STACK */
    31103171             PVIRTQBUF pVirtqBuf = NULL;
    31113172             int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pVirtq->uIdx, &pVirtqBuf, true);
     3173#endif /* !VIRTIO_VBUF_ON_STACK */
    31123174             if (rc == VERR_NOT_AVAILABLE)
    31133175             {
     
    31163178             }
    31173179             virtioNetR3Ctrl(pDevIns, pThis, pThisCC, pVirtqBuf);
     3180#ifndef VIRTIO_VBUF_ON_STACK
    31183181             virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
     3182#endif /* !VIRTIO_VBUF_ON_STACK */
    31193183         }
    31203184         else /* Must be Tx queue */
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