VirtualBox

Changeset 83571 in vbox for trunk/src


Ignore:
Timestamp:
Apr 5, 2020 9:53:37 PM (5 years ago)
Author:
vboxsync
Message:

DevVirtioSCSI.cpp: Eliminated unnecessary memory allocations in virtioScsiR3Ctrl, fixing the reference to fSupportedEvents after it went out of scope. bugref:9440

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp

    r83570 r83571  
    737737    RTSgBufInit(pReqSegBuf, paReqSegs, 1);
    738738
    739     virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, pReqSegBuf, pDescChain, true);
     739    virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, pReqSegBuf, pDescChain, true /*fFence*/);
    740740    virtioCoreQueueSync(pDevIns, &pThis->Virtio, EVENTQ_IDX);
    741741
     
    13191319                            uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain)
    13201320{
    1321     uint8_t bResponse = VIRTIOSCSI_S_OK;
    1322     uint8_t cSegs = 0;
    1323 
    13241321    AssertReturn(pDescChain->cbPhysSend >= RT_MIN(sizeof(VIRTIOSCSI_CTRL_AN_T),
    13251322                                                  sizeof(VIRTIOSCSI_CTRL_TMF_T)), 0);
     
    13281325     * Allocate buffer and read in the control command
    13291326     */
    1330     PVIRTIO_SCSI_CTRL_UNION_T pScsiCtrlUnion = (PVIRTIO_SCSI_CTRL_UNION_T)RTMemAllocZ(sizeof(VIRTIO_SCSI_CTRL_UNION_T));
    1331     AssertPtrReturn(pScsiCtrlUnion, VERR_NO_MEMORY /*ignored*/);
    1332 
    1333     uint8_t *pb = pScsiCtrlUnion->ab;
    1334     for (size_t cb = RT_MIN(pDescChain->cbPhysSend, sizeof(VIRTIO_SCSI_CTRL_UNION_T)); cb; )
    1335     {
    1336         size_t cbSeg = cb;
     1327    VIRTIO_SCSI_CTRL_UNION_T ScsiCtrlUnion;
     1328    RT_ZERO(ScsiCtrlUnion);
     1329
     1330    size_t const cbCtrl = RT_MIN(pDescChain->cbPhysSend, sizeof(VIRTIO_SCSI_CTRL_UNION_T));
     1331    for (size_t offCtrl = 0; offCtrl < cbCtrl; )
     1332    {
     1333        size_t cbSeg = cbCtrl - offCtrl;
    13371334        RTGCPHYS GCPhys = virtioCoreSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg);
    1338         PDMDevHlpPCIPhysRead(pDevIns, GCPhys, pb, cbSeg);
    1339         pb += cbSeg;
    1340         cb -= cbSeg;
    1341     }
    1342 
    1343     /** @todo r=bird: Memory leak here.  */
    1344     AssertReturn(   (pScsiCtrlUnion->scsiCtrl.uType == VIRTIOSCSI_T_TMF
     1335        PDMDevHlpPCIPhysRead(pDevIns, GCPhys, &ScsiCtrlUnion.ab[offCtrl], cbSeg);
     1336        offCtrl += cbSeg;
     1337    }
     1338
     1339    AssertReturn(   (ScsiCtrlUnion.scsiCtrl.uType == VIRTIOSCSI_T_TMF
    13451340                     && pDescChain->cbPhysSend >= sizeof(VIRTIOSCSI_CTRL_TMF_T))
    1346                  || ( (   pScsiCtrlUnion->scsiCtrl.uType == VIRTIOSCSI_T_AN_QUERY
    1347                        || pScsiCtrlUnion->scsiCtrl.uType == VIRTIOSCSI_T_AN_SUBSCRIBE)
    1348                      && pDescChain->cbPhysSend >= sizeof(VIRTIOSCSI_CTRL_AN_T)), 0);
    1349 
    1350     /** @todo r=bird: This segment handling is unnecessary. A stack array should
    1351      *        suffice.  The stack variable w/ initializer + memcpy into paReqSegs
    1352      *        done in the switch below is also weird + suboptimal. */
    1353     PRTSGSEG paReqSegs = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * 2);
    1354     AssertReturn(paReqSegs, VERR_NO_MEMORY); /** @todo r=bird: Memory leak here.  */
    1355 
    1356     switch (pScsiCtrlUnion->scsiCtrl.uType)
     1341                 || ( (   ScsiCtrlUnion.scsiCtrl.uType == VIRTIOSCSI_T_AN_QUERY
     1342                       || ScsiCtrlUnion.scsiCtrl.uType == VIRTIOSCSI_T_AN_SUBSCRIBE)
     1343                     && pDescChain->cbPhysSend >= sizeof(VIRTIOSCSI_CTRL_AN_T)),
     1344                    0 /** @todo r=bird: what kind of status is '0' here? */);
     1345
     1346    union
     1347    {
     1348        uint32_t fSupportedEvents;
     1349    }       uData;
     1350    uint8_t bResponse = VIRTIOSCSI_S_OK;
     1351    uint8_t cSegs;
     1352    RTSGSEG aReqSegs[2];
     1353    switch (ScsiCtrlUnion.scsiCtrl.uType)
    13571354    {
    13581355        case VIRTIOSCSI_T_TMF: /* Task Management Functions */
    13591356        {
    1360             uint8_t  uTarget  = pScsiCtrlUnion->scsiCtrlTmf.abScsiLun[1];
    1361             uint32_t uScsiLun = (pScsiCtrlUnion->scsiCtrlTmf.abScsiLun[2] << 8
    1362                                | pScsiCtrlUnion->scsiCtrlTmf.abScsiLun[3]) & 0x3fff;
     1357            uint8_t  uTarget  = ScsiCtrlUnion.scsiCtrlTmf.abScsiLun[1];
     1358            uint32_t uScsiLun = RT_MAKE_U16(ScsiCtrlUnion.scsiCtrlTmf.abScsiLun[3],
     1359                                            ScsiCtrlUnion.scsiCtrlTmf.abScsiLun[2]) & 0x3fff;
    13631360            Log2Func(("[%s] (Target: %d LUN: %d)  Task Mgt Function: %s\n",
    1364                       VIRTQNAME(qIdx), uTarget, uScsiLun, virtioGetTMFTypeText(pScsiCtrlUnion->scsiCtrlTmf.uSubtype)));
     1361                      VIRTQNAME(qIdx), uTarget, uScsiLun, virtioGetTMFTypeText(ScsiCtrlUnion.scsiCtrlTmf.uSubtype)));
    13651362
    13661363            if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent)
     
    13701367                bResponse = VIRTIOSCSI_S_INCORRECT_LUN;
    13711368            else
    1372                 switch (pScsiCtrlUnion->scsiCtrlTmf.uSubtype)
     1369                switch (ScsiCtrlUnion.scsiCtrlTmf.uSubtype)
    13731370                {
    13741371                    case VIRTIOSCSI_T_TMF_ABORT_TASK:
     
    14001397                        bResponse = VIRTIOSCSI_S_FAILURE;
    14011398                }
    1402 
    1403             RTSGSEG aSegs[] = { { &bResponse,  sizeof(bResponse) } };
    1404             memcpy(paReqSegs, aSegs, sizeof(aSegs));
    1405             cSegs = RT_ELEMENTS(aSegs);
     1399            cSegs = 0; /* only bResponse */
    14061400            break;
    14071401        }
    14081402        case VIRTIOSCSI_T_AN_QUERY: /* Guest SCSI driver is querying supported async event notifications */
    14091403        {
    1410 
    1411             PVIRTIOSCSI_CTRL_AN_T pScsiCtrlAnQuery = &pScsiCtrlUnion->scsiCtrlAsyncNotify;
     1404            PVIRTIOSCSI_CTRL_AN_T const pScsiCtrlAnQuery = &ScsiCtrlUnion.scsiCtrlAsyncNotify;
    14121405
    14131406            uint8_t  uTarget  = pScsiCtrlAnQuery->abScsiLun[1];
    1414             uint32_t uScsiLun = (pScsiCtrlAnQuery->abScsiLun[2] << 8 | pScsiCtrlAnQuery->abScsiLun[3]) & 0x3fff;
     1407            uint32_t uScsiLun = RT_MAKE_U16(pScsiCtrlAnQuery->abScsiLun[3], pScsiCtrlAnQuery->abScsiLun[2]) & 0x3fff;
    14151408
    14161409            if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent)
     
    14311424            }
    14321425#endif
    1433             uint32_t fSupportedEvents = SUPPORTED_EVENTS;
    1434             RTSGSEG aSegs[] = { { &fSupportedEvents, sizeof(fSupportedEvents) },
    1435                                 { &bResponse, sizeof(bResponse) } };
    1436             memcpy(paReqSegs, aSegs, sizeof(aSegs));
    1437             cSegs = RT_ELEMENTS(aSegs);
     1426            uData.fSupportedEvents = SUPPORTED_EVENTS;
     1427            aReqSegs[0].pvSeg = &uData.fSupportedEvents;
     1428            aReqSegs[0].cbSeg = sizeof(uData.fSupportedEvents);
     1429            cSegs = 1;
    14381430            break;
    14391431        }
    14401432        case VIRTIOSCSI_T_AN_SUBSCRIBE: /* Guest SCSI driver is subscribing to async event notification(s) */
    14411433        {
    1442             PVIRTIOSCSI_CTRL_AN_T pScsiCtrlAnSubscribe = &pScsiCtrlUnion->scsiCtrlAsyncNotify;
     1434            PVIRTIOSCSI_CTRL_AN_T const pScsiCtrlAnSubscribe = &ScsiCtrlUnion.scsiCtrlAsyncNotify;
    14431435
    14441436            if (pScsiCtrlAnSubscribe->fEventsRequested & ~SUBSCRIBABLE_EVENTS)
     
    14471439
    14481440            uint8_t  uTarget  = pScsiCtrlAnSubscribe->abScsiLun[1];
    1449             uint32_t uScsiLun = (pScsiCtrlAnSubscribe->abScsiLun[2] << 8
    1450                                | pScsiCtrlAnSubscribe->abScsiLun[3]) & 0x3fff;
     1441            uint32_t uScsiLun = RT_MAKE_U16(pScsiCtrlAnSubscribe->abScsiLun[3], pScsiCtrlAnSubscribe->abScsiLun[2]) & 0x3fff;
    14511442
    14521443#ifdef LOG_ENABLED
     
    14701461            }
    14711462
    1472             RTSGSEG aSegs[] = { { &pThis->fAsyncEvtsEnabled, sizeof(pThis->fAsyncEvtsEnabled) },
    1473                                 { &bResponse, sizeof(bResponse) } };
    1474             memcpy(paReqSegs, aSegs, sizeof(aSegs));
    1475             cSegs = RT_ELEMENTS(aSegs);
     1463            aReqSegs[0].pvSeg = &pThis->fAsyncEvtsEnabled;
     1464            aReqSegs[0].cbSeg = sizeof(pThis->fAsyncEvtsEnabled);
     1465            cSegs = 1;
    14761466            break;
    14771467        }
    14781468        default:
    14791469        {
    1480             LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(qIdx), pScsiCtrlUnion->scsiCtrl.uType));
     1470            LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(qIdx), ScsiCtrlUnion.scsiCtrl.uType));
    14811471
    14821472            bResponse = VIRTIOSCSI_S_FAILURE;
    1483             RTSGSEG aSegs[] = { { &bResponse, sizeof(bResponse) } };
    1484             memcpy(paReqSegs, aSegs, sizeof(aSegs));
    1485             cSegs = RT_ELEMENTS(aSegs);
     1473            cSegs = 0; /* only bResponse */
     1474            break;
    14861475        }
    14871476    }
     1477
     1478    /* Add the response code: */
     1479    aReqSegs[cSegs].pvSeg = &bResponse;
     1480    aReqSegs[cSegs].cbSeg = sizeof(bResponse);
     1481    cSegs++;
     1482    Assert(cSegs <= RT_ELEMENTS(aReqSegs));
     1483
    14881484    LogFunc(("Response code: %s\n", virtioGetReqRespText(bResponse)));
    14891485
    1490     PRTSGBUF pReqSegBuf = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF));
    1491     AssertReturn(pReqSegBuf, VERR_NO_MEMORY); /** @todo r=bird: Memory leak here.  */
    1492 
    1493     /* Copy segment data to malloc'd memory to avoid stack out-of-scope errors sanitizer doesn't detect */
    1494     /** @todo r=bird: The above comment makes zero sense as the memory is freed
    1495      *        before we return, so there cannot be any trouble with out-of-scope
    1496      *        stuff here. */
    1497     for (int i = 0; i < cSegs; i++)
    1498     {
    1499         void *pv = paReqSegs[i].pvSeg;
    1500         paReqSegs[i].pvSeg = RTMemDup(pv, paReqSegs[i].cbSeg);
    1501         AssertReturn(paReqSegs[i].pvSeg, VERR_NO_MEMORY); /** @todo r=bird: Memory leak here.  */
    1502     }
    1503 
    1504     RTSgBufInit(pReqSegBuf, paReqSegs, cSegs);
    1505 
    1506     virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, pReqSegBuf, pDescChain, true);
     1486    RTSGBUF ReqSgBuf;
     1487    RTSgBufInit(&ReqSgBuf, aReqSegs, cSegs);
     1488
     1489    virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &ReqSgBuf, pDescChain, true /*fFence*/);
    15071490    virtioCoreQueueSync(pDevIns, &pThis->Virtio, qIdx);
    1508 
    1509     for (int i = 0; i < cSegs; i++)
    1510         RTMemFree(paReqSegs[i].pvSeg);
    1511 
    1512     RTMemFree(paReqSegs);
    1513     RTMemFree(pReqSegBuf);
    1514     /** @todo r=bird: Leaking pScsiCtrlUnion here! */
    15151491
    15161492    return VINF_SUCCESS;
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