VirtualBox

Changeset 24745 in vbox for trunk


Ignore:
Timestamp:
Nov 17, 2009 10:34:09 PM (15 years ago)
Author:
vboxsync
Message:

DevATA: Async reset handling, protect reset or we'll die.

File:
1 edited

Legend:

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

    r24741 r24745  
    52875287
    52885288/**
     5289 * Callback employed by ataSuspend and ataPowerOff.
     5290 *
     5291 * @returns true if we've quiesced, false if we're still working.
     5292 * @param   pDevIns     The device instance.
     5293 */
     5294static DECLCALLBACK(bool) ataR3IsAsyncResetDone(PPDMDEVINS pDevIns)
     5295{
     5296    PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
     5297
     5298    if (   !ataWaitForAsyncIOIsIdle(&pThis->aCts[0], 1, true /*fLeaveSignallingOn*/)
     5299        || !ataWaitForAsyncIOIsIdle(&pThis->aCts[1], 1, true /*fLeaveSignallingOn*/))
     5300        return false;
     5301
     5302    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
     5303    {
     5304        PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
     5305        for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
     5306            ataResetDevice(&pThis->aCts[i].aIfs[j]);
     5307        PDMCritSectLeave(&pThis->aCts[i].lock);
     5308    }
     5309    PDMDevHlpAsyncNotificationCompleted(pDevIns);
     5310    return true;
     5311}
     5312
     5313
     5314/**
    52895315 * Reset notification.
    52905316 *
     
    52985324    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
    52995325    {
     5326        PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
     5327
    53005328        pThis->aCts[i].iSelectedIf = 0;
    53015329        pThis->aCts[i].iAIOIf = 0;
     
    53155343        ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetARequest);
    53165344        ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetCRequest);
    5317 /** @todo Deadlock alert. see @bugref{4394}. */
    5318         if (!ataWaitForAsyncIOIsIdle(&pThis->aCts[i], 30000, false /*fLeaveSignallingOn*/))
    5319         {
    5320             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "DevATA_ASYNCBUSY",
    5321                                        N_("The IDE async I/O thread remained busy after a reset, usually a host filesystem performance problem\n"));
    5322             AssertMsgFailed(("Async I/O thread busy after reset\n"));
    5323         }
    5324 
    5325         for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
    5326             ataResetDevice(&pThis->aCts[i].aIfs[j]);
    5327     }
     5345
     5346        PDMCritSectLeave(&pThis->aCts[i].lock);
     5347    }
     5348
     5349    /*
     5350     * Only reset the devices when both threads have quiesced.
     5351     */
     5352    if (   ataWaitForAsyncIOIsIdle(&pThis->aCts[0], 2, true /*fLeaveSignallingOn*/)
     5353        && ataWaitForAsyncIOIsIdle(&pThis->aCts[1], 2, true /*fLeaveSignallingOn*/))
     5354        for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
     5355        {
     5356            PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
     5357            for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
     5358                ataResetDevice(&pThis->aCts[i].aIfs[j]);
     5359            PDMCritSectLeave(&pThis->aCts[i].lock);
     5360        }
     5361    else
     5362        PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncResetDone);
    53285363}
    53295364
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