VirtualBox

Changeset 103681 in vbox


Ignore:
Timestamp:
Mar 5, 2024 1:55:44 PM (13 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162046
Message:

DevXHCI: Fixed a rare race condition which could miss a ringing doorbell. Also added more debugging code (not compiled by default) and print doorbell state in VM debugger (see bugref:10113).

File:
1 edited

Legend:

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

    r99739 r103681  
    16041604#endif
    16051605
    1606     /** Flag indicating a sleeping worker thread. */
    1607     volatile bool                   fWrkThreadSleeping;
     1606    /** Flag indicating a pending worker thread notification. */
     1607    volatile bool                   fNotificationSent;
    16081608    volatile bool                   afPadding[3];
    16091609
     
    21662166
    21672167    /* Tell the worker thread there's something to do. */
    2168     if (ASMAtomicReadBool(&pThis->fWrkThreadSleeping))
     2168    if (!ASMAtomicXchgBool(&pThis->fNotificationSent, true))
    21692169    {
    21702170        LogFlowFunc(("Signal event semaphore\n"));
     
    43534353
    43544354        /* Abort the endpoint, i.e. cancel any outstanding URBs. This needs to be done after
    4355          * writing back the EP state so that the completion callback can operate.
     4355         * writing back the EP state so that the completion callback can operate. Note that
     4356         * the completion callback will not modify the TR when it sees that the EP is not in
     4357         * the 'running' state.
     4358         * NB: If a URB is canceled before it completed, we have no way to tell if any data
     4359         * was already (partially) transferred.
    43564360         */
    43574361        if (RT_SUCCESS(xhciR3FindRhDevBySlot(pDevIns, pThis, pThisCC, uSlotID, &pRh, &uPort)))
     
    43644368        }
    43654369
    4366         /// @todo The completion callbacks should do more work for canceled URBs.
    43674370        /* Once the completion callbacks had a chance to run, we have to adjust
    43684371         * the endpoint state.
     
    43724375        PDMDevHlpPCIPhysReadMeta(pDevIns, GCPhysEndp, &endp_ctx, sizeof(endp_ctx));
    43734376
     4377        /* If the enqueue and dequeue pointers are different, a transfer was
     4378         * in progress.
     4379         */
    43744380        bool fXferWasInProgress = endp_ctx.trep != endp_ctx.trdp;
    43754381
     
    52535259    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    52545260    {
    5255         uint32_t    u32Tasks = 0;
    52565261        uint8_t     uSlotID;
    52575262
    5258         ASMAtomicWriteBool(&pThis->fWrkThreadSleeping, true);
    5259         u32Tasks = ASMAtomicXchgU32(&pThis->u32TasksNew, 0);
    5260         if (!u32Tasks)
    5261         {
    5262             Assert(ASMAtomicReadBool(&pThis->fWrkThreadSleeping));
     5263        bool fNotificationSent = ASMAtomicXchgBool(&pThis->fNotificationSent, false);
     5264        if (!fNotificationSent)
     5265        {
    52635266            rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->hEvtProcess, RT_INDEFINITE_WAIT);
    52645267            AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), rc);
     
    52665269                break;
    52675270            LogFlowFunc(("Woken up with rc=%Rrc\n", rc));
    5268             u32Tasks = ASMAtomicXchgU32(&pThis->u32TasksNew, 0);
     5271            ASMAtomicWriteBool(&pThis->fNotificationSent, false);
    52695272        }
    52705273
     
    53065309
    53075310        RTCritSectLeave(&pThisCC->CritSectThrd);
    5308 
    5309         ASMAtomicWriteBool(&pThis->fWrkThreadSleeping, false);
    53105311    } /* While running */
    53115312
     
    75667567        return;
    75677568    }
     7569
     7570    if (pszArgs && strstr(pszArgs, "genintrhw"))
     7571    {
     7572        pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (external)...\n");
     7573        int iIntr = 0;
     7574        PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
     7575        xhciSetIntr(pDevIns, pThis, pIntr);
     7576        return;
     7577    }
     7578
     7579    if (pszArgs && strstr(pszArgs, "genintrint"))
     7580    {
     7581        pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (internal)...\n");
     7582        int iIntr = 0;
     7583        PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
     7584        xhciR3SetIntrPending(pDevIns, pThis, pIntr);
     7585        return;
     7586    }
     7587
     7588    if (pszArgs && strstr(pszArgs, "genintrhw"))
     7589    {
     7590        pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (external)...\n");
     7591        int iIntr = 0;
     7592        PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
     7593        xhciSetIntr(pDevIns, pThis, pIntr);
     7594        return;
     7595    }
     7596
     7597    if (pszArgs && strstr(pszArgs, "genintrint"))
     7598    {
     7599        pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (internal)...\n");
     7600        int iIntr = 0;
     7601        PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
     7602        xhciR3SetIntrPending(pDevIns, pThis, pIntr);
     7603        return;
     7604    }
     7605
     7606    if (pszArgs && strstr(pszArgs, "genportchgevt"))
     7607    {
     7608        pHlp->pfnPrintf(pHlp, "Generating port change event...\n");
     7609        int iPort = 0;
     7610        xhciR3GenPortChgEvent(pDevIns, pThis, IDX_TO_ID(iPort));
     7611        return;
     7612    }
     7613
     7614    if (pszArgs && strstr(pszArgs, "genmfiwrapevt"))
     7615    {
     7616        pHlp->pfnPrintf(pHlp, "Generating MF Index wrap event...\n");
     7617        XHCI_EVENT_TRB  ed;
     7618        RT_ZERO(ed);
     7619        ed.mwe.cc   = XHCI_TCC_SUCCESS;
     7620        ed.mwe.type = XHCI_TRB_MFIDX_WRAP;
     7621        xhciR3WriteEvent(pDevIns, pThis, &ed, XHCI_PRIMARY_INTERRUPTER, false);
     7622        return;
     7623    }
     7624
     7625    if (pszArgs && strstr(pszArgs, "gendoorbell"))
     7626    {
     7627        pHlp->pfnPrintf(pHlp, "Generating doorbell ring..\n");
     7628        xhciKickWorker(pDevIns, pThis, XHCI_JOB_DOORBELL, 0);
     7629        return;
     7630    }
    75687631#endif
    75697632
     
    77327795                pHlp->pfnPrintf(pHlp, "  Speed:%u Entries:%u RhPort:%u", ctxSlot.speed, ctxSlot.ctx_ent, ctxSlot.rh_port);
    77337796                pHlp->pfnPrintf(pHlp, " Address:%u State:%s \n", ctxSlot.dev_addr, pcszDesc);
     7797                pHlp->pfnPrintf(pHlp, "  Doorbells:%08X\n", pThis->aBellsRung[ID_TO_IDX(uSlotID)]);
    77347798
    77357799                /* Endpoint contexts. */
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