VirtualBox

Changeset 26348 in vbox


Ignore:
Timestamp:
Feb 9, 2010 8:56:37 AM (15 years ago)
Author:
vboxsync
Message:

Must use VMMR3EmtRendezvous in PGMR3PhysFreeRamPages

File:
1 edited

Legend:

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

    r26330 r26348  
    741741static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, uint8_t uType)
    742742{
     743    Assert(PGMIsLockOwner(pVM));
    743744    uint32_t            cPendingPages = 0;
    744745    PGMMFREEPAGESREQ    pReq;
     
    746747    AssertLogRelRCReturn(rc, rc);
    747748
    748     /* Itegerate the pages. */
     749    /* Iterate the pages. */
    749750    PPGMPAGE pPageDst   = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT];
    750751    uint32_t cPagesLeft = ((GCPhysLast - GCPhys) >> PAGE_SHIFT) + 1;
     
    767768    GMMR3FreePagesCleanup(pReq);
    768769
     770    return rc;
     771}
     772
     773/**
     774 * Rendezvous callback used by PGMR3PhysFreeRamPages that frees a range of guest physical pages
     775 *
     776 * This is only called on one of the EMTs while the other ones are waiting for
     777 * it to complete this function.
     778 *
     779 * @returns VINF_SUCCESS (VBox strict status code).
     780 * @param   pVM         The VM handle.
     781 * @param   pVCpu       The VMCPU for the EMT we're being called on. Unused.
     782 * @param   pvUser      User parameter
     783 */
     784static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysFreeRamPagesRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
     785{
     786    uintptr_t          *paUser          = (uintptr_t *)pvUser;
     787    unsigned            cPages          = paUser[0];
     788    RTGCPHYS           *paPhysPage      = (RTGCPHYS *)paUser[1];
     789    uint32_t            cPendingPages   = 0;
     790    PGMMFREEPAGESREQ    pReq;
     791
     792    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]);
     813        if (RT_FAILURE(rc))
     814        {
     815            pgmUnlock(pVM);
     816            AssertLogRelRC(rc);
     817            return rc;
     818        }
     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    pgmUnlock(pVM);
    769834    return rc;
    770835}
     
    780845VMMR3DECL(int) PGMR3PhysFreeRamPages(PVM pVM, unsigned cPages, RTGCPHYS *paPhysPage)
    781846{
    782     uint32_t            cPendingPages = 0;
    783     PGMMFREEPAGESREQ    pReq;
    784     int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
    785     AssertLogRelRCReturn(rc, rc);
    786 
    787     /* Itegerate the pages. */
    788     for (unsigned i = 0; i < cPages; i++)
    789     {
    790         PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]);
    791         if (    pPage == NULL
    792             ||  pPage->uTypeY != PGMPAGETYPE_RAM)
    793         {
    794             Log(("PGMR3PhysFreePageRange: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0));
    795             break;
    796         }
    797 
    798         rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]);
    799         AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */
    800     }
    801 
    802     if (cPendingPages)
    803     {
    804         rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages);
    805         AssertLogRelRCReturn(rc, rc);
    806     }
    807     GMMR3FreePagesCleanup(pReq);
    808 
     847    uintptr_t paUser[2];
     848
     849    paUser[0] = cPages;
     850    paUser[1] = (uintptr_t)paPhysPage;
     851    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysFreeRamPagesRendezvous, (void *)paUser);
     852    AssertRC(rc);
    809853    return rc;
    810854}
    811 
    812855
    813856/**
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