儲存庫 vbox 的更動 83587
- 時間撮記:
- 2020-4-6 下午12:31:32 (5 年 以前)
- 位置:
- trunk/src/VBox/Devices
- 檔案:
-
- 修改 4 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r83499 r83587 1427 1427 uint16_t cSegsAllocated = VIRTIONET_PREALLOCATE_RX_SEG_COUNT; 1428 1428 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. */ 1430 1434 PRTSGSEG paVirtSegsToGuest = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * cSegsAllocated); 1431 1435 AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY); … … 1438 1442 for (cDescs = uOffset = 0; uOffset < cb; ) 1439 1443 { 1440 PVIRTIO_DESC_CHAIN_T pDescChain ;1444 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 1441 1445 1442 1446 int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue), &pDescChain, true); 1443 Assert RC(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE);1447 Assert(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE, ("%Rrc\n", rc)); 1444 1448 1445 1449 /** @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); 1449 1454 1450 1455 /* Unlikely that len of 1st seg of guest Rx (IN) buf is less than sizeof(virtio_net_pkt_hdr) == 12. 1451 1456 * Assert it to reduce complexity. Robust solution would entail finding seg idx and offset of 1452 1457 * 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); 1456 1462 1457 1463 uint32_t cbDescChainLeft = pDescChain->cbPhysReturn; … … 1500 1506 break; 1501 1507 } 1508 1509 virtioCoreR3DescChainRelease(pDescChain); 1502 1510 } 1503 1511 … … 2063 2071 2064 2072 int rc; 2065 PVIRTIO_DESC_CHAIN_T pDescChain ;2073 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 2066 2074 while ((rc = virtioCoreR3QueuePeek(pVirtio->pDevIns, pVirtio, idxQueue, &pDescChain)) == VINF_SUCCESS) 2067 2075 { 2068 if (RT_SUCCESS(rc)) 2076 if (RT_SUCCESS(rc)) /** @todo r=bird: pointless, see loop condition. */ 2069 2077 Log10Func(("%s fetched descriptor chain from %s\n", INSTANCE(pThis), VIRTQNAME(idxQueue))); 2070 2078 else 2071 2079 { 2072 2080 LogFunc(("%s failed to find expected data on %s, rc = %Rrc\n", INSTANCE(pThis), VIRTQNAME(idxQueue), rc)); 2081 virtioCoreR3DescChainRelease(pDescChain); 2073 2082 break; 2074 2083 } … … 2096 2105 if (pThisCC->pDrv) 2097 2106 { 2098 PDMNETWORKGSO Gso, *pGso = virtioNetR3SetupGsoCtx(&Gso, &PktHdr); 2107 PDMNETWORKGSO Gso; 2108 PPDMNETWORKGSO pGso = virtioNetR3SetupGsoCtx(&Gso, &PktHdr); 2099 2109 2100 2110 /** @todo Optimize away the extra copying! (lazy bird) */ … … 2141 2151 Log4Func(("Failed to allocate S/G buffer: size=%u rc=%Rrc\n", uSize, rc)); 2142 2152 /* Stop trying to fetch TX descriptors until we get more bandwidth. */ 2153 virtioCoreR3DescChainRelease(pDescChain); 2143 2154 break; 2144 2155 } … … 2152 2163 virtioCoreQueueSync(pVirtio->pDevIns, pVirtio, idxQueue); 2153 2164 } 2165 2166 virtioCoreR3DescChainRelease(pDescChain); 2167 pDescChain = NULL; 2154 2168 } 2155 2169 virtioNetR3SetWriteLed(pThisCC, false); … … 2266 2280 { 2267 2281 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; 2269 2283 int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, idxQueue, &pDescChain, true); 2270 2284 if (rc == VERR_NOT_AVAILABLE) … … 2274 2288 } 2275 2289 virtioNetR3Ctrl(pDevIns, pThis, pThisCC, pDescChain); 2290 virtioCoreR3DescChainRelease(pDescChain); 2276 2291 } 2277 2292 else if (IS_TX_QUEUE(idxQueue)) -
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r83582 r83587 717 717 } 718 718 719 PVIRTIO_DESC_CHAIN_T pDescChain ;719 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 720 720 int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, EVENTQ_IDX, &pDescChain, true); 721 721 AssertRCReturn(rc, rc); … … 742 742 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pDescChain, true /*fFence*/); 743 743 virtioCoreQueueSync(pDevIns, &pThis->Virtio, EVENTQ_IDX); 744 virtioCoreR3DescChainRelease(pDescChain); 744 745 745 746 return VINF_SUCCESS; … … 751 752 RTMemFree(pReq->pbSense); 752 753 pReq->pbSense = NULL; 754 virtioCoreR3DescChainRelease(pReq->pDescChain); 755 pReq->pDescChain = NULL; 753 756 pTarget->pDrvMediaEx->pfnIoReqFree(pTarget->pDrvMediaEx, pReq->hIoReq); 754 757 } … … 1257 1260 pReq->cbDataOut = cbDataOut; 1258 1261 pReq->pDescChain = pDescChain; 1262 virtioCoreR3DescChainRetain(pDescChain); /* (For pReq->pDescChain. Released by virtioScsiR3FreeReq.) */ 1259 1263 pReq->uDataInOff = offDataIn; 1260 1264 pReq->uDataOutOff = offDataOut; … … 1550 1554 pWorkerR3->auRedoDescs[i], &pDescChain); 1551 1555 if (RT_FAILURE(rc)) 1552 LogRel(("Error fetching desc chain to redo, %Rrc", rc));1556 LogRel(("Error fetching desc chain to redo, %Rrc", rc)); 1553 1557 1554 1558 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, qIdx, pDescChain); 1555 1559 if (RT_FAILURE(rc)) 1556 LogRel(("Error submitting req packet, resetting %Rrc", rc)); 1560 LogRel(("Error submitting req packet, resetting %Rrc", rc)); 1561 1562 virtioCoreR3DescChainRelease(pDescChain); 1557 1563 } 1558 1564 pWorkerR3->cRedoDescs = 0; 1559 1565 1560 1566 Log6Func(("fetching next descriptor chain from %s\n", VIRTQNAME(qIdx))); 1561 PVIRTIO_DESC_CHAIN_T pDescChain ;1567 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 1562 1568 int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, qIdx, &pDescChain, true); 1563 1569 if (rc == VERR_NOT_AVAILABLE) 1564 1570 { 1565 Log6Func(("Nothing found in %s\n", VIRTQNAME(qIdx)));1566 continue;1571 Log6Func(("Nothing found in %s\n", VIRTQNAME(qIdx))); 1572 continue; 1567 1573 } 1568 1574 … … 1572 1578 else /* request queue index */ 1573 1579 { 1574 1575 1576 1580 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, qIdx, pDescChain); 1581 if (RT_FAILURE(rc)) 1582 LogRel(("Error submitting req packet, resetting %Rrc", rc)); 1577 1583 } 1584 1585 virtioCoreR3DescChainRelease(pDescChain); 1578 1586 } 1579 1587 } -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r83575 r83587 602 602 uint16_t uHeadIdx, PPVIRTIO_DESC_CHAIN_T ppDescChain) 603 603 { 604 AssertReturn(ppDescChain, VERR_INVALID_PARAMETER); 604 AssertReturn(ppDescChain, VERR_INVALID_POINTER); 605 *ppDescChain = NULL; 605 606 606 607 Assert(idxQueue < RT_ELEMENTS(pVirtio->virtqState)); 607 608 608 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue]; 609 610 PVIRTIOSGSEG paSegsIn = (PVIRTIOSGSEG)RTMemAlloc(VIRTQ_MAX_SIZE * sizeof(VIRTIOSGSEG)); 611 AssertReturn(paSegsIn, VERR_NO_MEMORY); 612 613 PVIRTIOSGSEG paSegsOut = (PVIRTIOSGSEG)RTMemAlloc(VIRTQ_MAX_SIZE * sizeof(VIRTIOSGSEG)); 614 AssertReturn(paSegsOut, VERR_NO_MEMORY); 609 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue]; 615 610 616 611 AssertMsgReturn(IS_DRIVER_OK(pVirtio) && pVirtio->uQueueEnable[idxQueue], … … 622 617 RT_NOREF(pVirtq); 623 618 619 /* 620 * Allocate and initialize the descriptor chain structure. 621 */ 622 PVIRTIO_DESC_CHAIN_T pDescChain = (PVIRTIO_DESC_CHAIN_T)RTMemAllocZ(sizeof(VIRTIO_DESC_CHAIN_T)); 623 AssertReturn(pDescChain, VERR_NO_MEMORY); 624 pDescChain->u32Magic = VIRTIO_DESC_CHAIN_MAGIC; 625 pDescChain->cRefs = 1; 626 pDescChain->uHeadIdx = uHeadIdx; 627 *ppDescChain = pDescChain; 628 629 /* 630 * Gather segments. 631 */ 624 632 VIRTQ_DESC_T desc; 625 633 626 uint32_t cbIn = 0, cbOut = 0, cSegsIn = 0, cSegsOut = 0; 634 uint32_t cbIn = 0; 635 uint32_t cbOut = 0; 636 uint32_t cSegsIn = 0; 637 uint32_t cSegsOut = 0; 638 PVIRTIOSGSEG paSegsIn = pDescChain->aSegsIn; 639 PVIRTIOSGSEG paSegsOut = pDescChain->aSegsOut; 627 640 628 641 do … … 657 670 Log6Func(("%s IN desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxQueue), uDescIdx, cSegsIn, desc.GCPhysBuf, desc.cb)); 658 671 cbIn += desc.cb; 659 pSeg = & (paSegsIn[cSegsIn++]);672 pSeg = &paSegsIn[cSegsIn++]; 660 673 } 661 674 else … … 663 676 Log6Func(("%s OUT desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxQueue), uDescIdx, cSegsOut, desc.GCPhysBuf, desc.cb)); 664 677 cbOut += desc.cb; 665 pSeg = & (paSegsOut[cSegsOut++]);678 pSeg = &paSegsOut[cSegsOut++]; 666 679 } 667 680 … … 672 685 } while (desc.fFlags & VIRTQ_DESC_F_NEXT); 673 686 674 PVIRTIO_DESC_CHAIN_T pDescChain = (PVIRTIO_DESC_CHAIN_T)RTMemAllocZ(sizeof(VIRTIO_DESC_CHAIN_T)); 675 AssertReturn(pDescChain, VERR_NO_MEMORY); 676 677 pDescChain->uHeadIdx = uHeadIdx; 678 *ppDescChain = pDescChain; 679 687 /* 688 * Add segments to the descriptor chain structure. 689 */ 680 690 if (cSegsIn) 681 691 { 682 PVIRTIOSGBUF pSgPhysIn = (PVIRTIOSGBUF)RTMemAllocZ(sizeof(VIRTIOSGBUF)); 683 AssertReturn(pSgPhysIn, VERR_NO_MEMORY); 684 685 virtioCoreSgBufInit(pSgPhysIn, paSegsIn, cSegsIn); 686 pDescChain->pSgPhysReturn = pSgPhysIn; 692 virtioCoreSgBufInit(&pDescChain->SgBufIn, paSegsIn, cSegsIn); 693 pDescChain->pSgPhysReturn = &pDescChain->SgBufIn; 687 694 pDescChain->cbPhysReturn = cbIn; 688 695 } … … 690 697 if (cSegsOut) 691 698 { 692 PVIRTIOSGBUF pSgPhysOut = (PVIRTIOSGBUF)RTMemAllocZ(sizeof(VIRTIOSGBUF)); 693 AssertReturn(pSgPhysOut, VERR_NO_MEMORY); 694 695 virtioCoreSgBufInit(pSgPhysOut, paSegsOut, cSegsOut); 696 pDescChain->pSgPhysSend = pSgPhysOut; 699 virtioCoreSgBufInit(&pDescChain->SgBufOut, paSegsOut, cSegsOut); 700 pDescChain->pSgPhysSend = &pDescChain->SgBufOut; 697 701 pDescChain->cbPhysSend = cbOut; 698 702 } 699 703 700 701 704 Log6Func(("%s -- segs OUT: %u (%u bytes) IN: %u (%u bytes) --\n", pVirtq->szVirtqName, cSegsOut, cbOut, cSegsIn, cbIn)); 702 705 703 706 return VINF_SUCCESS; 704 707 } 708 709 710 /** 711 * Retains a reference to the given descriptor chain. 712 * 713 * @returns New reference count. 714 * @retval UINT32_MAX on invalid parameter. 715 * @param pDescChain The descriptor chain to reference. 716 */ 717 uint32_t virtioCoreR3DescChainRetain(PVIRTIO_DESC_CHAIN_T pDescChain) 718 { 719 AssertReturn(pDescChain, UINT32_MAX); 720 AssertReturn(pDescChain->u32Magic == VIRTIO_DESC_CHAIN_MAGIC, UINT32_MAX); 721 uint32_t cRefs = ASMAtomicIncU32(&pDescChain->cRefs); 722 Assert(cRefs > 1); 723 Assert(cRefs < 16); 724 return cRefs; 725 } 726 727 728 /** 729 * Releases a reference to the given descriptor chain. 730 * 731 * @returns New reference count. 732 * @retval 0 if freed or invalid parameter. 733 * @param pDescChain The descriptor chain to reference. NULL is quietly 734 * ignored (returns 0). 735 */ 736 uint32_t virtioCoreR3DescChainRelease(PVIRTIO_DESC_CHAIN_T pDescChain) 737 { 738 if (!pDescChain) 739 return 0; 740 AssertReturn(pDescChain, 0); 741 AssertReturn(pDescChain->u32Magic == VIRTIO_DESC_CHAIN_MAGIC, 0); 742 uint32_t cRefs = ASMAtomicDecU32(&pDescChain->cRefs); 743 Assert(cRefs < 16); 744 if (cRefs == 0) 745 { 746 pDescChain->u32Magic = ~VIRTIO_DESC_CHAIN_MAGIC; 747 RTMemFree(pDescChain); 748 } 749 return cRefs; 750 } 751 705 752 706 753 /* … … 839 886 * @param ppDescChain Address to store pointer to descriptor chain that contains the 840 887 * pre-processed transaction information pulled from the virtq. 888 * Returned reference must be released by calling 889 * virtioCoreR3DescChainRelease(). 841 890 * @param fRemove flags whether to remove desc chain from queue (false = peek) 842 891 * … … 893 942 * @retval VERR_INVALID_STATE VirtIO not in ready state 894 943 * @retval VERR_NOT_AVAILABLE Queue is empty 944 * 945 * @note This function will not release any reference to pDescChain. The 946 * caller must take care of that. 895 947 */ 896 948 int virtioCoreR3QueuePut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn, … … 900 952 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue]; 901 953 PVIRTIOSGBUF pSgPhysReturn = pDescChain->pSgPhysReturn; 954 955 Assert(pDescChain->u32Magic == VIRTIO_DESC_CHAIN_MAGIC); 956 Assert(pDescChain->cRefs > 0); 902 957 903 958 AssertMsgReturn(IS_DRIVER_OK(pVirtio) /*&& pVirtio->uQueueEnable[idxQueue]*/, … … 951 1006 Log6Func(("Write ahead used_idx=%u, %s used_idx=%u\n", 952 1007 pVirtq->uUsedIdx, VIRTQNAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue))); 953 954 if (pDescChain->pSgPhysSend)955 {956 RTMemFree(pDescChain->pSgPhysSend->paSegs);957 RTMemFree(pDescChain->pSgPhysSend);958 }959 if (pDescChain->pSgPhysReturn)960 {961 RTMemFree(pSgPhysReturn->paSegs);962 RTMemFree(pSgPhysReturn);963 }964 RTMemFree(pDescChain);965 1008 966 1009 return VINF_SUCCESS; -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h
r83576 r83587 93 93 typedef PVIRTIOSGBUF *PPVIRTIOSGBUF; 94 94 95 /** 96 * Virtio descriptor chain representation. 97 */ 95 98 typedef struct VIRTIO_DESC_CHAIN 96 99 { 97 uint32_t uHeadIdx; /**< Head idx of associated desc chain */ 98 uint32_t cbPhysSend; /**< Total size of src buffer */ 99 PVIRTIOSGBUF pSgPhysSend; /**< Phys S/G/ buf for data from guest */ 100 uint32_t cbPhysReturn; /**< Total size of dst buffer */ 101 PVIRTIOSGBUF pSgPhysReturn; /**< Phys S/G buf to store result for guest */ 102 } VIRTIO_DESC_CHAIN_T, *PVIRTIO_DESC_CHAIN_T, **PPVIRTIO_DESC_CHAIN_T; 100 uint32_t u32Magic; /**< Magic value, VIRTIO_DESC_CHAIN_MAGIC. */ 101 uint32_t volatile cRefs; /**< Reference counter. */ 102 uint32_t uHeadIdx; /**< Head idx of associated desc chain */ 103 uint32_t cbPhysSend; /**< Total size of src buffer */ 104 PVIRTIOSGBUF pSgPhysSend; /**< Phys S/G/ buf for data from guest */ 105 uint32_t cbPhysReturn; /**< Total size of dst buffer */ 106 PVIRTIOSGBUF pSgPhysReturn; /**< Phys S/G buf to store result for guest */ 107 108 /** @name Internal (bird combined 5 allocations into a single), fingers off. 109 * @{ */ 110 VIRTIOSGBUF SgBufIn; 111 VIRTIOSGBUF SgBufOut; 112 VIRTIOSGSEG aSegsIn[VIRTQ_MAX_SIZE]; 113 VIRTIOSGSEG aSegsOut[VIRTQ_MAX_SIZE]; 114 /** @} */ 115 } VIRTIO_DESC_CHAIN_T; 116 /** Pointer to a Virtio descriptor chain. */ 117 typedef VIRTIO_DESC_CHAIN_T *PVIRTIO_DESC_CHAIN_T; 118 /** Pointer to a Virtio descriptor chain pointer. */ 119 typedef VIRTIO_DESC_CHAIN_T **PPVIRTIO_DESC_CHAIN_T; 120 /** Magic value for VIRTIO_DESC_CHAIN_T::u32Magic. */ 121 #define VIRTIO_DESC_CHAIN_MAGIC UINT32_C(0x19600219) 103 122 104 123 typedef struct VIRTIOPCIPARAMS … … 377 396 int virtioCoreR3DescChainGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue, 378 397 uint16_t uHeadIdx, PPVIRTIO_DESC_CHAIN_T ppDescChain); 398 uint32_t virtioCoreR3DescChainRetain(PVIRTIO_DESC_CHAIN_T pDescChain); 399 uint32_t virtioCoreR3DescChainRelease(PVIRTIO_DESC_CHAIN_T pDescChain); 379 400 380 401 int virtioCoreR3QueuePeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue,
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器