VirtualBox

Changeset 37359 in vbox for trunk/src/VBox/Devices/USB


Ignore:
Timestamp:
Jun 7, 2011 5:12:57 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
72127
Message:

VUSB: Don't create the reset timer on the fly, it triggers lock order violations occasionally.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/VUSBDevice.cpp

    r35346 r37359  
    5858    /** User argument to pfnDone. */
    5959    void               *pvUser;
    60     /** The timer used to notify EMT. */
    61     PTMTIMER            pTimer;
    6260} VUSBRESETARGS, *PVUSBRESETARGS;
    6361
     
    11681166            PVUSBRESETARGS pArgs = (PVUSBRESETARGS)pDev->pvResetArgs;
    11691167            Assert(pArgs->pDev == pDev);
    1170             TMR3TimerDestroy(pArgs->pTimer);
    1171             pArgs->pTimer = NULL;
    11721168            RTMemTmpFree(pArgs);
    11731169
     
    11851181    RTMemFree(pDev->paIfStates);
    11861182    pDev->enmState = VUSB_DEVICE_STATE_DESTROYED;
     1183    TMR3TimerDestroy(pDev->pResetTimer);
    11871184}
    11881185
     
    12521249 * Timer callback for doing reset completion.
    12531250 *
     1251 * @param   pUsbIns     The USB device instance.
     1252 * @param   pTimer      The timer instance.
     1253 * @param   pvUser      The VUSB device data.
    12541254 * @thread EMT
    12551255 */
    1256 static DECLCALLBACK(void) vusbDevResetDoneTimer(void *pvUser)
    1257 {
    1258     PVUSBRESETARGS pArgs = (PVUSBRESETARGS)pvUser;
    1259     PVUSBDEV pDev = pArgs->pDev;
    1260     Assert(pDev->pvResetArgs == pArgs);
     1256static DECLCALLBACK(void) vusbDevResetDoneTimer(PPDMUSBINS pUsbIns, PTMTIMER pTimer, void *pvUser)
     1257{
     1258    PVUSBDEV        pDev  = (PVUSBDEV)pvUser;
     1259    PVUSBRESETARGS  pArgs = (PVUSBRESETARGS)pDev->pvResetArgs;
     1260    AssertPtr(pArgs); Assert(pArgs->pDev == pDev); Assert(pDev->pUsbIns == pUsbIns);
    12611261
    12621262    /*
     
    12661266    AssertRC(rc);
    12671267    pDev->hResetThread = NIL_RTTHREAD;
    1268     pDev->pvResetArgs = NULL;
     1268    pDev->pvResetArgs  = NULL;
    12691269
    12701270    /*
     
    12731273    vusbDevResetDone(pArgs->pDev, pArgs->rc, pArgs->pfnDone, pArgs->pvUser);
    12741274
    1275     TMR3TimerDestroy(pArgs->pTimer);
    12761275    RTMemTmpFree(pArgs);
    12771276}
     
    12911290{
    12921291    PVUSBRESETARGS  pArgs = (PVUSBRESETARGS)pvUser;
     1292    PVUSBDEV        pDev  = pArgs->pDev;
    12931293    LogFlow(("vusb: reset thread started\n"));
    12941294
     
    12961296     * Tell EMT that we're in flow and then perform the reset.
    12971297     */
    1298     uint64_t u64EndTS = TMTimerGet(pArgs->pTimer) + TMTimerFromMilli(pArgs->pTimer, 10);
     1298    uint64_t u64EndTS = TMTimerGet(pDev->pResetTimer) + TMTimerFromMilli(pDev->pResetTimer, 10);
    12991299    RTThreadUserSignal(Thread);
    13001300
    1301     int rc = pArgs->rc = vusbDevResetWorker(pArgs->pDev, pArgs->fResetOnLinux);
     1301    int rc = pArgs->rc = vusbDevResetWorker(pDev, pArgs->fResetOnLinux);
    13021302
    13031303    /*
     
    13061306     * us more accurate scheduling than making this thread sleep.
    13071307     */
    1308     int rc2 = TMTimerSet(pArgs->pTimer, u64EndTS);
     1308    int rc2 = TMTimerSet(pDev->pResetTimer, u64EndTS);
    13091309    AssertReleaseRC(rc2);
    13101310
     
    13181318 *
    13191319 * Since a device reset shall take at least 10ms from the guest point of view,
    1320  * it must be performed asynchronously. We create a thread which performs this
     1320 * it must be performed asynchronously.  We create a thread which performs this
    13211321 * operation and ensures it will take at least 10ms.
    13221322 *
     
    13711371        if (pArgs)
    13721372        {
    1373             pArgs->pTimer = TMR3TimerCreateExternal(pVM, TMCLOCK_VIRTUAL, vusbDevResetDoneTimer, pArgs, "USB Device Reset Timer.");
    1374             if (pArgs->pTimer)
     1373            pDev->pvResetArgs = pArgs;
     1374            pArgs->pDev = pDev;
     1375            pArgs->fResetOnLinux = fResetOnLinux;
     1376            pArgs->rc = VERR_INTERNAL_ERROR;
     1377            pArgs->pfnDone = pfnDone;
     1378            pArgs->pvUser = pvUser;
     1379            int rc = RTThreadCreate(&pDev->hResetThread, vusbDevResetThread, pArgs, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "USBRESET");
     1380            if (RT_SUCCESS(rc))
    13751381            {
    1376                 pDev->pvResetArgs = pArgs;
    1377                 pArgs->pDev = pDev;
    1378                 pArgs->fResetOnLinux = fResetOnLinux;
    1379                 pArgs->rc = VERR_INTERNAL_ERROR;
    1380                 pArgs->pfnDone = pfnDone;
    1381                 pArgs->pvUser = pvUser;
    1382                 int rc = RTThreadCreate(&pDev->hResetThread, vusbDevResetThread, pArgs, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "USBRESET");
    1383                 if (RT_SUCCESS(rc))
    1384                 {
    1385                     /* give the thread a chance to get started. */
    1386                     RTThreadUserWait(pDev->hResetThread, 2);
    1387                     return rc;
    1388                 }
    1389 
    1390                 pDev->pvResetArgs = NULL;
    1391                 pDev->hResetThread = NIL_RTTHREAD;
    1392                 TMR3TimerDestroy(pArgs->pTimer);
     1382                /* give the thread a chance to get started. */
     1383                RTThreadUserWait(pDev->hResetThread, 2);
     1384                return rc;
    13931385            }
     1386
     1387            pDev->pvResetArgs  = NULL;
     1388            pDev->hResetThread = NIL_RTTHREAD;
    13941389            RTMemTmpFree(pArgs);
    13951390        }
     
    15541549    pDev->hResetThread = NIL_RTTHREAD;
    15551550    pDev->pvResetArgs = NULL;
     1551    pDev->pResetTimer = NULL;
     1552
     1553    /*
     1554     * Create the reset timer.
     1555     */
     1556    int rc = PDMUsbHlpTMTimerCreate(pUsbIns, TMCLOCK_VIRTUAL, vusbDevResetDoneTimer, pDev, 0 /*fFlags*/,
     1557                                    "USB Device Reset Timer",  &pDev->pResetTimer);
     1558    AssertRCReturn(rc, rc);
    15561559
    15571560    /*
  • trunk/src/VBox/Devices/USB/VUSBInternal.h

    r35346 r37359  
    212212    /** Pointer to the reset thread arguments. */
    213213    void               *pvResetArgs;
     214    /** The reset timer handle. */
     215    PTMTIMER            pResetTimer;
    214216} VUSBDEV;
    215217
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