VirtualBox

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


Ignore:
Timestamp:
May 9, 2022 5:06:17 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
151379
Message:

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

Location:
trunk/src/VBox/Devices
Files:
4 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 */
  • trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp

    r93614 r94969  
    16021602             for (int i = 0; i < pWorkerR3->cRedoDescs; i++)
    16031603             {
     1604#ifdef VIRTIO_VBUF_ON_STACK
     1605                PVIRTQBUF pVirtqBuf = virtioCoreR3VirtqBufAlloc();
     1606                if (!pVirtqBuf)
     1607                {
     1608                    LogRel(("Failed to allocate memory for VIRTQBUF\n"));
     1609                    break;  /* No point in trying to allocate memory for other descriptor chains */
     1610                }
     1611                int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, uVirtqNbr,
     1612                                                    pWorkerR3->auRedoDescs[i], pVirtqBuf);
     1613#else /* !VIRTIO_VBUF_ON_STACK */
    16041614                  PVIRTQBUF pVirtqBuf;
    16051615                  int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, uVirtqNbr,
    16061616                                                        pWorkerR3->auRedoDescs[i], &pVirtqBuf);
     1617#endif /* !VIRTIO_VBUF_ON_STACK */
    16071618                  if (RT_FAILURE(rc))
    16081619                      LogRel(("Error fetching desc chain to redo, %Rrc", rc));
     
    16171628
    16181629             Log6Func(("fetching next descriptor chain from %s\n", VIRTQNAME(uVirtqNbr)));
     1630#ifdef VIRTIO_VBUF_ON_STACK
     1631            PVIRTQBUF pVirtqBuf = virtioCoreR3VirtqBufAlloc();
     1632            if (!pVirtqBuf)
     1633                LogRel(("Failed to allocate memory for VIRTQBUF\n"));
     1634            else
     1635            {
     1636             int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, uVirtqNbr, pVirtqBuf, true);
     1637#else /* !VIRTIO_VBUF_ON_STACK */
    16191638             PVIRTQBUF pVirtqBuf = NULL;
    16201639             int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, uVirtqNbr, &pVirtqBuf, true);
     1640#endif /* !VIRTIO_VBUF_ON_STACK */
    16211641             if (rc == VERR_NOT_AVAILABLE)
    16221642             {
     
    16361656
    16371657             virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
     1658#ifdef VIRTIO_VBUF_ON_STACK
     1659            }
     1660#endif /* VIRTIO_VBUF_ON_STACK */
    16381661        }
    16391662    }
  • trunk/src/VBox/Devices/VirtIO/VirtioCore.cpp

    r94287 r94969  
    620620    uint16_t uUsedIdxShadow  = pVirtq->uUsedIdxShadow;
    621621
     622#ifdef VIRTIO_VBUF_ON_STACK
     623    VIRTQBUF_T VirtqBuf;
     624    PVIRTQBUF pVirtqBuf = &VirtqBuf;
     625#else /* !VIRTIO_VBUF_ON_STACK */
    622626    PVIRTQBUF pVirtqBuf = NULL;
     627#endif /* !VIRTIO_VBUF_ON_STACK */
    623628
    624629    bool fEmpty = IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtq);
     
    629634    if (!fEmpty)
    630635    {
     636#ifdef VIRTIO_VBUF_ON_STACK
     637        virtioCoreR3VirtqAvailBufPeek(pDevIns,  pVirtio, uVirtq, pVirtqBuf);
     638#else /* !VIRTIO_VBUF_ON_STACK */
    631639        virtioCoreR3VirtqAvailBufPeek(pDevIns,  pVirtio, uVirtq, &pVirtqBuf);
     640#endif /* !VIRTIO_VBUF_ON_STACK */
    632641        cSendSegs   = pVirtqBuf->pSgPhysSend ? pVirtqBuf->pSgPhysSend->cSegs : 0;
    633642        cReturnSegs = pVirtqBuf->pSgPhysReturn ? pVirtqBuf->pSgPhysReturn->cSegs : 0;
     
    680689}
    681690
     691#ifdef VIRTIO_VBUF_ON_STACK
     692/** API Function: See header file */
     693PVIRTQBUF virtioCoreR3VirtqBufAlloc(void)
     694{
     695    PVIRTQBUF pVirtqBuf = (PVIRTQBUF)RTMemAllocZ(sizeof(VIRTQBUF_T));
     696    AssertReturn(pVirtqBuf, NULL);
     697    pVirtqBuf->u32Magic  = VIRTQBUF_MAGIC;
     698    pVirtqBuf->cRefs     = 1;
     699    return pVirtqBuf;
     700}
     701#endif /* VIRTIO_VBUF_ON_STACK */
     702
    682703/** API Function: See header file */
    683704uint32_t virtioCoreR3VirtqBufRetain(PVIRTQBUF pVirtqBuf)
     
    752773
    753774/** API function: See Header file  */
     775#ifdef VIRTIO_VBUF_ON_STACK
     776int virtioCoreR3VirtqAvailBufPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq, PVIRTQBUF pVirtqBuf)
     777{
     778    return virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, pVirtqBuf, false);
     779}
     780#else /* !VIRTIO_VBUF_ON_STACK */
    754781int virtioCoreR3VirtqAvailBufPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq,
    755782                         PPVIRTQBUF ppVirtqBuf)
     
    757784    return virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, ppVirtqBuf, false);
    758785}
     786#endif /* !VIRTIO_VBUF_ON_STACK */
    759787
    760788/** API function: See Header file  */
     
    778806
    779807/** API Function: See header file */
     808#ifdef VIRTIO_VBUF_ON_STACK
     809int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq,
     810                                 uint16_t uHeadIdx, PVIRTQBUF pVirtqBuf)
     811#else /* !VIRTIO_VBUF_ON_STACK */
    780812int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq,
    781813                             uint16_t uHeadIdx, PPVIRTQBUF ppVirtqBuf)
    782 {
     814#endif /* !VIRTIO_VBUF_ON_STACK */
     815{
     816#ifndef VIRTIO_VBUF_ON_STACK
    783817    AssertReturn(ppVirtqBuf, VERR_INVALID_POINTER);
    784818    *ppVirtqBuf = NULL;
     819#endif /* !VIRTIO_VBUF_ON_STACK */
    785820
    786821    AssertMsgReturn(uVirtq < RT_ELEMENTS(pVirtio->aVirtqueues),
     
    800835     * Allocate and initialize the descriptor chain structure.
    801836     */
     837#ifndef VIRTIO_VBUF_ON_STACK
    802838    PVIRTQBUF pVirtqBuf = (PVIRTQBUF)RTMemAllocZ(sizeof(VIRTQBUF_T));
    803839    AssertReturn(pVirtqBuf, VERR_NO_MEMORY);
    804840    pVirtqBuf->u32Magic  = VIRTQBUF_MAGIC;
    805841    pVirtqBuf->cRefs     = 1;
     842#endif /* !VIRTIO_VBUF_ON_STACK */
    806843    pVirtqBuf->uHeadIdx  = uHeadIdx;
    807844    pVirtqBuf->uVirtq    = uVirtq;
     845#ifndef VIRTIO_VBUF_ON_STACK
    808846    *ppVirtqBuf          = pVirtqBuf;
     847#endif /* !VIRTIO_VBUF_ON_STACK */
    809848
    810849    /*
     
    904943
    905944/** API function: See Header file  */
     945#ifdef VIRTIO_VBUF_ON_STACK
     946int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq,
     947                                 PVIRTQBUF pVirtqBuf, bool fRemove)
     948#else /* !VIRTIO_VBUF_ON_STACK */
    906949int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq,
    907950                         PPVIRTQBUF ppVirtqBuf, bool fRemove)
     951#endif /* !VIRTIO_VBUF_ON_STACK */
    908952{
    909953    Assert(uVirtq < RT_ELEMENTS(pVirtio->aVirtqueues));
     
    921965        pVirtq->uAvailIdxShadow++;
    922966
     967#ifdef VIRTIO_VBUF_ON_STACK
     968    int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, uHeadIdx, pVirtqBuf);
     969#else /* !VIRTIO_VBUF_ON_STACK */
    923970    int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, uHeadIdx, ppVirtqBuf);
     971#endif /* !VIRTIO_VBUF_ON_STACK */
    924972    return rc;
    925973}
  • trunk/src/VBox/Devices/VirtIO/VirtioCore.h

    r94275 r94969  
    2222# pragma once
    2323#endif
     24
     25/* Do not allocate VIRTQBUF from the heap when possible */
     26#define VIRTIO_VBUF_ON_STACK 1
    2427
    2528#include <iprt/ctype.h>
     
    676679uint16_t virtioCoreVirtqAvailBufCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr);
    677680
     681#ifdef VIRTIO_VBUF_ON_STACK
     682/**
     683 * This function is identical to virtioCoreR3VirtqAvailBufGet(), *except* it doesn't consume
     684 * peeked buffer from avail ring of the virtq. The function *becomes* identical to the
     685 * virtioCoreR3VirtqAvailBufGet() only if virtioCoreR3VirtqAvailRingNext() is invoked to
     686 * consume buf from the queue's avail ring, followed by invocation of virtioCoreR3VirtqUsedBufPut(),
     687 * to hand host-processed buffer back to guest, which completes guest-initiated virtq buffer circuit.
     688 *
     689 * @param   pDevIns     The device instance.
     690 * @param   pVirtio     Pointer to the shared virtio state.
     691 * @param   uVirtqNbr   Virtq number
     692 * @param   pVirtqBuf   Pointer to descriptor chain that contains the
     693 *                      pre-processed transaction information pulled from the virtq.
     694 *
     695 * @returns VBox status code:
     696 * @retval  VINF_SUCCESS         Success
     697 * @retval  VERR_INVALID_STATE   VirtIO not in ready state (asserted).
     698 * @retval  VERR_NOT_AVAILABLE   If the queue is empty.
     699 */
     700int  virtioCoreR3VirtqAvailBufPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr,
     701                                   PVIRTQBUF pVirtqBuf);
     702
     703/**
     704 * This function fetches the next buffer (descriptor chain) from the VirtIO "avail" ring of
     705 * indicated queue, separating the buf's s/g vectors into OUT (e.g. guest-to-host)
     706 * components and and IN (host-to-guest) components.
     707 *
     708 * Caller is responsible for GCPhys to host virtual memory conversions. If the
     709 * virtq buffer being peeked at is "consumed", virtioCoreR3VirtqAvailRingNext() must
     710 * be called, and after that virtioCoreR3VirtqUsedBufPut() must be called to
     711 * complete the buffer transfer cycle with the guest.
     712 *
     713 * @param   pDevIns     The device instance.
     714 * @param   pVirtio     Pointer to the shared virtio state.
     715 * @param   uVirtqNbr   Virtq number
     716 * @param   pVirtqBuf   Pointer to descriptor chain that contains the
     717 *                      pre-processed transaction information pulled from the virtq.
     718 * @param   fRemove     flags whether to remove desc chain from queue (false = peek)
     719 *
     720 * @returns VBox status code:
     721 * @retval  VINF_SUCCESS         Success
     722 * @retval  VERR_INVALID_STATE   VirtIO not in ready state (asserted).
     723 * @retval  VERR_NOT_AVAILABLE   If the queue is empty.
     724 */
     725int  virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr,
     726                                  PVIRTQBUF pVirtqBuf, bool fRemove);
     727
     728/**
     729 * Fetches a specific descriptor chain using avail ring of indicated queue and converts the
     730 * descriptor chain into its OUT (to device) and IN (to guest) components.
     731 *
     732 * The caller is responsible for GCPhys to host virtual memory conversions and *must*
     733 * return the virtq buffer using virtioCoreR3VirtqUsedBufPut() to complete the roundtrip
     734 * virtq transaction.
     735 * *
     736 * @param   pDevIns     The device instance.
     737 * @param   pVirtio     Pointer to the shared virtio state.
     738 * @param   uVirtqNbr   Virtq number
     739 * @param   pVirtqBuf   Pointer to descriptor chain that contains the
     740 *                      pre-processed transaction information pulled from the virtq.
     741 * @param   fRemove     flags whether to remove desc chain from queue (false = peek)
     742 *
     743 * @returns VBox status code:
     744 * @retval  VINF_SUCCESS         Success
     745 * @retval  VERR_INVALID_STATE   VirtIO not in ready state (asserted).
     746 * @retval  VERR_NOT_AVAILABLE   If the queue is empty.
     747 */
     748int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr,
     749                                  uint16_t uHeadIdx, PVIRTQBUF pVirtqBuf);
     750#else /* !VIRTIO_VBUF_ON_STACK */
    678751/**
    679752 * This function is identical to virtioCoreR3VirtqAvailBufGet(), *except* it doesn't consume
     
    748821int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr,
    749822                                  uint16_t uHeadIdx, PPVIRTQBUF ppVirtqBuf);
     823#endif /* !VIRTIO_VBUF_ON_STACK */
    750824
    751825/**
     
    10921166int  virtioCoreVirtqUsedRingSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr);
    10931167
     1168#ifdef VIRTIO_VBUF_ON_STACK
     1169/**
     1170 * Allocates a descriptor chain object with the reference count of one. Copying the reference
     1171 * to this object requires a call to virtioCoreR3VirtqBufRetain. All references must be later
     1172 * released with virtioCoreR3VirtqBufRelease. Just to be clear, one alloc plus one retain will
     1173 * require two releases.
     1174 *
     1175 * @returns A descriptor chain object.
     1176 *
     1177 * @retval  NULL if out of memory.
     1178 *
     1179 * NOTE: VIRTQBUF_T objects allocated on the stack will have garbage in the u32Magic field,
     1180 * triggering an assertion if virtioCoreR3VirtqBufRelease is called on them.
     1181 */
     1182PVIRTQBUF virtioCoreR3VirtqBufAlloc(void);
     1183#endif /* VIRTIO_VBUF_ON_STACK */
     1184
    10941185/**
    10951186 * Retains a reference to the given descriptor chain.
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