VirtualBox

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


Ignore:
Timestamp:
Apr 6, 2020 12:31:32 PM (5 years ago)
Author:
vboxsync
Message:

Virtio_1_0: Reworked the VIRTIO_DESC_CHAIN_T handling to decrease the potential for memory leaks by employing reference counting and not having virtioCoreR3QueuePut be the one to free/release the chain. Combined the 5 allocations into a single one. bugref:9440

File:
1 edited

Legend:

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

    r83499 r83587  
    14271427    uint16_t cSegsAllocated = VIRTIONET_PREALLOCATE_RX_SEG_COUNT;
    14281428
    1429     PRTSGBUF pVirtSegBufToGuest = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF));
     1429    /**  @todo r=bird: error codepaths below are almost all leaky!  Maybe keep
     1430     *         allocations and cleanup here and put the code doing the complicated
     1431     *         work into a helper that can AssertReturn at will without needing to
     1432     *         care about cleaning stuff up. */
     1433    PRTSGBUF pVirtSegBufToGuest = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF)); /** @todo r=bird: Missing check. */
    14301434    PRTSGSEG paVirtSegsToGuest  = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * cSegsAllocated);
    14311435    AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY);
     
    14381442    for (cDescs = uOffset = 0; uOffset < cb; )
    14391443    {
    1440         PVIRTIO_DESC_CHAIN_T pDescChain;
     1444        PVIRTIO_DESC_CHAIN_T pDescChain = NULL;
    14411445
    14421446        int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue), &pDescChain, true);
    1443         AssertRC(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE);
     1447        Assert(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE, ("%Rrc\n", rc));
    14441448
    14451449        /** @todo  Find a better way to deal with this */
    1446         AssertMsgReturn(rc == VINF_SUCCESS && pDescChain->cbPhysReturn,
    1447                         ("Not enough Rx buffers in queue to accomodate ethernet packet\n"),
    1448                         VERR_INTERNAL_ERROR);
     1450        AssertMsgReturnStmt(rc == VINF_SUCCESS && pDescChain->cbPhysReturn,
     1451                            ("Not enough Rx buffers in queue to accomodate ethernet packet\n"),
     1452                            virtioCoreR3DescChainRelease(pDescChain),
     1453                            VERR_INTERNAL_ERROR);
    14491454
    14501455        /* Unlikely that len of 1st seg of guest Rx (IN) buf is less than sizeof(virtio_net_pkt_hdr) == 12.
    14511456         * Assert it to reduce complexity. Robust solution would entail finding seg idx and offset of
    14521457         * virtio_net_header.num_buffers (to update field *after* hdr & pkts copied to gcPhys) */
    1453         AssertMsgReturn(pDescChain->pSgPhysReturn->paSegs[0].cbSeg >= sizeof(VIRTIONET_PKT_HDR_T),
    1454                         ("Desc chain's first seg has insufficient space for pkt header!\n"),
    1455                         VERR_INTERNAL_ERROR);
     1458        AssertMsgReturnStmt(pDescChain->pSgPhysReturn->paSegs[0].cbSeg >= sizeof(VIRTIONET_PKT_HDR_T),
     1459                            ("Desc chain's first seg has insufficient space for pkt header!\n"),
     1460                            virtioCoreR3DescChainRelease(pDescChain),
     1461                            VERR_INTERNAL_ERROR);
    14561462
    14571463        uint32_t cbDescChainLeft = pDescChain->cbPhysReturn;
     
    15001506                break;
    15011507        }
     1508
     1509        virtioCoreR3DescChainRelease(pDescChain);
    15021510    }
    15031511
     
    20632071
    20642072    int rc;
    2065     PVIRTIO_DESC_CHAIN_T pDescChain;
     2073    PVIRTIO_DESC_CHAIN_T pDescChain = NULL;
    20662074    while ((rc = virtioCoreR3QueuePeek(pVirtio->pDevIns, pVirtio, idxQueue, &pDescChain)) == VINF_SUCCESS)
    20672075    {
    2068         if (RT_SUCCESS(rc))
     2076        if (RT_SUCCESS(rc)) /** @todo r=bird: pointless, see loop condition. */
    20692077            Log10Func(("%s fetched descriptor chain from %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
    20702078        else
    20712079        {
    20722080            LogFunc(("%s failed to find expected data on %s, rc = %Rrc\n", INSTANCE(pThis), VIRTQNAME(idxQueue), rc));
     2081            virtioCoreR3DescChainRelease(pDescChain);
    20732082            break;
    20742083        }
     
    20962105        if (pThisCC->pDrv)
    20972106        {
    2098             PDMNETWORKGSO Gso, *pGso = virtioNetR3SetupGsoCtx(&Gso, &PktHdr);
     2107            PDMNETWORKGSO  Gso;
     2108            PPDMNETWORKGSO pGso = virtioNetR3SetupGsoCtx(&Gso, &PktHdr);
    20992109
    21002110            /** @todo Optimize away the extra copying! (lazy bird) */
     
    21412151                Log4Func(("Failed to allocate S/G buffer: size=%u rc=%Rrc\n", uSize, rc));
    21422152                /* Stop trying to fetch TX descriptors until we get more bandwidth. */
     2153                virtioCoreR3DescChainRelease(pDescChain);
    21432154                break;
    21442155            }
     
    21522163            virtioCoreQueueSync(pVirtio->pDevIns, pVirtio, idxQueue);
    21532164        }
     2165
     2166        virtioCoreR3DescChainRelease(pDescChain);
     2167        pDescChain = NULL;
    21542168    }
    21552169    virtioNetR3SetWriteLed(pThisCC, false);
     
    22662280             {
    22672281                 Log10Func(("%s fetching next descriptor chain from %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue)));
    2268                  PVIRTIO_DESC_CHAIN_T pDescChain;
     2282                 PVIRTIO_DESC_CHAIN_T pDescChain = NULL;
    22692283                 int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, idxQueue, &pDescChain, true);
    22702284                 if (rc == VERR_NOT_AVAILABLE)
     
    22742288                 }
    22752289                 virtioNetR3Ctrl(pDevIns, pThis, pThisCC, pDescChain);
     2290                 virtioCoreR3DescChainRelease(pDescChain);
    22762291             }
    22772292             else if (IS_TX_QUEUE(idxQueue))
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