VirtualBox

Changeset 247 in vbox


Ignore:
Timestamp:
Jan 23, 2007 5:10:04 PM (18 years ago)
Author:
vboxsync
Message:

Out of memory reporting for dynamic memory allocation case.

Location:
trunk/src/VBox/VMM
Files:
7 edited

Legend:

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

    r107 r247  
    407407 *
    408408 * @returns VBox status code.
    409  * @param   pVM         The VM handle.
    410  * @param   pv          Pointer to memory range which shall be locked down.
    411  *                      This pointer is page aligned.
    412  * @param   cb          Size of memory range (in bytes). This size is page aligned.
    413  * @param   eType       Memory type.
    414  * @param   ppLockedMem Where to store the pointer to the created locked memory record.
    415  *                      This is optional, pass NULL if not used.
    416  */
    417 int mmr3LockMem(PVM pVM, void *pv, size_t cb, MMLOCKEDTYPE eType, PMMLOCKEDMEM *ppLockedMem)
     409 * @param   pVM             The VM handle.
     410 * @param   pv              Pointer to memory range which shall be locked down.
     411 *                          This pointer is page aligned.
     412 * @param   cb              Size of memory range (in bytes). This size is page aligned.
     413 * @param   eType           Memory type.
     414 * @param   ppLockedMem     Where to store the pointer to the created locked memory record.
     415 *                          This is optional, pass NULL if not used.
     416 * @param   fSilentFailure  Don't raise an error when unsuccessful. Upper layer with deal with it.
     417 */
     418int mmr3LockMem(PVM pVM, void *pv, size_t cb, MMLOCKEDTYPE eType, PMMLOCKEDMEM *ppLockedMem, bool fSilentFailure)
    418419{
    419420    Assert(RT_ALIGN_P(pv, PAGE_SIZE) == pv);
     
    465466        AssertMsgFailed(("SUPPageLock failed with rc=%d\n", rc));
    466467        MMR3HeapFree(pLockedMem);
    467         rc = VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to lock %d bytes of host memory (out of memory)"), cb);
     468        if (!fSilentFailure)
     469            rc = VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to lock %d bytes of host memory (out of memory)"), cb);
    468470    }
    469471
  • trunk/src/VBox/VMM/MMInternal.h

    r161 r247  
    656656int  mmR3HyperInitPaging(PVM pVM);
    657657
    658 int  mmr3LockMem(PVM pVM, void *pv, size_t cb, MMLOCKEDTYPE eType, PMMLOCKEDMEM *ppLockedMem);
     658int  mmr3LockMem(PVM pVM, void *pv, size_t cb, MMLOCKEDTYPE eType, PMMLOCKEDMEM *ppLockedMem, bool fSilentFailure = false);
    659659int  mmr3MapLocked(PVM pVM, PMMLOCKEDMEM pLockedMem, RTGCPTR Addr, unsigned iPage, size_t cPages, unsigned fFlags);
    660660
  • trunk/src/VBox/VMM/MMPhys.cpp

    r23 r247  
    148148         */
    149149        PMMLOCKEDMEM    pLockedMem;
    150         rc = mmr3LockMem(pVM, pvRam, cb, MM_LOCKED_TYPE_PHYS, &pLockedMem);
     150        rc = mmr3LockMem(pVM, pvRam, cb, MM_LOCKED_TYPE_PHYS, &pLockedMem, (enmType == MM_PHYS_TYPE_DYNALLOC_CHUNK) ? false : true /* fSilentFailure */);
    151151        if (VBOX_SUCCESS(rc))
    152152        {
     
    182182        }
    183183        /* Cleanup is done in VM destruction to which failure of this function will lead. */
     184        /* Not true in case of MM_PHYS_TYPE_DYNALLOC_CHUNK */
    184185    }
    185186
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r80 r247  
    376376        if (VBOX_SUCCESS(rc))
    377377            return rc;
     378
    378379        SUPPageFree(pvRam);
     380
     381        LogRel(("pgmr3PhysGrowRange: out of memory. pause until the user resumes execution.\n"));
     382        VMSetRuntimeError(pVM, false, "HostMemoryLow", "Unable to allocate and lock memory. The virtual machine will be paused. Please close applications to free up memory or save and close the VM.");
     383 
     384        rc = VMR3Suspend(pVM);
     385        AssertRC(rc);
     386
     387        /* Wait for resume event; will only return in that case. If the VM is stopped, the EMT thread will be destroyed. */
     388        rc = VMR3WaitForResume(pVM);
     389
     390        /* Retry */
     391        LogRel(("pgmr3PhysGrowRange: VM execution resumed -> retry.\n"));
     392        return pgmr3PhysGrowRange(pVM, GCPhys);
     393       
    379394    }
    380395    return rc;
  • trunk/src/VBox/VMM/VMEmt.cpp

    r23 r247  
    6868    for (;;)
    6969    {
     70        /* Requested to exit the EMT thread out of sync? (currently only VMR3WaitForResume) */
     71        if (setjmp(pVM->vm.s.emtJumpEnv) != 0)
     72            break;
    7073
    7174        /*
     
    126129         * Some requests (both VMR3Req* and the DBGF) can potentially
    127130         * resume or start the VM, in that case we'll get a change in
    128          * VM status indicating that we're no running.
     131         * VM status indicating that we're now running.
    129132         */
    130133        if (    VBOX_SUCCESS(rc)
     
    140143
    141144    /*
    142      * Exitting.
     145     * Exiting.
    143146     */
    144147    Log(("vmR3EmulationThread: Terminating emulation thread! Thread=%#x pVM=%p rc=%Vrc enmBefore=%d enmVMState=%d\n",
     
    159162}
    160163
     164/**
     165 * Wait for VM to be resumed. Handle events like vmR3EmulationThread does.
     166 * In case the VM is stopped, clean up and long jump to the main EMT loop.
     167 *
     168 * @returns VINF_SUCCESS or doesn't return
     169 * @param   pVM             VM handle.
     170 */
     171VMR3DECL(int) VMR3WaitForResume(PVM pVM)
     172{
     173    /*
     174     * The request loop.
     175     */
     176    VMSTATE enmBefore;
     177    int     rc;
     178    for (;;)
     179    {
     180
     181        /*
     182         * Pending requests which needs servicing?
     183         *
     184         * We check for state changes in addition to status codes when
     185         * servicing requests. (Look after the ifs.)
     186         */
     187        enmBefore = pVM->enmVMState;
     188        if (VM_FF_ISSET(pVM, VM_FF_TERMINATE))
     189        {
     190            rc = VINF_EM_TERMINATE;
     191            break;
     192        }
     193        else if (pVM->vm.s.pReqs)
     194        {
     195            /*
     196             * Service execute in EMT request.
     197             */
     198            rc = VMR3ReqProcess(pVM);
     199            Log(("vmR3EmulationThread: Req rc=%Vrc, VM state %d -> %d\n", rc, enmBefore, pVM->enmVMState));
     200        }
     201        else if (VM_FF_ISSET(pVM, VM_FF_DBGF))
     202        {
     203            /*
     204             * Service the debugger request.
     205             */
     206            rc = DBGFR3VMMForcedAction(pVM);
     207            Log(("vmR3EmulationThread: Dbg rc=%Vrc, VM state %d -> %d\n", rc, enmBefore, pVM->enmVMState));
     208        }
     209        else if (VM_FF_ISSET(pVM, VM_FF_RESET))
     210        {
     211            /*
     212             * Service a delay reset request.
     213             */
     214            rc = VMR3Reset(pVM);
     215            VM_FF_CLEAR(pVM, VM_FF_RESET);
     216            Log(("vmR3EmulationThread: Reset rc=%Vrc, VM state %d -> %d\n", rc, enmBefore, pVM->enmVMState));
     217        }
     218        else
     219        {
     220            /*
     221             * Nothing important is pending, so wait for something.
     222             */
     223            rc = VMR3Wait(pVM);
     224            if (VBOX_FAILURE(rc))
     225                break;
     226        }
     227
     228        /*
     229         * Check for termination requests, these are extremely high priority.
     230         */
     231        if (    rc == VINF_EM_TERMINATE
     232            ||  VM_FF_ISSET(pVM, VM_FF_TERMINATE))
     233            break;
     234
     235        /*
     236         * Some requests (both VMR3Req* and the DBGF) can potentially
     237         * resume or start the VM, in that case we'll get a change in
     238         * VM status indicating that we're now running.
     239         */
     240        if (    VBOX_SUCCESS(rc)
     241            &&  enmBefore != pVM->enmVMState
     242            &&  (pVM->enmVMState == VMSTATE_RUNNING))
     243        {
     244            /* Only valid exit reason. */
     245            return VINF_SUCCESS;
     246        }
     247
     248    } /* forever */
     249
     250    /* Return to the main loop in vmR3EmulationThread, which will clean up for us. */
     251    longjmp(pVM->vm.s.emtJumpEnv, 1);
     252}
    161253
    162254/**
  • trunk/src/VBox/VMM/VMInternal.h

    r234 r247  
    2525#include <VBox/cdefs.h>
    2626#include <VBox/vmapi.h>
    27 
     27#include <setjmp.h>
    2828
    2929#if !defined(IN_VM_R3) && !defined(IN_VM_R0) && !defined(IN_VM_GC)
     
    256256    bool                            fEMTDoesTheCleanup;
    257257
     258    /** vmR3EmulationThread longjmp buffer */
     259    jmp_buf                         emtJumpEnv;
     260
    258261    /** Number of VMR3ReqAlloc returning a new packet. */
    259262    STAMCOUNTER                     StatReqAllocNew;
  • trunk/src/VBox/VMM/VMMInternal.h

    r234 r247  
    250250    VMMR0JMPBUF                 CallHostR0JmpBuf;
    251251    /** @} */
    252 
     252   
    253253    /** Number of VMMR0_DO_RUN_GC calls. */
    254254    STAMCOUNTER                 StatRunGC;
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