VirtualBox

Changeset 52878 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 28, 2014 5:05:33 PM (10 years ago)
Author:
vboxsync
Message:

USB: Fix lock order violation when canceling all URBs

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

Legend:

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

    r52301 r52878  
    371371    /** Event semaphore to interact with the framer thread. */
    372372    R3PTRTYPE(RTSEMEVENT) hSemEventFrame;
     373    /** Event semaphore to release the thread waiting for the framer thread to stop. */
     374    R3PTRTYPE(RTSEMEVENTMULTI) hSemEventFrameStopped;
    373375    /** Flag whether the framer thread should processing frames. */
    374376    volatile bool         fBusStarted;
     
    793795static void                 rhport_power(POHCIROOTHUB pRh, unsigned iPort, bool fPowerUp);
    794796static void                 ohciBusResume(POHCI ohci, bool fHardware);
     797static void                 ohciBusStop(POHCI pThis);
    795798
    796799static DECLCALLBACK(void)   ohciRhXferCompletion(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb);
     
    11111114         fResetOnLinux ? " (reset on linux)" : ""));
    11121115
     1116    /* Stop the bus in any case, disabling walking the lists. */
     1117    ohciBusStop(pThis);
     1118
    11131119    /*
    11141120     * Cancel all outstanding URBs.
     
    11271133    else
    11281134        pThis->ctl &= OHCI_CTL_IR | OHCI_CTL_RWC;       /* IR and RWC are preserved on software reset. */
     1135
     1136    /* Clear the HCFS bits first to make setting the new state work. */
     1137    pThis->ctl &= ~OHCI_CTL_HCFS;
    11291138    pThis->ctl |= fNewMode;
    11301139    pThis->status = 0;
     
    38363845               && pThread->enmState == PDMTHREADSTATE_RUNNING
    38373846               && RT_SUCCESS(rc))
     3847        {
     3848            /* Signal the waiter that we are stopped now. */
     3849            rc = RTSemEventMultiSignal(pThis->hSemEventFrameStopped);
     3850            AssertRC(rc);
    38383851            rc = RTSemEventWait(pThis->hSemEventFrame, RT_INDEFINITE_WAIT);
     3852        }
    38393853
    38403854        AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc), rc);
     
    39053919
    39063920    pThis->SofTime = PDMDevHlpTMTimeVirtGet(pThis->CTX_SUFF(pDevIns));
    3907     ASMAtomicXchgBool(&pThis->fBusStarted, true);
    3908     RTSemEventSignal(pThis->hSemEventFrame);
     3921    bool fBusActive = ASMAtomicXchgBool(&pThis->fBusStarted, true);
     3922    if (!fBusActive)
     3923        RTSemEventSignal(pThis->hSemEventFrame);
    39093924}
    39103925
     
    39143929static void ohciBusStop(POHCI pThis)
    39153930{
    3916     ASMAtomicXchgBool(&pThis->fBusStarted, false);
    3917     RTSemEventSignal(pThis->hSemEventFrame);
     3931    bool fBusActive = ASMAtomicXchgBool(&pThis->fBusStarted, false);
     3932    if (fBusActive)
     3933    {
     3934        int rc = RTSemEventMultiReset(pThis->hSemEventFrameStopped);
     3935        AssertRC(rc);
     3936
     3937        /* Signal the frame thread to stop. */
     3938        RTSemEventSignal(pThis->hSemEventFrame);
     3939
     3940        /* Wait for signal from the thrad that it stopped. */
     3941        rc = RTSemEventMultiWait(pThis->hSemEventFrameStopped, RT_INDEFINITE_WAIT);
     3942        AssertRC(rc);
     3943    }
    39183944    VUSBIDevPowerOff(pThis->RootHub.pIDev);
    39193945}
     
    55165542     *            just one way of getting into the UsbReset state.
    55175543     */
    5518     ohciBusStop(pThis);
    55195544    ohciDoReset(pThis, OHCI_USB_RESET, true /* reset devices */);
    55205545}
     
    56335658     * Destroy event sempahores.
    56345659     */
    5635     RTSemEventDestroy(pThis->hSemEventFrame);
     5660    if (pThis->hSemEventFrame)
     5661        RTSemEventDestroy(pThis->hSemEventFrame);
     5662    if (pThis->hSemEventFrameStopped)
     5663        RTSemEventMultiDestroy(pThis->hSemEventFrameStopped);
    56365664    if (RTCritSectIsInitialized(&pThis->CritSect))
    56375665        RTCritSectDelete(&pThis->CritSect);
     
    57895817
    57905818    rc = RTSemEventCreate(&pThis->hSemEventFrame);
     5819    AssertRCReturn(rc, rc);
     5820
     5821    rc = RTSemEventMultiCreate(&pThis->hSemEventFrameStopped);
    57915822    AssertRCReturn(rc, rc);
    57925823
  • trunk/src/VBox/Devices/USB/DrvVUSBRootHub.cpp

    r52301 r52878  
    609609    /*
    610610     * Cancel the URBS.
    611      */
    612     RTCritSectEnter(&pDev->CritSectAsyncUrbs);
     611     *
     612     * Not using th CritAsyncUrbs critical section here is safe
     613     * as the I/O thread is the only thread accessing this struture at the
     614     * moment.
     615     */
    613616    PVUSBURB pUrb = pDev->pAsyncUrbHead;
    614617
     
    620623        pUrb = pNext;
    621624    }
    622     RTCritSectLeave(&pDev->CritSectAsyncUrbs);
    623625
    624626    return VINF_SUCCESS;
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