VirtualBox

Changeset 29910 in vbox


Ignore:
Timestamp:
May 31, 2010 2:04:26 PM (15 years ago)
Author:
vboxsync
Message:

PDMR3QueueFlushAll: Fixed race where we could leave unflushed items if an insert was completed right before clearing the active bit. Probably would require us to be preempted after the loop test for it to hit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMQueue.cpp

    r29905 r29910  
    671671     * flush are caught using the pending bit.
    672672     *
    673      * Note! The order in which the FF and pending bit are set and cleared is
    674      *       important.
     673     * Note! We must check the force action and pending flags after clearing
     674     *       the active bit!
    675675     */
    676676    VM_FF_CLEAR(pVM, VM_FF_PDM_QUEUES);
    677     if (!ASMAtomicBitTestAndSet(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_ACTIVE_BIT))
     677    while (!ASMAtomicBitTestAndSet(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_ACTIVE_BIT))
    678678    {
    679679        ASMAtomicBitClear(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT);
    680         do
    681         {
    682             VM_FF_CLEAR(pVM, VM_FF_PDM_QUEUES);
    683             for (PPDMQUEUE pCur = pVM->pUVM->pdm.s.pQueuesForced; pCur; pCur = pCur->pNext)
    684                 if (    pCur->pPendingR3
    685                     ||  pCur->pPendingR0
    686                     ||  pCur->pPendingRC)
    687                     pdmR3QueueFlush(pCur);
    688         } while (   ASMAtomicBitTestAndClear(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT)
    689                  || VM_FF_ISPENDING(pVM, VM_FF_PDM_QUEUES));
     680
     681        for (PPDMQUEUE pCur = pVM->pUVM->pdm.s.pQueuesForced; pCur; pCur = pCur->pNext)
     682            if (    pCur->pPendingR3
     683                ||  pCur->pPendingR0
     684                ||  pCur->pPendingRC)
     685                pdmR3QueueFlush(pCur);
    690686
    691687        ASMAtomicBitClear(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_ACTIVE_BIT);
     688
     689        /* We're done if there were no inserts while we were busy. */
     690        if (   !ASMBitTest(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT)
     691            && !VM_FF_ISPENDING(pVM, VM_FF_PDM_QUEUES))
     692            break;
     693        VM_FF_CLEAR(pVM, VM_FF_PDM_QUEUES);
    692694    }
    693695}
     
    708710     * Get the lists.
    709711     */
    710     PPDMQUEUEITEMCORE pItems = (PPDMQUEUEITEMCORE)ASMAtomicXchgPtr((void * volatile *)&pQueue->pPendingR3, NULL);
     712    PPDMQUEUEITEMCORE pItems   = (PPDMQUEUEITEMCORE)ASMAtomicXchgPtr((void * volatile *)&pQueue->pPendingR3, NULL);
    711713    RTRCPTR           pItemsRC = ASMAtomicXchgRCPtr(&pQueue->pPendingRC, NIL_RTRCPTR);
    712714    RTR0PTR           pItemsR0 = ASMAtomicXchgR0Ptr(&pQueue->pPendingR0, NIL_RTR0PTR);
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