VirtualBox

Changeset 19265 in vbox for trunk/src/VBox/VMM/VM.cpp


Ignore:
Timestamp:
Apr 29, 2009 2:11:45 PM (16 years ago)
Author:
vboxsync
Message:

SMP cleanup fixes.

File:
1 edited

Legend:

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

    r19257 r19265  
    16271627    {
    16281628        /*
    1629          * Request EMT to do the larger part of the destruction.
     1629         * Request EMT to do the larger part of the destruction. (in reverse order as VCPU 0 does the real cleanup)
    16301630         */
    1631         PVMREQ pReq = NULL;
    1632         int rc = VMR3ReqCallU(pUVM, VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)vmR3Destroy, 1, pVM);
    1633         if (RT_SUCCESS(rc))
    1634             rc = pReq->iStatus;
    1635         AssertRC(rc);
    1636         VMR3ReqFree(pReq);
     1631        for (int idCpu = pVM->cCPUs - 1;idCpu>=0;idCpu--)
     1632        {
     1633            PVMREQ pReq = NULL;
     1634            int rc = VMR3ReqCallU(pUVM, (VMREQDEST)idCpu, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)vmR3Destroy, 1, pVM);
     1635            if (RT_SUCCESS(rc))
     1636                rc = pReq->iStatus;
     1637            AssertRC(rc);
     1638            VMR3ReqFree(pReq);
     1639        }
    16371640
    16381641        /*
     
    16591662{
    16601663    PUVM pUVM = pVM->pUVM;
     1664    PVMCPU pVCpu = VMMGetCpu(pVM);
     1665
    16611666    NOREF(pUVM);
    16621667    LogFlow(("vmR3Destroy: pVM=%p pUVM=%p\n", pVM, pUVM));
    16631668    VM_ASSERT_EMT(pVM);
     1669
     1670    /* Only VCPU 0 does the full cleanup. */
     1671    if (pVCpu->idCpu != 0)
     1672        return VINF_EM_TERMINATE;
    16641673
    16651674    /*
     
    17391748    if (pUVM->pVM)
    17401749    {
     1750        PVMCPU pVCpu = VMMGetCpu(pUVM->pVM);
     1751
     1752        /* VCPU 0 does all the cleanup work. */
     1753        if (pVCpu->idCpu != 0)
     1754            return;
     1755
    17411756        /*
    17421757         * Modify state and then terminate MM.
     
    18581873    }
    18591874
     1875    /*
     1876     * Now all queued VCPU requests (again, there shouldn't be any).
     1877     */
     1878    for (VMCPUID i = 0; i < pUVM->cCpus; i++)
     1879    {
     1880        PUVMCPU pUVCpu = &pUVM->aCpus[i];
     1881
     1882        for (unsigned i = 0; i < 10; i++)
     1883        {
     1884            PVMREQ pReqHead = (PVMREQ)ASMAtomicXchgPtr((void *volatile *)&pUVCpu->vm.s.pReqs, NULL);
     1885            AssertMsg(!pReqHead, ("This isn't supposed to happen! VMR3Destroy caller has to serialize this.\n"));
     1886            if (!pReqHead)
     1887                break;
     1888            for (PVMREQ pReq = pReqHead; pReq; pReq = pReq->pNext)
     1889            {
     1890                ASMAtomicUoWriteSize(&pReq->iStatus, VERR_INTERNAL_ERROR);
     1891                ASMAtomicWriteSize(&pReq->enmState, VMREQSTATE_INVALID);
     1892                RTSemEventSignal(pReq->EventSem);
     1893                RTThreadSleep(2);
     1894                RTSemEventDestroy(pReq->EventSem);
     1895            }
     1896            /* give them a chance to respond before we free the request memory. */
     1897            RTThreadSleep(32);
     1898        }
     1899    }
     1900
    18601901    /*
    18611902     * Make sure the VMMR0.r0 module and whatever else is unloaded.
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