VirtualBox

Changeset 98661 in vbox for trunk/src/VBox/Devices/Storage


Ignore:
Timestamp:
Feb 20, 2023 4:31:14 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155961
Message:

Devices/DevVirtioSCSI: Possible fix for bugref:9440#c164, the queue head can get out of sync if two threads complete I/O requests concurrently

File:
1 edited

Legend:

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

    r98562 r98661  
    368368{
    369369    R3PTRTYPE(PPDMTHREAD)           pThread;                    /**< pointer to worker thread's handle                 */
    370     uint16_t                        auRedoDescs[VIRTQ_SIZE];/**< List of previously suspended reqs to re-submit    */
     370    RTCRITSECT                      CritSectVirtq;              /**< Protecting the virtq against concurrent thread access. */
     371    uint16_t                        auRedoDescs[VIRTQ_SIZE];    /**< List of previously suspended reqs to re-submit    */
    371372    uint16_t                        cRedoDescs;                 /**< Number of redo desc chain head desc idxes in list */
    372373} VIRTIOSCSIWORKERR3;
     
    715716
    716717#endif /* LOG_ENABLED */
     718
     719
     720/**
     721 * Wrapper around virtioCoreR3VirtqUsedBufPut() and virtioCoreVirtqUsedRingSync() doing some device locking.
     722 *
     723 * @returns nothing.
     724 * @param   pDevIns         The PDM device instance.
     725 * @param   pVirtio         Pointer to the shared virtio core structure.
     726 * @param   uVirtqNbr       The virtq number.
     727 * @param   pSgVirtReturn   The S/G buffer to return data from.
     728 * @param   pVirtqBuf       The virtq buffer.
     729 *
     730 * @note This is a temporary fix, see @bugref{9440#c164} on why it is necessary. Should be moved to VirtioCore or
     731 *       VirtioCore should be changed to not require locking.
     732 */
     733DECLINLINE(void) virtioScsiR3VirtqUsedBufPutAndSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr, PRTSGBUF pSgVirtReturn,
     734                                                    PVIRTQBUF pVirtqBuf)
     735{
     736    PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     737
     738    RTCritSectEnter(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
     739    virtioCoreR3VirtqUsedBufPut(pThisCC->pDevIns, pVirtio, uVirtqNbr, pSgVirtReturn, pVirtqBuf, true /* fFence */);
     740    virtioCoreVirtqUsedRingSync(pThisCC->pDevIns, pVirtio, uVirtqNbr);
     741    RTCritSectLeave(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
     742}
    717743
    718744
     
    793819    RTSgBufInit(&ReqSgBuf, aReqSegs, RT_ELEMENTS(aReqSegs));
    794820
    795     rc = virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pVirtqBuf, true /*fFence*/);
    796     if (rc == VINF_SUCCESS)
    797         virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, false);
    798     else
    799         LogRel(("Error writing control message to guest\n"));
     821    virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pVirtqBuf);
    800822    virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
    801823
     
    889911        pRespHdr->uResponse = VIRTIOSCSI_S_RESET;
    890912
    891     virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf, true /* fFence */);
    892     virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, uVirtqNbr);
    893 
     913    virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf);
    894914    Log2(("---------------------------------------------------------------------------------\n"));
    895915
     
    10741094                        VERR_BUFFER_OVERFLOW);
    10751095
    1076         virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, pReq->uVirtqNbr, &ReqSgBuf, pReq->pVirtqBuf, true /* fFence TBD */);
    1077         virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, pReq->uVirtqNbr);
    1078 
     1096        virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, pReq->uVirtqNbr, &ReqSgBuf, pReq->pVirtqBuf);
    10791097        Log2(("-----------------------------------------------------------------------------------------\n"));
    10801098    }
     
    15601578    RTSgBufInit(&ReqSgBuf, aReqSegs, cSegs);
    15611579
    1562     virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf, true /*fFence*/);
    1563     virtioCoreVirtqUsedRingSync(pDevIns, &pThis->Virtio, uVirtqNbr);
    1564 
     1580    virtioScsiR3VirtqUsedBufPutAndSync(pDevIns, &pThis->Virtio, uVirtqNbr, &ReqSgBuf, pVirtqBuf);
    15651581    return VINF_SUCCESS;
    15661582}
     
    24602476           pThisCC->aWorkers[uVirtqNbr].pThread = NULL;
    24612477        }
     2478
     2479        if (RTCritSectIsInitialized(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq))
     2480            RTCritSectDelete(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
    24622481    }
    24632482
     
    25742593        }
    25752594        pThis->afVirtqAttached[uVirtqNbr] = true;
     2595        rc = RTCritSectInit(&pThisCC->aWorkers[uVirtqNbr].CritSectVirtq);
     2596        if (RT_FAILURE(rc))
     2597            return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     2598                                       N_("DevVirtioSCSI: Failed to create worker critical section"));
    25762599    }
    25772600
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