VirtualBox

Ignore:
Timestamp:
Nov 4, 2022 1:36:24 PM (2 years ago)
Author:
vboxsync
Message:

Devices/DevVirtioSCSI: Fix reference counting issue where a reference would've been released twice in the I/O request finish handler when the underlying driver reported a CHECK CONDITION error for the request causing the VM to hang when powering off, ticketref:21144

File:
1 edited

Legend:

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

    r96407 r97400  
    804804#endif
    805805
     806/**
     807 * Releases one reference from the given controller instances active request counter.
     808 *
     809 * @returns nothing.
     810 * @param   pDevIns     The device instance.
     811 * @param   pThis       VirtIO SCSI shared instance data.
     812 * @param   pThisCC     VirtIO SCSI ring-3 instance data.
     813 */
     814DECLINLINE(void) virtioScsiR3Release(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC)
     815{
     816    Assert(pThis->cActiveReqs);
     817
     818    if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
     819        PDMDevHlpAsyncNotificationCompleted(pDevIns);
     820}
     821
     822/**
     823 * Retains one reference for the given controller instances active request counter.
     824 *
     825 * @returns nothing.
     826 * @param   pThis       VirtIO SCSI shared instance data.
     827 */
     828DECLINLINE(void) virtioScsiR3Retain(PVIRTIOSCSI pThis)
     829{
     830    ASMAtomicIncU32(&pThis->cActiveReqs);
     831}
     832
    806833/** Internal worker. */
    807834static void virtioScsiR3FreeReq(PVIRTIOSCSITARGET pTarget, PVIRTIOSCSIREQ pReq)
     
    865892    virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf, true /* fFence */);
    866893    virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, uVirtqNbr);
    867 
    868     if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
    869         PDMDevHlpAsyncNotificationCompleted(pDevIns);
    870894
    871895    Log2(("---------------------------------------------------------------------------------\n"));
     
    10591083
    10601084    virtioScsiR3FreeReq(pTarget, pReq);
    1061 
    1062     if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
    1063         PDMDevHlpAsyncNotificationCompleted(pDevIns);
    1064 
     1085    virtioScsiR3Release(pDevIns, pThis, pThisCC);
    10651086    return rc;
    10661087}
     
    11561177                                 uint16_t uVirtqNbr, PVIRTQBUF pVirtqBuf)
    11571178{
    1158 
    1159     ASMAtomicIncU32(&pThis->cActiveReqs);
    1160 
    11611179    /*
    11621180     * Validate configuration values we use here before we start.
     
    12951313     * Have underlying driver allocate a req of size set during initialization of this device.
    12961314     */
     1315    virtioScsiR3Retain(pThis);
     1316
    12971317    PDMMEDIAEXIOREQ     hIoReq    = NULL;
    12981318    PVIRTIOSCSIREQ      pReq      = NULL;
     
    13021322                                      PDMIMEDIAEX_F_SUSPEND_ON_RECOVERABLE_ERR);
    13031323
    1304     AssertMsgRCReturn(rc, ("Failed to allocate I/O request, rc=%Rrc\n", rc), rc);
     1324    if (RT_FAILURE(rc))
     1325    {
     1326        virtioScsiR3Release(pDevIns, pThis, pThisCC);
     1327        return rc;
     1328    }
    13051329
    13061330    pReq->hIoReq      = hIoReq;
     
    13551379        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, uVirtqNbr, pVirtqBuf, &respHdr, abSense, cbSenseCfg);
    13561380        virtioScsiR3FreeReq(pTarget, pReq);
     1381        virtioScsiR3Release(pDevIns, pThis, pThisCC);
    13571382    }
    13581383    return VINF_SUCCESS;
     
    23932418        {
    23942419            /* Stop considering this request active */
    2395             if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
    2396                 PDMDevHlpAsyncNotificationCompleted(pDevIns);
     2420            virtioScsiR3Release(pDevIns, pThis, pThisCC);
    23972421            break;
    23982422        }
    23992423        case PDMMEDIAEXIOREQSTATE_ACTIVE:
    2400             ASMAtomicIncU32(&pThis->cActiveReqs);
     2424            virtioScsiR3Retain(pThis);
    24012425            break;
    24022426        default:
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