VirtualBox

Changeset 82010 in vbox


Ignore:
Timestamp:
Nov 20, 2019 3:20:11 AM (5 years ago)
Author:
vboxsync
Message:

Storage/DevVirtioSCSI.cpp: Implemented save/load suspended I/O handling differently and fixed save load logic. Was fuzzy about some details previously. See bugref:9440 Comment #129

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

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

    r82004 r82010  
    334334     | VIRTIOSCSI_EVT_ASYNC_DEVICE_BUSY )
    335335
    336 typedef struct VIRTIOSCSI_REQ_REDO
    337 {
    338     struct VIRTIOSCSI_REQ_REDO *next;                           /**< link to next in chain                             */
    339     uint16_t  uHeadIdx;                                         /**< desc chain head idx                               */
    340 } VIRTIOSCSI_REQ_REDO, *PVIRTIOSCSI_REQ_REDO;
    341 
    342336/**
    343337 * Worker thread context, shared state.
     
    358352    bool volatile                   fSleeping;                  /**< Flags whether worker thread is sleeping or not    */
    359353    bool volatile                   fNotified;                  /**< Flags whether worker thread notified              */
    360     PVIRTIOSCSI_REQ_REDO            pReqRedoQueue;              /**< Singly-linked listhead for suspended reqs to redo */
     354    uint16_t                        auRedoDescs[VIRTQ_MAX_SIZE];/**< List of previously suspended reqs to re-submit    */
     355    uint16_t                        cRedoDescs;                 /**< Number of redo desc chain head desc idxes in list */
    361356} VIRTIOSCSIWORKERR3;
    362357/** Pointer to a VirtIO SCSI worker. */
     
    15061501    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    15071502    {
    1508         if (!pWorkerR3->pReqRedoQueue && virtioCoreQueueIsEmpty(pDevIns, &pThis->Virtio, qIdx))
     1503        if (!pWorkerR3->cRedoDescs && virtioCoreQueueIsEmpty(pDevIns, &pThis->Virtio, qIdx))
    15091504        {
    15101505            /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */
     
    15331528        {
    15341529             /* Process any reqs that were suspended saved to the redo queue in save exec. */
    1535              PVIRTIOSCSI_REQ_REDO pReqRedo = pWorkerR3->pReqRedoQueue;
    1536              for (; pReqRedo; pReqRedo = pReqRedo->next)
     1530             for (int i = 0; i < pWorkerR3->cRedoDescs; i++)
    15371531             {
    15381532                  PVIRTIO_DESC_CHAIN_T pDescChain;
    15391533                  int rc = virtioCoreR3DescChainGet(pDevIns, &pThis->Virtio, qIdx,
    1540                                                 pReqRedo->uHeadIdx, &pDescChain);
     1534                                                pWorkerR3->auRedoDescs[i], &pDescChain);
    15411535                  if (RT_FAILURE(rc))
    15421536                     LogRel(("Error fetching desc chain to redo, %Rrc", rc));
     
    15461540                     LogRel(("Error submitting req packet, resetting %Rrc", rc));
    15471541             }
    1548              pWorkerR3->pReqRedoQueue = NULL;
     1542             pWorkerR3->cRedoDescs = 0;
    15491543
    15501544             Log6Func(("fetching next descriptor chain from %s\n", QUEUENAME(qIdx)));
     
    19591953{
    19601954    PVIRTIOSCSI     pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI);
    1961 //    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
     1955    PVIRTIOSCSICC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC);
    19621956    PCPDMDEVHLPR3   pHlp    = pDevIns->pHlpR3;
    19631957    LogFunc(("LOAD EXEC!!\n"));
     
    19661960    AssertLogRelMsgReturn(uVersion == VIRTIOSCSI_SAVED_STATE_VERSION,
    19671961                          ("uVersion=%u\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
    1968 
    1969     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uNumQueues);
    1970     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uSegMax);
    1971     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uMaxSectors);
    1972     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uCmdPerLun);
    1973     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uEventInfoSize);
    1974     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uSenseSize);
    1975     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uCdbSize);
    1976     pHlp->pfnSSMGetU16(pSSM, &pThis->virtioScsiConfig.uMaxChannel);
    1977     pHlp->pfnSSMGetU16(pSSM, &pThis->virtioScsiConfig.uMaxTarget);
    1978     pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uMaxLun);
    1979     pHlp->pfnSSMGetU32(pSSM, &pThis->fAsyncEvtsEnabled);
    1980     pHlp->pfnSSMGetU32(pSSM, (uint32_t *)&pThis->cActiveReqs);
    1981     pHlp->pfnSSMGetU32(pSSM, &pThis->fVirtioReady);
    1982     pHlp->pfnSSMGetU32(pSSM, &pThis->fHasT10pi);
    1983     pHlp->pfnSSMGetU32(pSSM, &pThis->fHasHotplug);
    1984     pHlp->pfnSSMGetU32(pSSM, &pThis->fHasInOutBufs);
    1985     pHlp->pfnSSMGetU32(pSSM, &pThis->fHasLunChange);
    1986     pHlp->pfnSSMGetU32(pSSM, &pThis->fResetting);
     1962// re-calculate names in aszQueueNames
     1963
     1964    for (int qIdx = 0; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++)
     1965        pHlp->pfnSSMGetBool(pSSM, &pThis->afQueueAttached[qIdx]);
     1966
     1967    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uNumQueues);
     1968    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uSegMax);
     1969    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uMaxSectors);
     1970    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uCmdPerLun);
     1971    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uEventInfoSize);
     1972    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uSenseSize);
     1973    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uCdbSize);
     1974    pHlp->pfnSSMGetU16(pSSM,  &pThis->virtioScsiConfig.uMaxChannel);
     1975    pHlp->pfnSSMGetU16(pSSM,  &pThis->virtioScsiConfig.uMaxTarget);
     1976    pHlp->pfnSSMGetU32(pSSM,  &pThis->virtioScsiConfig.uMaxLun);
     1977    pHlp->pfnSSMGetU32(pSSM,  &pThis->fAsyncEvtsEnabled);
    19871978    pHlp->pfnSSMGetBool(pSSM, &pThis->fEventsMissed);
    1988 
    1989 //    int rc = vboxscsiR3LoadExec(pHlp, &pThisCC->VBoxSCSI, pSSM);
     1979    pHlp->pfnSSMGetU32(pSSM,  &pThis->fVirtioReady);
     1980    pHlp->pfnSSMGetU32(pSSM,  &pThis->fHasT10pi);
     1981    pHlp->pfnSSMGetU32(pSSM,  &pThis->fHasHotplug);
     1982    pHlp->pfnSSMGetU32(pSSM,  &pThis->fHasInOutBufs);
     1983    pHlp->pfnSSMGetU32(pSSM,  &pThis->fHasLunChange);
     1984    pHlp->pfnSSMGetU32(pSSM,  &pThis->fResetting);
     1985
     1986    /* TODO: Ask aiechner about BIOS-related changes */
     1987    pHlp->pfnSSMGetU32(pSSM, &pThis->cTargets);
     1988
     1989
     1990    uint16_t cReqsRedo;
     1991    pHlp->pfnSSMGetU16(pSSM, &cReqsRedo);
     1992
     1993    for (uint16_t qIdx = VIRTQ_REQ_BASE; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++)
     1994    {
     1995        PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[qIdx];
     1996        pWorkerR3->cRedoDescs = 0;
     1997    }
     1998
     1999LogFunc(("Have %d redo reqs to load:%d\n", cReqsRedo));
     2000
     2001    for (int i = 0; i < cReqsRedo; i++)
     2002    {
     2003        uint16_t qIdx, uHeadIdx;
     2004
     2005        pHlp->pfnSSMGetU16(pSSM, &qIdx);
     2006
     2007        pHlp->pfnSSMGetU16(pSSM, &uHeadIdx);
     2008LogFunc(("    loaded redo req: qIdx=%d, headIdx=%d\n", qIdx, uHeadIdx));
     2009
     2010        PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[qIdx];
     2011        pWorkerR3->auRedoDescs[pWorkerR3->cRedoDescs++] = uHeadIdx;
     2012        pWorkerR3->cRedoDescs %= VIRTQ_MAX_SIZE;
     2013    }
    19902014
    19912015    /*
     
    20192043    LogFunc(("SAVE EXEC!!\n"));
    20202044
    2021      /* Every device first. */
    2022 //     lsilogicR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
    2023      for (unsigned i = 0; i < pThis->cTargets; i++)
     2045    for (int qIdx = 0; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++)
     2046        pHlp->pfnSSMPutBool(pSSM, pThis->afQueueAttached[qIdx]);
     2047
     2048    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uNumQueues);
     2049    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uSegMax);
     2050    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uMaxSectors);
     2051    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uCmdPerLun);
     2052    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uEventInfoSize);
     2053    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uSenseSize);
     2054    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uCdbSize);
     2055    pHlp->pfnSSMPutU16(pSSM,  pThis->virtioScsiConfig.uMaxChannel);
     2056    pHlp->pfnSSMPutU16(pSSM,  pThis->virtioScsiConfig.uMaxTarget);
     2057    pHlp->pfnSSMPutU32(pSSM,  pThis->virtioScsiConfig.uMaxLun);
     2058    pHlp->pfnSSMPutU32(pSSM,  pThis->fAsyncEvtsEnabled);
     2059    pHlp->pfnSSMPutBool(pSSM, pThis->fEventsMissed);
     2060    pHlp->pfnSSMPutU32(pSSM,  pThis->fVirtioReady);
     2061    pHlp->pfnSSMPutU32(pSSM,  pThis->fHasT10pi);
     2062    pHlp->pfnSSMPutU32(pSSM,  pThis->fHasHotplug);
     2063    pHlp->pfnSSMPutU32(pSSM,  pThis->fHasInOutBufs);
     2064    pHlp->pfnSSMPutU32(pSSM,  pThis->fHasLunChange);
     2065    pHlp->pfnSSMPutU32(pSSM,  pThis->fResetting);
     2066
     2067    /* Save suspended I/O requests */
     2068    /* TODO: Ask aiechner about BIOS-related changes */
     2069
     2070
     2071    AssertMsg(!pThis->cActiveReqs, ("There are still outstanding requests on this device\n"));
     2072
     2073     pHlp->pfnSSMPutU32(pSSM, pThis->cTargets);
     2074
     2075     for (uint16_t uTarget = 0; uTarget < pThis->cTargets; uTarget++)
    20242076     {
    2025          PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[i];
    2026 
    2027          AssertMsg(!pThis->cActiveReqs, ("There are still outstanding requests on this device\n"));
    2028          pHlp->pfnSSMPutU32(pSSM, pThis->cTargets);
     2077
     2078        PVIRTIOSCSITARGET pTarget = &pThisCC->paTargetInstances[uTarget];
    20292079
    20302080         /* Query all suspended requests and store them in the request queue. */
     
    20322082         {
    20332083             uint32_t cReqsRedo = pTarget->pDrvMediaEx->pfnIoReqGetSuspendedCount(pTarget->pDrvMediaEx);
     2084LogFunc(("Saving redo reqs target=%d, cReqsRedo=%d\n", uTarget, cReqsRedo));
     2085
     2086             pHlp->pfnSSMPutU16(pSSM, cReqsRedo);
     2087
    20342088             if (cReqsRedo)
    20352089             {
    20362090                 PDMMEDIAEXIOREQ hIoReq;
    20372091                 PVIRTIOSCSIREQ pReq;
     2092
    20382093                 int rc = pTarget->pDrvMediaEx->pfnIoReqQuerySuspendedStart(pTarget->pDrvMediaEx, &hIoReq,
    20392094                                                                            (void **)&pReq);
    20402095                 AssertRCBreak(rc);
    20412096
    2042                  /* todo: BIOS? */
    2043                  for (; cReqsRedo; --cReqsRedo)
     2097                 while(--cReqsRedo)
    20442098                 {
    2045 
    2046                     /* Add the head virtio desc idx of this request to the redo queue */
    2047                     PVIRTIOSCSI_REQ_REDO pReqRedo = (PVIRTIOSCSI_REQ_REDO)RTMemAllocZ(sizeof(VIRTIOSCSI_REQ_REDO));
    2048                     AssertReturn(pReqRedo, VERR_NO_MEMORY);
    2049                     pReqRedo->uHeadIdx = pReq->pDescChain->uHeadIdx;
    2050                     PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[pReq->qIdx];
    2051                     PVIRTIOSCSI_REQ_REDO *pReqRedoSlot = &pWorkerR3->pReqRedoQueue;
    2052 
    2053                     while(*pReqRedoSlot)
    2054                         pReqRedoSlot = &((*pReqRedoSlot)->next);
    2055 
    2056                     *pReqRedoSlot = pReqRedo;
    2057                      rc = pTarget->pDrvMediaEx->pfnIoReqQuerySuspendedNext(pTarget->pDrvMediaEx, hIoReq,
    2058                                                                            &hIoReq, (void **)&pReq);
    2059                      AssertRCBreak(rc);
     2099LogFunc(("     redo req: qIdx=%d, headIdx=%d\n", pReq->qIdx, pReq->pDescChain->uHeadIdx));
     2100
     2101                    pHlp->pfnSSMPutU16(pSSM, pReq->qIdx);
     2102                    pHlp->pfnSSMPutU16(pSSM, pReq->pDescChain->uHeadIdx);
     2103
     2104                    rc = pTarget->pDrvMediaEx->pfnIoReqQuerySuspendedNext(pTarget->pDrvMediaEx, hIoReq,
     2105                                                                          &hIoReq, (void **)&pReq);
     2106                    AssertRCBreak(rc);
    20602107                 }
    20612108             }
    20622109         }
    2063 //         int rc = vboxscsiR3SaveExec(pHlp, &pThisCC->VBoxSCSI, pSSM);
    20642110     }
    2065     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uNumQueues);
    2066     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uSegMax);
    2067     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uMaxSectors);
    2068     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uCmdPerLun);
    2069     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uEventInfoSize);
    2070     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uSenseSize);
    2071     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uCdbSize);
    2072     pHlp->pfnSSMPutU16(pSSM, pThis->virtioScsiConfig.uMaxChannel);
    2073     pHlp->pfnSSMPutU16(pSSM, pThis->virtioScsiConfig.uMaxTarget);
    2074     pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uMaxLun);
    2075     pHlp->pfnSSMPutU32(pSSM, pThis->fAsyncEvtsEnabled);
    2076     pHlp->pfnSSMPutBool(pSSM, pThis->fEventsMissed);
    2077     pHlp->pfnSSMPutU32(pSSM, pThis->fVirtioReady);
    2078     pHlp->pfnSSMPutU32(pSSM, pThis->fHasT10pi);
    2079     pHlp->pfnSSMPutU32(pSSM, pThis->fHasHotplug);
    2080     pHlp->pfnSSMPutU32(pSSM, pThis->fHasInOutBufs);
    2081     pHlp->pfnSSMPutU32(pSSM, pThis->fHasLunChange);
    2082     pHlp->pfnSSMPutU32(pSSM, pThis->fResetting);
    20832111
    20842112    /*
     
    21962224        return false;
    21972225
    2198     LogFunc(("Device I/O activity quiesced: enmQuiescingFor=%s\n",
     2226    LogFunc(("Device I/O activity quiesced: %s\n",
    21992227        virtioCoreGetStateChangeText(pThisCC->enmQuiescingFor)));
    22002228
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r82004 r82010  
    107107    switch (enmState)
    108108    {
    109         case kvirtIoVmStateChangedReset:                return "<VM RESET>";
    110         case kvirtIoVmStateChangedSuspend:              return "<VM SUSPEND>";
    111         case kvirtIoVmStateChangedPowerOff:             return "<VM POWEROFF>";
    112         case kvirtIoVmStateChangedResume:               return "<VM RESUME>";
     109        case kvirtIoVmStateChangedReset:                return "VM RESET";
     110        case kvirtIoVmStateChangedSuspend:              return "VM SUSPEND";
     111        case kvirtIoVmStateChangedPowerOff:             return "VM POWER OFF";
     112        case kvirtIoVmStateChangedResume:               return "VM RESUME";
    113113        default:                                        return "<BAD ENUM>";
    114114    }
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