VirtualBox

Changeset 24098 in vbox for trunk


Ignore:
Timestamp:
Oct 26, 2009 11:22:39 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53983
Message:

DevLsiLogic,DrvSCSI: Added new DrvSCSI method for synchronizing the requst queue. Useful for the lsilogicReset case. Dropped the lsilogicPowerOff and lsilogicSuspend waits as DrvSCSI will suspend on its own because it's a PDM thread. Fixed regression from recent saved state change.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmifs.h

    r23185 r24098  
    25562556     *
    25572557     * @returns VBox status code.
    2558      * @param   pInterface    Pointer to this interface.
    2559      * @param   pSCSIRequest  Pointer to the SCSI request to execute.
     2558     * @param   pInterface      Pointer to this interface.
     2559     * @param   pSCSIRequest    Pointer to the SCSI request to execute.
    25602560     */
    25612561     DECLR3CALLBACKMEMBER(int, pfnSCSIRequestSend, (PPDMISCSICONNECTOR pInterface, PPDMSCSIREQUEST pSCSIRequest));
     2562
     2563    /**
     2564     * Wait for all current requests to complete.
     2565     *
     2566     * This can only be called while the VM is running.
     2567     *
     2568     * @returns VINF_SUCCESS, VERR_NO_MEMORY, VERR_INVALID_STATE or VERR_TIMEOUT.
     2569     * @param   pInterface      Pointer to this interface.
     2570     * @param   cMillies        The timeout in milliseconds or RT_INDEFINITE_WAIT.
     2571     */
     2572     DECLR3CALLBACKMEMBER(int, pfnSyncronizeRequests, (PPDMISCSICONNECTOR pInterface, uint32_t cMillies));
    25622573
    25632574} PDMISCSICONNECTOR;
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r24071 r24098  
    23812381    pThis->cMaxBuses    = 1;
    23822382    pThis->cbReplyFrame = 128; /* @todo Figure out where it is needed. */
    2383     /* @todo: Put stuff to reset here. */
     2383    /** @todo: Put stuff to reset here. */
    23842384
    23852385    lsilogicInitializeConfigurationPages(pThis);
     
    47864786 * @retruns Flag which indicates if all I/O completed in the given timeout.
    47874787 * @param   pLsiLogic    Pointer to the dveice instance to check.
    4788  * @param   cMillis      Timeout in milliseconds to wait.
     4788 * @param   cMillis      Timeout in milliseconds to wait per device.
    47894789 */
    47904790static bool lsilogicWaitForAsyncIOFinished(PLSILOGICSCSI pLsiLogic, unsigned cMillies)
    47914791{
    47924792    uint64_t u64Start;
    4793     bool     fIdle;
     4793    unsigned i;
    47944794
    47954795    /*
     
    47994799    for (;;)
    48004800    {
    4801         fIdle = true;
    4802 
    48034801        /* Check every port. */
    4804         for (unsigned i = 0; i < RT_ELEMENTS(pLsiLogic->aDeviceStates); i++)
    4805         {
    4806             PLSILOGICDEVICE pLsiLogicDevice = &pLsiLogic->aDeviceStates[i];
    4807             if (ASMAtomicReadU32(&pLsiLogicDevice->cOutstandingRequests))
    4808             {
    4809                 fIdle = false;
     4802        for (i = 0; i < RT_ELEMENTS(pLsiLogic->aDeviceStates); i++)
     4803            if (ASMAtomicReadU32(&pLsiLogic->aDeviceStates[i].cOutstandingRequests))
    48104804                break;
    4811             }
    4812         }
    4813         if (   fIdle
    4814             || RTTimeMilliTS() - u64Start >= cMillies)
    4815             break;
    4816 
    4817         /* Sleep for a bit. */
    4818         RTThreadSleep(100); /** @todo wait on something which can be woken up. 100ms is too long for teleporting VMs! */
    4819     }
    4820 
    4821     return fIdle;
     4805        if (i >= RT_ELEMENTS(pLsiLogic->aDeviceStates))
     4806            return true;
     4807
     4808        uint64_t cMsElapsed = RTTimeMilliTS() - u64Start;
     4809        if (cMsElapsed >= cMillies)
     4810            return false;
     4811
     4812        /* Try synchronize the request queue for this device. */
     4813        PPDMISCSICONNECTOR pDrvSCSIConnector = pLsiLogic->aDeviceStates[i].pDrvSCSIConnector;
     4814        uint32_t cMsLeft = cMillies - (uint32_t)cMsElapsed;
     4815        pDrvSCSIConnector->pfnSyncronizeRequests(pDrvSCSIConnector, RT_MAX(cMsLeft, 100));
     4816    }
    48224817}
    48234818
     
    48334828}
    48344829
    4835 static DECLCALLBACK(int) lsilogicSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     4830static DECLCALLBACK(int) lsilogicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    48364831{
    48374832    PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    48384833
    4839     /* Wait that no task is pending on any device. */
    4840     if (!lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000))
    4841     {
    4842         AssertLogRelMsgFailed(("LsiLogic: There are still tasks outstanding\n"));
    4843         return VERR_TIMEOUT;
    4844     }
    4845 
    4846     return VINF_SUCCESS;
    4847 }
    4848 
    4849 static DECLCALLBACK(int) lsilogicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    4850 {
    4851     PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    4852 
    48534834    /* Every device first. */
    4854     lsilogicSaveLoadPrep(pDevIns, pSSM);
     4835    lsilogicLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
    48554836    for (unsigned i = 0; i < RT_ELEMENTS(pLsiLogic->aDeviceStates); i++)
    48564837    {
     
    51725153
    51735154/**
    5174  * @copydoc FNPDMDEVPOWEROFF
    5175  */
    5176 static DECLCALLBACK(void) lsilogicPowerOff(PPDMDEVINS pDevIns)
    5177 {
    5178     PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    5179 
    5180     bool fIdle = lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000);
    5181     Assert(fIdle);
    5182 }
    5183 
    5184 /**
    5185  * @copydoc FNPDMDEVSUSPEND
    5186  */
    5187 static DECLCALLBACK(void) lsilogicSuspend(PPDMDEVINS pDevIns)
    5188 {
    5189     PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    5190 
    5191     bool fIdle = lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000);
    5192     Assert(fIdle);
    5193 }
    5194 
    5195 /**
    51965155 * @copydoc FNPDMDEVRESET
    51975156 */
     
    52015160    int rc;
    52025161
     5162/** @todo r=bird: this is a deadlock trap. We're EMT(0), if there are
     5163 *        outstanding requests they may require EMT interaction because of
     5164 *        physical write backs around lsilogicDeviceSCSIRequestCompleted...
     5165 *
     5166 *        I have some more generic solution for delayed suspend, reset and
     5167 *        poweroff handling that I'm considering.  The idea is that the
     5168 *        notification callback returns a status indicating that it didn't
     5169 *        complete and needs to be called again or something.  EMT continues on
     5170 *        the next device and when it's done, it processes incoming requests and
     5171 *        does another notification round... This way we could combine the waits
     5172 *        in the I/O controllers and reduce the time it takes to suspend a VM a
     5173 *        wee bit...
     5174 */
    52035175    bool fIdle = lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000);
    52045176    Assert(fIdle);
     
    54495421
    54505422    /* Register save state handlers. */
    5451     rc = PDMDevHlpSSMRegisterEx(pDevIns, LSILOGIC_SAVED_STATE_VERSION, sizeof(*pThis), NULL,
    5452                                 NULL,                 lsilogicLiveExec, NULL,
    5453                                 lsilogicSaveLoadPrep, lsilogicSaveExec, NULL,
    5454                                 lsilogicSaveLoadPrep, lsilogicLoadExec, NULL);
     5423    rc = PDMDevHlpSSMRegister3(pDevIns, LSILOGIC_SAVED_STATE_VERSION, sizeof(*pThis),
     5424                               lsilogicLiveExec, lsilogicSaveExec, lsilogicLoadExec);
    54555425    if (RT_FAILURE(rc))
    54565426        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot register save state handlers"));
     
    55035473    lsilogicReset,
    55045474    /* pfnSuspend */
    5505     lsilogicSuspend,
     5475    NULL,
    55065476    /* pfnResume */
    55075477    NULL,
     
    55155485    NULL,
    55165486    /* pfnPowerOff */
    5517     lsilogicPowerOff,
     5487    NULL,
    55185488    /* pfnSoftReset */
    55195489    NULL,
  • trunk/src/VBox/Devices/Storage/DrvSCSI.cpp

    r23472 r24098  
    671671
    672672/**
     673 * Request function to syncronize the request execution.
     674 *
     675 * @returns VINF_SUCCESS.
     676 */
     677static int drvscsiAsyncIOLoopSyncCallback(void)
     678{
     679    return VINF_SUCCESS;
     680}
     681
     682/**
    673683 * Request function to wakeup the thread.
    674684 *
     
    716726    rc = RTReqCall(pThis->pQueueRequests, &pReq, 10000 /* 10 sec. */, (PFNRT)drvscsiAsyncIOLoopWakeupFunc, 0);
    717727    AssertMsgRC(rc, ("Inserting request into queue failed rc=%Rrc\n", rc));
     728    if (RT_SUCCESS(rc))
     729        RTReqFree(pReq);
     730    /*else: leak it */
    718731
    719732    return rc;
     
    735748
    736749    return VINF_SUCCESS;
     750}
     751
     752/** @copydoc PDMISCSICONNECTOR::pfnSyncronizeRequests. */
     753static DECLCALLBACK(int) drvscsiSyncronizeRequests(PPDMISCSICONNECTOR pInterface, uint32_t cMillies)
     754{
     755    int rc;
     756    PDRVSCSI pThis = PDMISCSICONNECTOR_2_DRVSCSI(pInterface);
     757    PRTREQ pReq;
     758
     759    Assert(cMillies > 100);
     760    AssertReturn(pThis->pQueueRequests, VERR_INVALID_STATE);
     761
     762    rc = RTReqCall(pThis->pQueueRequests, &pReq, cMillies, (PFNRT)drvscsiAsyncIOLoopSyncCallback, 0);
     763    AssertMsgRC(rc, ("Inserting request into queue failed rc=%Rrc\n", rc));
     764    if (RT_SUCCESS(rc))
     765        RTReqFree(pReq);
     766    /*else: leak it */
     767
     768    return rc;
    737769}
    738770
     
    794826    pDrvIns->IBase.pfnQueryInterface                    = drvscsiQueryInterface;
    795827    pThis->ISCSIConnector.pfnSCSIRequestSend            = drvscsiRequestSend;
     828    pThis->ISCSIConnector.pfnSyncronizeRequests         = drvscsiSyncronizeRequests;
    796829
    797830    /*
     
    904937    NULL,
    905938    /* pfnDetach */
    906     NULL, 
     939    NULL,
    907940    /* pfnPowerOff */
    908     NULL, 
     941    NULL,
    909942    /* pfnSoftReset */
    910943    NULL,
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette