VirtualBox

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


Ignore:
Timestamp:
Nov 4, 2019 9:46:54 PM (5 years ago)
Author:
vboxsync
Message:

Virtio_1_0,DevVirtioScsi: More common virtio code cleanups. bugref:9218 bugref:9440

File:
1 edited

Legend:

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

    r81658 r81660  
    8181
    8282#define VIRTIOSCSI_REQ_QUEUE_CNT                    1           /**< T.B.D. Consider increasing                      */
    83 #define VIRTIOSCSI_QUEUE_CNT                        VIRTIOSCSI_REQ_QUEUE_CNT + 2
     83#define VIRTIOSCSI_QUEUE_CNT                        (VIRTIOSCSI_REQ_QUEUE_CNT + 2)
    8484#define VIRTIOSCSI_MAX_LUN                          256         /**< VirtIO specification, section 5.6.4             */
    8585#define VIRTIOSCSI_MAX_COMMANDS_PER_LUN             128         /**< T.B.D. What is a good value for this?           */
     
    394394} VIRTIOSCSITARGET, *PVIRTIOSCSITARGET;
    395395
     396
     397/** Why we're quiescing. */
     398typedef enum VIRTIOSCSIQUIESCINGFOR
     399{
     400    kvirtIoScsiQuiescingForInvalid = 0,
     401    kvirtIoScsiQuiescingForReset,
     402    kvirtIoScsiQuiescingForSuspend,
     403    kvirtIoScsiQuiescingForPowerOff,
     404    kvirtIoScsiQuiescingFor32BitHack = 0x7fffffff
     405} VIRTIOSCSIQUIESCINGFOR;
     406
     407
    396408/**
    397409 * PDM instance data (state) for VirtIO Host SCSI device
     
    492504    /** True if in the process of quiescing I/O */
    493505    uint32_t                        fQuiescing;
     506    /** For which purpose we're quiescing. */
     507    VIRTIOSCSIQUIESCINGFOR          enmQuiescingFor;
    494508
    495509} VIRTIOSCSI, *PVIRTIOSCSI;
     
    663677
    664678    PVIRTIO_DESC_CHAIN_T pDescChain;
    665     virtioQueueGet(&pThis->Virtio, EVENTQ_IDX, &pDescChain, true);
     679    virtioR3QueueGet(&pThis->Virtio, EVENTQ_IDX, &pDescChain, true);
    666680
    667681    RTSGBUF reqSegBuf;
     
    669683    RTSgBufInit(&reqSegBuf, aReqSegs, RT_ELEMENTS(aReqSegs));
    670684
    671     virtioQueuePut( &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true);
     685    virtioR3QueuePut( &pThis->Virtio, EVENTQ_IDX, &reqSegBuf, pDescChain, true);
    672686    virtioQueueSync(&pThis->Virtio, EVENTQ_IDX);
    673687
     
    719733        pRespHdr->uResponse = VIRTIOSCSI_S_RESET;
    720734
    721     virtioQueuePut(&pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */);
     735    virtioR3QueuePut(&pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true /* fFence */);
    722736    virtioQueueSync(&pThis->Virtio, qIdx);
    723737
     
    875889
    876890
    877         virtioQueuePut(&pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */);
     891        virtioR3QueuePut(&pThis->Virtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */);
    878892        virtioQueueSync(&pThis->Virtio, pReq->qIdx);
    879893
     
    14171431
    14181432    LogFunc(("Response code: %s\n", virtioGetReqRespText(bResponse)));
    1419     virtioQueuePut( &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true);
     1433    virtioR3QueuePut( &pThis->Virtio, qIdx, &reqSegBuf, pDescChain, true);
    14201434    virtioQueueSync(&pThis->Virtio, qIdx);
    14211435
     
    14761490             Log6Func(("fetching next descriptor chain from %s\n", QUEUENAME(qIdx)));
    14771491             PVIRTIO_DESC_CHAIN_T pDescChain;
    1478              int rc = virtioQueueGet(&pThis->Virtio, qIdx, &pDescChain, true);
     1492             int rc = virtioR3QueueGet(&pThis->Virtio, qIdx, &pDescChain, true);
    14791493             if (rc == VERR_NOT_AVAILABLE)
    14801494             {
     
    20562070static DECLCALLBACK(bool) virtioScsiR3DeviceQuiesced(PPDMDEVINS pDevIns)
    20572071{
    2058     LogFunc(("Device I/O activity quiesced.\n"));
    20592072    PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    2060 
     2073    LogFunc(("Device I/O activity quiesced: enmQuiescingFor=%d\n", pThis->enmQuiescingFor));
     2074
     2075    if (pThis->enmQuiescingFor == kvirtIoScsiQuiescingForReset)
     2076        virtioR3PropagateResetNotification(&pThis->Virtio);
     2077    /** @todo r=bird: Do we need other notifications here for suspend and/or poweroff? */
     2078
     2079    pThis->enmQuiescingFor = kvirtIoScsiQuiescingForInvalid;
    20612080    pThis->fQuiescing = false;
    2062 
    20632081    return true;
    20642082}
     
    20672085 * Worker for virtioScsiR3Reset() and virtioScsiR3SuspendOrPowerOff().
    20682086 */
    2069 static void virtioScsiR3QuiesceDevice(PPDMDEVINS pDevIns)
     2087static void virtioScsiR3QuiesceDevice(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor)
    20702088{
    20712089    PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     
    20732091    /* Prevent worker threads from removing/processing elements from virtq's */
    20742092    pThis->fQuiescing = true;
     2093    pThis->enmQuiescingFor = enmQuiscingFor;
    20752094
    20762095    PDMDevHlpSetAsyncNotification(pDevIns, virtioScsiR3DeviceQuiesced);
     
    20822101
    20832102/**
    2084  * @interface_method_impl{PDMDEVREGR3,pfnResume}
    2085  */
    2086 static DECLCALLBACK(void) virtioScsiR3Resume(PPDMDEVINS pDevIns)
    2087 {
    2088     LogFunc(("\n"));
    2089 
     2103 * Common worker for suspend and power off.
     2104 */
     2105static void virtioScsiR3SuspendOrPowerOff(PPDMDEVINS pDevIns, VIRTIOSCSIQUIESCINGFOR enmQuiscingFor)
     2106{
    20902107    PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    20912108
    2092     pThis->fQuiescing = false;
    2093 
    2094     /* Wake worker threads flagged to skip pulling queue entries during quiesce
    2095      * to ensure they re-check their queues. Active request queues may already
    2096      * be awake due to new reqs coming in.
    2097      */
    2098     for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_REQ_QUEUE_CNT; qIdx++)
    2099     {
    2100         PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx];
    2101 
    2102         if (ASMAtomicReadBool(&pWorker->fSleeping))
    2103         {
    2104             Log6Func(("waking %s worker.\n", QUEUENAME(qIdx)));
    2105             int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess);
    2106             AssertRC(rc);
    2107         }
    2108     }
    2109 
    2110     /* Ensure guest is working the queues too. */
    2111     virtioPropagateResumeNotification(&pThis->Virtio);
    2112 }
    2113 
    2114 /**
    2115  * @interface_method_impl{PDMDEVREGR3,pfnSuspend}
    2116  */
    2117 static DECLCALLBACK(void) virtioScsiR3SuspendOrPowerOff(PPDMDEVINS pDevIns)
    2118 {
    2119     LogFunc(("\n"));
    2120 
    2121     virtioScsiR3QuiesceDevice(pDevIns);
    2122 
    2123     PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2109    virtioScsiR3QuiesceDevice(pDevIns, enmQuiscingFor);
     2110
    21242111
    21252112    /* VM is halted, thus no new I/O being dumped into queues by the guest.
     
    21392126
    21402127/**
     2128 * @interface_method_impl{PDMDEVREGR3,pfnPowerOff}
     2129 */
     2130static DECLCALLBACK(void) virtioScsiR3PowerOff(PPDMDEVINS pDevIns)
     2131{
     2132    LogFunc(("\n"));
     2133    virtioScsiR3SuspendOrPowerOff(pDevIns, kvirtIoScsiQuiescingForPowerOff);
     2134}
     2135
     2136/**
     2137 * @interface_method_impl{PDMDEVREGR3,pfnSuspend}
     2138 */
     2139static DECLCALLBACK(void) virtioScsiR3Suspend(PPDMDEVINS pDevIns)
     2140{
     2141    LogFunc(("\n"));
     2142    virtioScsiR3SuspendOrPowerOff(pDevIns, kvirtIoScsiQuiescingForSuspend);
     2143}
     2144
     2145/**
     2146 * @interface_method_impl{PDMDEVREGR3,pfnResume}
     2147 */
     2148static DECLCALLBACK(void) virtioScsiR3Resume(PPDMDEVINS pDevIns)
     2149{
     2150    PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2151    LogFunc(("\n"));
     2152
     2153    pThis->fQuiescing = false;
     2154
     2155    /* Wake worker threads flagged to skip pulling queue entries during quiesce
     2156     * to ensure they re-check their queues. Active request queues may already
     2157     * be awake due to new reqs coming in.
     2158     */
     2159    for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_REQ_QUEUE_CNT; qIdx++)
     2160    {
     2161        PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[qIdx];
     2162
     2163        if (ASMAtomicReadBool(&pWorker->fSleeping))
     2164        {
     2165            Log6Func(("waking %s worker.\n", QUEUENAME(qIdx)));
     2166            int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess);
     2167            AssertRC(rc);
     2168        }
     2169    }
     2170
     2171    /* Ensure guest is working the queues too. */
     2172    virtioR3PropagateResumeNotification(&pThis->Virtio);
     2173}
     2174
     2175/**
    21412176 * @interface_method_impl{PDMDEVREGR3,pfnReset}
    21422177 */
     
    21462181    PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    21472182    pThis->fResetting = true;
    2148     virtioScsiR3QuiesceDevice(pDevIns);
     2183    virtioScsiR3QuiesceDevice(pDevIns, kvirtIoScsiQuiescingForReset);
     2184
     2185    /** @todo r=bird: Shouldn't you reset the device here?!? */
    21492186}
    21502187
     
    21542191static DECLCALLBACK(int) virtioScsiR3Destruct(PPDMDEVINS pDevIns)
    21552192{
    2156     /*
    2157      * Check the versions here as well since the destructor is *always* called.
    2158      */
    2159 
    21602193    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    2161 
    2162     PVIRTIOSCSI  pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
     2194    PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    21632195
    21642196    RTMemFree(pThis->paTargetInstances);
     
    21732205        }
    21742206    }
    2175      return VINF_SUCCESS;
     2207
     2208    virtioR3Term(&pThis->Virtio, pDevIns);
     2209    return VINF_SUCCESS;
    21762210}
    21772211
     
    22652299        return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: failed to initialize VirtIO"));
    22662300
     2301    /* Name the queues: */
    22672302    RTStrCopy(pThis->aszQueueNames[CONTROLQ_IDX], VIRTIO_MAX_QUEUE_NAME_SIZE, "controlq");
    22682303    RTStrCopy(pThis->aszQueueNames[EVENTQ_IDX],   VIRTIO_MAX_QUEUE_NAME_SIZE, "eventq");
     
    22712306                    "requestq<%d>", qIdx - VIRTQ_REQ_BASE);
    22722307
     2308    /* Attach the queues and create worker threads for them: */
    22732309    for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++)
    22742310    {
    2275         rc = virtioQueueAttach(&pThis->Virtio, qIdx, QUEUENAME(qIdx));
    2276         pThis->afQueueAttached[qIdx] = (rc == VINF_SUCCESS);
     2311        rc = virtioR3QueueAttach(&pThis->Virtio, qIdx, QUEUENAME(qIdx));
     2312        pThis->afQueueAttached[qIdx] = (rc == VINF_SUCCESS); /** @todo r=bird: This looks a bit fishy, esp. giving the following. */
    22772313
    22782314        if (qIdx == CONTROLQ_IDX || IS_REQ_QUEUE(qIdx))
     
    24372473    /* .pfnPowerOn = */             NULL,
    24382474    /* .pfnReset = */               virtioScsiR3Reset,
    2439     /* .pfnSuspend = */             virtioScsiR3SuspendOrPowerOff,
     2475    /* .pfnSuspend = */             virtioScsiR3Suspend,
    24402476    /* .pfnResume = */              virtioScsiR3Resume,
    24412477    /* .pfnAttach = */              virtioScsiR3Attach,
     
    24432479    /* .pfnQueryInterface = */      NULL,
    24442480    /* .pfnInitComplete = */        NULL,
    2445     /* .pfnPowerOff = */            virtioScsiR3SuspendOrPowerOff,
     2481    /* .pfnPowerOff = */            virtioScsiR3PowerOff,
    24462482    /* .pfnSoftReset = */           NULL,
    24472483    /* .pfnReserved0 = */           NULL,
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