VirtualBox

Changeset 27084 in vbox


Ignore:
Timestamp:
Mar 5, 2010 1:08:58 PM (15 years ago)
Author:
vboxsync
Message:

Take the balloon size into account when applying account limits for the VM.

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

Legend:

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

    r26606 r27084  
    276276
    277277
    278 #if 0 /* impractical */
    279 GMMR3DECL(int)  GMMR3BalloonedPages(PVM pVM, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted)
     278/**
     279 * @see GMMR0BalloonedPages
     280 */
     281GMMR3DECL(int)  GMMR3BalloonedPages(PVM pVM, bool fInflate, uint32_t cBalloonedPages)
    280282{
    281283    GMMBALLOONEDPAGESREQ Req;
    282284    Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    283285    Req.Hdr.cbReq = sizeof(Req);
     286    Req.fInflate = fInflate;
     287    Req.cBalloonedPages = cBalloonedPages;
    284288
    285289    return VMMR3CallR0(pVM, VMMR0_DO_GMM_BALLOONED_PAGES, 0, &Req.Hdr);
    286 }
    287 #endif
    288 
    289 
    290 /**
    291  * @see GMMR0DeflatedBalloon
    292  */
    293 GMMR3DECL(int)  GMMR3DeflatedBalloon(PVM pVM, uint32_t cPages)
    294 {
    295     return VMMR3CallR0(pVM, VMMR0_DO_GMM_DEFLATED_BALLOON, cPages, NULL);
    296290}
    297291
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r27042 r27084  
    772772
    773773/**
    774  * Rendezvous callback used by PGMR3PhysFreeRamPages that frees a range of guest physical pages
     774 * Rendezvous callback used by PGMR3ChangeMemBalloon that changes the memory balloon size
    775775 *
    776776 * This is only called on one of the EMTs while the other ones are waiting for
     
    782782 * @param   pvUser      User parameter
    783783 */
    784 static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysFreeRamPagesRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
     784static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysChangeMemBalloonRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
    785785{
    786786    uintptr_t          *paUser          = (uintptr_t *)pvUser;
    787     unsigned            cPages          = paUser[0];
    788     RTGCPHYS           *paPhysPage      = (RTGCPHYS *)paUser[1];
     787    bool                fInflate        = !!paUser[0];
     788    unsigned            cPages          = paUser[1];
     789    RTGCPHYS           *paPhysPage      = (RTGCPHYS *)paUser[2];
    789790    uint32_t            cPendingPages   = 0;
    790791    PGMMFREEPAGESREQ    pReq;
     792    int                 rc;
    791793
    792794    pgmLock(pVM);
    793     int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
    794     if (RT_FAILURE(rc))
    795     {
    796         pgmUnlock(pVM);
    797         AssertLogRelRC(rc);
    798         return rc;
    799     }
    800 
    801     /* Iterate the pages. */
    802     for (unsigned i = 0; i < cPages; i++)
    803     {
    804         PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]);
    805         if (    pPage == NULL
    806             ||  pPage->uTypeY != PGMPAGETYPE_RAM)
    807         {
    808             Log(("PGMR3PhysFreePageRange: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0));
    809             break;
    810         }
    811 
    812         rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]);
     795
     796    if (fInflate)
     797    {
     798        /* Replace pages with ZERO pages. */
     799        rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
    813800        if (RT_FAILURE(rc))
    814801        {
     
    817804            return rc;
    818805        }
    819     }
    820 
    821     if (cPendingPages)
    822     {
    823         rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages);
    824         if (RT_FAILURE(rc))
    825         {
    826             pgmUnlock(pVM);
    827             AssertLogRelRC(rc);
    828             return rc;
    829         }
    830     }
    831     GMMR3FreePagesCleanup(pReq);
    832 
    833     /* Flush the PGM pool cache as we might have stale references to pages that we just freed. */
    834     pgmR3PoolClearAllRendezvous(pVM, pVCpu, NULL);
    835 
     806
     807        /* Iterate the pages. */
     808        for (unsigned i = 0; i < cPages; i++)
     809        {
     810            PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]);
     811            if (    pPage == NULL
     812                ||  pPage->uTypeY != PGMPAGETYPE_RAM)
     813            {
     814                Log(("PGMR3PhysFreePageRange: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0));
     815                break;
     816            }
     817
     818            rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]);
     819            if (RT_FAILURE(rc))
     820            {
     821                pgmUnlock(pVM);
     822                AssertLogRelRC(rc);
     823                return rc;
     824            }
     825        }
     826
     827        if (cPendingPages)
     828        {
     829            rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages);
     830            if (RT_FAILURE(rc))
     831            {
     832                pgmUnlock(pVM);
     833                AssertLogRelRC(rc);
     834                return rc;
     835            }
     836        }
     837        GMMR3FreePagesCleanup(pReq);
     838
     839        /* Flush the PGM pool cache as we might have stale references to pages that we just freed. */
     840        pgmR3PoolClearAllRendezvous(pVM, pVCpu, NULL);
     841    }
     842
     843    /* Notify GMM about the balloon change. */
     844    rc = GMMR3BalloonedPages(pVM, fInflate, cPages);
    836845    pgmUnlock(pVM);
     846    AssertLogRelRC(rc);
    837847    return rc;
    838848}
     
    843853 * @returns VBox status code.
    844854 * @param   pVM         The VM handle.
     855 * @param   fInflate    Inflate or deflate memory balloon
    845856 * @param   cPages      Number of pages to free
    846857 * @param   paPhysPage  Array of guest physical addresses
    847858 */
    848 static DECLCALLBACK(void) pgmR3PhysFreeRamPagesHelper(PVM pVM, unsigned cPages, RTGCPHYS *paPhysPage)
    849 {
    850     uintptr_t paUser[2];
    851 
    852     paUser[0] = cPages;
    853     paUser[1] = (uintptr_t)paPhysPage;
    854     int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysFreeRamPagesRendezvous, (void *)paUser);
     859static DECLCALLBACK(void) pgmR3PhysChangeMemBalloonHelper(PVM pVM, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage)
     860{
     861    uintptr_t paUser[3];
     862
     863    paUser[0] = fInflate;
     864    paUser[1] = cPages;
     865    paUser[2] = (uintptr_t)paPhysPage;
     866    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysChangeMemBalloonRendezvous, (void *)paUser);
    855867    AssertRC(rc);
    856868
     
    860872
    861873/**
    862  * Frees a range of ram pages, replacing them with ZERO pages
     874 * Inflate or deflate a memory balloon
    863875 *
    864876 * @returns VBox status code.
    865877 * @param   pVM         The VM handle.
     878 * @param   fInflate    Inflate or deflate memory balloon
    866879 * @param   cPages      Number of pages to free
    867880 * @param   paPhysPage  Array of guest physical addresses
    868881 */
    869 VMMR3DECL(int) PGMR3PhysFreeRamPages(PVM pVM, unsigned cPages, RTGCPHYS *paPhysPage)
     882VMMR3DECL(int) PGMR3PhysChangeMemBalloon(PVM pVM, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage)
    870883{
    871884    int rc;
    872 
    873     /* Currently only used by the VMM device in responds to a balloon request. */
    874885
    875886    /* We own the IOM lock here and could cause a deadlock by waiting for another VCPU that is blocking on the IOM lock.
     
    884895        memcpy(paPhysPageCopy, paPhysPage, cbPhysPage);
    885896
    886         rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3PhysFreeRamPagesHelper, 3, pVM, cPages, paPhysPageCopy);
     897        rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3PhysChangeMemBalloonHelper, 4, pVM, fInflate, cPages, paPhysPageCopy);
    887898        AssertRC(rc);
    888899    }
    889900    else
    890901    {
    891         uintptr_t paUser[2];
    892 
    893         paUser[0] = cPages;
    894         paUser[1] = (uintptr_t)paPhysPage;
    895         rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysFreeRamPagesRendezvous, (void *)paUser);
     902        uintptr_t paUser[3];
     903
     904        paUser[0] = fInflate;
     905        paUser[1] = cPages;
     906        paUser[2] = (uintptr_t)paPhysPage;
     907        rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysChangeMemBalloonRendezvous, (void *)paUser);
    896908        AssertRC(rc);
    897909    }
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r27005 r27084  
    10791079 * The initial resource reservations.
    10801080 *
    1081  * This will make memory reservations according to policy and priority. If there isn't
     1081 * This will make memory reservations according to policy and priority. If there aren't
    10821082 * sufficient resources available to sustain the VM this function will fail and all
    10831083 * future allocations requests will fail as well.
     
    18131813    {
    18141814        case GMMACCOUNT_BASE:
    1815             if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + cPages > pGVM->gmm.s.Reserved.cBasePages))
     1815            if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages > pGVM->gmm.s.Reserved.cBasePages))
    18161816            {
    18171817                Log(("gmmR0AllocatePages: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n",
     
    23242324        GMMPAGEDESC    PageDesc;
    23252325
    2326         if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + cPages > pGVM->gmm.s.Reserved.cBasePages))
     2326        if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages > pGVM->gmm.s.Reserved.cBasePages))
    23272327        {
    23282328            Log(("GMMR0AllocateLargePage: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n",
     
    28412841 * ballooned.
    28422842 *
    2843  * Since the whole purpose of ballooning is to free up guest RAM pages, this API
    2844  * may also be given a set of related pages to be freed. These pages are assumed
    2845  * to be on the base account.
    2846  *
    28472843 * @returns VBox status code:
    28482844 * @retval  xxx
     
    28502846 * @param   pVM                 Pointer to the shared VM structure.
    28512847 * @param   idCpu               VCPU id
     2848 * @param   fInflate            Inflate or deflate the balloon
    28522849 * @param   cBalloonedPages     The number of pages that was ballooned.
    2853  * @param   cPagesToFree        The number of pages to be freed.
    2854  * @param   paPages             Pointer to the page descriptors for the pages that's to be freed.
    2855  * @param   fCompleted          Indicates whether the ballooning request was completed (true) or
    2856  *                              if there is more pages to come (false). If the ballooning was not
    2857  *                              not triggered by the GMM, don't set this.
     2850 *
    28582851 * @thread  EMT.
    28592852 */
    2860 GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted)
    2861 {
    2862     LogFlow(("GMMR0BalloonedPages: pVM=%p cBalloonedPages=%#x cPagestoFree=%#x paPages=%p enmAccount=%d fCompleted=%RTbool\n",
    2863              pVM, cBalloonedPages, cPagesToFree, paPages, fCompleted));
     2853GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, bool fInflate, uint32_t cBalloonedPages)
     2854{
     2855    LogFlow(("GMMR0BalloonedPages: pVM=%p fInflate=%RTBool cBalloonedPages=%#x\n",
     2856             pVM, fInflate, cBalloonedPages));
    28642857
    28652858    /*
     
    28732866        return rc;
    28742867
    2875     AssertPtrReturn(paPages, VERR_INVALID_PARAMETER);
    28762868    AssertMsgReturn(cBalloonedPages < RT_BIT(32 - PAGE_SHIFT), ("%#x\n", cBalloonedPages), VERR_INVALID_PARAMETER);
    2877     AssertMsgReturn(cPagesToFree <= cBalloonedPages, ("%#x\n", cPagesToFree), VERR_INVALID_PARAMETER);
    2878 
    2879     for (unsigned iPage = 0; iPage < cPagesToFree; iPage++)
    2880         AssertMsgReturn(    paPages[iPage].idPage <= GMM_PAGEID_LAST
    2881                         /*||  paPages[iPage].idPage == NIL_GMM_PAGEID*/,
    2882                         ("#%#x: %#x\n", iPage, paPages[iPage].idPage), VERR_INVALID_PARAMETER);
    28832869
    28842870    /*
     
    28892875    if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
    28902876    {
    2891 
    2892         if (pGVM->gmm.s.Allocated.cBasePages >= cPagesToFree)
    2893         {
    2894             /*
    2895              * Record the ballooned memory.
    2896              */
    2897             pGMM->cBalloonedPages += cBalloonedPages;
    2898             if (pGVM->gmm.s.cReqBalloonedPages)
     2877        if (fInflate)
     2878        {
     2879            if (pGVM->gmm.s.Allocated.cBasePages >= cBalloonedPages)
    28992880            {
    2900                 pGVM->gmm.s.cBalloonedPages += cBalloonedPages;
    2901                 pGVM->gmm.s.cReqActuallyBalloonedPages += cBalloonedPages;
    2902                 if (fCompleted)
     2881                /*
     2882                 * Record the ballooned memory.
     2883                 */
     2884                pGMM->cBalloonedPages += cBalloonedPages;
     2885                if (pGVM->gmm.s.cReqBalloonedPages)
    29032886                {
    2904                     Log(("GMMR0BalloonedPages: +%#x - Global=%#llx;  / VM: Total=%#llx Req=%#llx Actual=%#llx (completed)\n", cBalloonedPages,
     2887                    /* Codepath never taken. Might be interesting in the future to request ballooned memory from guests in low memory conditions.. */
     2888                    AssertFailed();
     2889
     2890                    pGVM->gmm.s.cBalloonedPages += cBalloonedPages;
     2891                    pGVM->gmm.s.cReqActuallyBalloonedPages += cBalloonedPages;
     2892                    Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n", cBalloonedPages,
    29052893                         pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages));
    2906 
    2907                     /*
    2908                      * Anything we need to do here now when the request has been completed?
    2909                      */
    2910                     pGVM->gmm.s.cReqBalloonedPages = 0;
    29112894                }
    29122895                else
    2913                     Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n", cBalloonedPages,
    2914                          pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages));
     2896                {
     2897                    pGVM->gmm.s.cBalloonedPages += cBalloonedPages;
     2898                    Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx (user)\n",
     2899                         cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages));
     2900                }
    29152901            }
    29162902            else
     2903                rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
     2904        }
     2905        else
     2906        {
     2907            /* Deflate. */
     2908            if (pGVM->gmm.s.cBalloonedPages >= cBalloonedPages)
    29172909            {
    2918                 pGVM->gmm.s.cBalloonedPages += cBalloonedPages;
    2919                 Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx (user)\n",
     2910                /*
     2911                 * Record the ballooned memory.
     2912                 */
     2913                Assert(pGMM->cBalloonedPages >= cBalloonedPages);
     2914                pGMM->cBalloonedPages       -= cBalloonedPages;
     2915                pGVM->gmm.s.cBalloonedPages -= cBalloonedPages;
     2916                Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx (user)\n",
    29202917                     cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages));
    29212918            }
    2922 
    2923             /*
    2924              * Any pages to free?
    2925              */
    2926             if (cPagesToFree)
    2927                 rc = gmmR0FreePages(pGMM, pGVM, cPagesToFree, paPages, GMMACCOUNT_BASE);
    2928         }
    2929         else
    2930             rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
     2919            else
     2920                rc = VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH;
     2921        }
    29312922        GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
    29322923    }
     
    29542945    AssertPtrReturn(pVM, VERR_INVALID_POINTER);
    29552946    AssertPtrReturn(pReq, VERR_INVALID_POINTER);
    2956     AssertMsgReturn(pReq->Hdr.cbReq >= RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[0]),
    2957                     ("%#x < %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[0])),
     2947    AssertMsgReturn(pReq->Hdr.cbReq == sizeof(GMMBALLOONEDPAGESREQ),
     2948                    ("%#x < %#x\n", pReq->Hdr.cbReq, sizeof(GMMBALLOONEDPAGESREQ)),
    29582949                    VERR_INVALID_PARAMETER);
    2959     AssertMsgReturn(pReq->Hdr.cbReq == RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[pReq->cPagesToFree]),
    2960                     ("%#x != %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMBALLOONEDPAGESREQ, aPages[pReq->cPagesToFree])),
    2961                     VERR_INVALID_PARAMETER);
    2962 
    2963     return GMMR0BalloonedPages(pVM, idCpu, pReq->cBalloonedPages, pReq->cPagesToFree, &pReq->aPages[0], pReq->fCompleted);
     2950
     2951    return GMMR0BalloonedPages(pVM, idCpu, pReq->fInflate, pReq->cBalloonedPages);
    29642952}
    29652953
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r26606 r27084  
    915915            return GMMR0BalloonedPagesReq(pVM, idCpu, (PGMMBALLOONEDPAGESREQ)pReqHdr);
    916916
    917         case VMMR0_DO_GMM_DEFLATED_BALLOON:
    918             if (pReqHdr)
    919                 return VERR_INVALID_PARAMETER;
    920             return GMMR0DeflatedBalloon(pVM, idCpu, (uint32_t)u64Arg);
    921 
    922917        case VMMR0_DO_GMM_MAP_UNMAP_CHUNK:
    923918            if (u64Arg)
     
    11161111            case VMMR0_DO_GMM_FREE_PAGES:
    11171112            case VMMR0_DO_GMM_BALLOONED_PAGES:
    1118             case VMMR0_DO_GMM_DEFLATED_BALLOON:
    11191113            /* On the mac we might not have a valid jmp buf, so check these as well. */
    11201114            case VMMR0_DO_VMMR0_INIT:
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