VirtualBox

Changeset 20880 in vbox


Ignore:
Timestamp:
Jun 24, 2009 8:10:25 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
49026
Message:

Queue suspend and power off calls from the VM for SMP guests (deadlock prevention).

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/types.h

    r20804 r20880  
    109109 * Intended for scheduling a VM request or some other task. */
    110110#define VMCPUID_ANY         UINT32_C(0xfffffff4)
    111 /** Any virtual CPU except the current one.
     111/** Any virtual CPU; always queue for future execution.
    112112 * Intended for scheduling a VM request or some other task. */
    113 #define VMCPUID_OTHER       UINT32_C(0xfffffff5)
     113#define VMCPUID_ANY_QUEUE   UINT32_C(0xfffffff5)
    114114/** The NIL value. */
    115115#define NIL_VMCPUID         UINT32_C(0xfffffffd)
  • trunk/src/VBox/VMM/PDMDevHlp.cpp

    r20687 r20880  
    23352335{
    23362336    PDMDEV_ASSERT_DEVINS(pDevIns);
    2337     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     2337    PVM pVM = pDevIns->Internal.s.pVMR3;
     2338    VM_ASSERT_EMT(pVM);
    23382339    LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d:\n",
    23392340             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
    23402341
    2341     int rc = VMR3Suspend(pDevIns->Internal.s.pVMR3);
     2342    if (pVM->cCPUs > 1)
     2343    {
     2344        /* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
     2345        PVMREQ pReq;
     2346        int rc = VMR3ReqCallU(pVM->pUVM, VMCPUID_ANY_QUEUE, &pReq, 0, VMREQFLAGS_NO_WAIT,
     2347                            (PFNRT)VMR3Suspend, 1, pVM);
     2348        AssertRC(rc);
     2349        rc = VINF_EM_SUSPEND;
     2350    }
     2351    else
     2352        rc = VMR3Suspend(pVM);
    23422353
    23432354    LogFlow(("pdmR3DevHlp_VMSuspend: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
     
    23502361{
    23512362    PDMDEV_ASSERT_DEVINS(pDevIns);
    2352     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     2363    PVM pVM = pDevIns->Internal.s.pVMR3;
     2364    VM_ASSERT_EMT(pVM);
    23532365    LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d:\n",
    23542366             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
    23552367
    2356     int rc = VMR3PowerOff(pDevIns->Internal.s.pVMR3);
     2368    if (pVM->cCPUs > 1)
     2369    {
     2370        /* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
     2371        PVMREQ pReq;
     2372        int rc = VMR3ReqCallU(pVM->pUVM, VMCPUID_ANY_QUEUE, &pReq, 0, VMREQFLAGS_NO_WAIT,
     2373                            (PFNRT)VMR3PowerOff, 1, pVM);
     2374        AssertRC(rc);
     2375        rc = VINF_EM_OFF;
     2376    }
     2377    else
     2378        rc = VMR3PowerOff(pVM);
    23572379
    23582380    LogFlow(("pdmR3DevHlp_VMPowerOff: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
  • trunk/src/VBox/VMM/VMEmt.cpp

    r20864 r20880  
    137137                if (RT_FAILURE(rc))
    138138                {
    139                     AssertFailed();
     139                    AssertMsgFailed(("VMR3WaitU failed with %Rrc\n", rc));
    140140                    break;
    141141                }
     
    201201                if (RT_FAILURE(rc))
    202202                {
    203                     AssertFailed();
     203                    AssertMsgFailed(("VMR3WaitU failed with %Rrc\n", rc));
    204204                    break;
    205205                }
  • trunk/src/VBox/VMM/VMReq.cpp

    r20806 r20880  
    6363 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    6464 *                          one of the following special values:
    65  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     65 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    6666 * @param   ppReq           Where to store the pointer to the request.
    6767 *                          This will be NULL or a valid request pointer not matter what happends.
     
    9999 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    100100 *                          one of the following special values:
    101  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     101 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    102102 * @param   ppReq           Where to store the pointer to the request.
    103103 *                          This will be NULL or a valid request pointer not matter what happends.
     
    135135 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    136136 *                          one of the following special values:
    137  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     137 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    138138 * @param   ppReq           Where to store the pointer to the request.
    139139 *                          This will be NULL or a valid request pointer not matter what happends.
     
    171171 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    172172 *                          one of the following special values:
    173  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     173 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    174174 * @param   ppReq           Where to store the pointer to the request.
    175175 *                          This will be NULL or a valid request pointer not matter what happends, unless fFlags
     
    209209 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    210210 *                          one of the following special values:
    211  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     211 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    212212 * @param   ppReq           Where to store the pointer to the request.
    213213 *                          This will be NULL or a valid request pointer not matter what happends, unless fFlags
     
    247247 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    248248 *                          one of the following special values:
    249  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     249 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    250250 * @param   ppReq           Where to store the pointer to the request.
    251251 *                          This will be NULL or a valid request pointer not matter what happends, unless fFlags
     
    386386 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    387387 *                          one of the following special values:
    388  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     388 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    389389 */
    390390VMMR3DECL(int) VMR3ReqAlloc(PVM pVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu)
     
    407407 * @param   idDstCpu        The destination CPU(s). Either a specific CPU ID or
    408408 *                          one of the following special values:
    409  *                              VMCPUID_ANY, VMCPUID_OTHER, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
     409 *                              VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
    410410 */
    411411VMMR3DECL(int) VMR3ReqAllocU(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu)
     
    420420    AssertPtrReturn(ppReq, VERR_INVALID_POINTER);
    421421    AssertMsgReturn(    idDstCpu == VMCPUID_ANY
    422                     ||  idDstCpu == VMCPUID_OTHER
     422                    ||  idDstCpu == VMCPUID_ANY_QUEUE
    423423                    ||  idDstCpu < pUVM->cCpus
    424424                    ||  idDstCpu == VMCPUID_ALL
     
    676676    }
    677677    else if (   pReq->idDstCpu != VMCPUID_ANY   /* for a specific VMCPU? */
    678              && pReq->idDstCpu != VMCPUID_OTHER
     678             && pReq->idDstCpu != VMCPUID_ANY_QUEUE
    679679             && (   !pUVCpu                     /* and it's not the current thread. */
    680680                 || pUVCpu->idCpu != pReq->idDstCpu))
     
    715715    else if (   (    pReq->idDstCpu == VMCPUID_ANY
    716716                 && !pUVCpu /* only EMT threads have a valid pointer stored in the TLS slot. */)
    717              || pReq->idDstCpu == VMCPUID_OTHER)
     717             || pReq->idDstCpu == VMCPUID_ANY_QUEUE)
    718718    {
    719719        unsigned fFlags = ((VMREQ volatile *)pReq)->fFlags;     /* volatile paranoia */
    720720
    721         Assert(pReq->idDstCpu != VMCPUID_OTHER || pUVCpu);
     721        Assert(pReq->idDstCpu != VMCPUID_ANY_QUEUE || pUVCpu);
    722722
    723723        /*
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