VirtualBox

Changeset 31938 in vbox for trunk/src


Ignore:
Timestamp:
Aug 24, 2010 5:17:48 PM (14 years ago)
Author:
vboxsync
Message:

FT updates

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

Legend:

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

    r31895 r31938  
    546546
    547547    case FTMSYNCSTATE_DELTA_MEMORY:
     548        /* Nothing to do as we sync the memory in an async thread; no need to block EMT. */
    548549        break;
    549550    }
     
    557558        AssertRC(rc);
    558559    }
     560}
     561
     562/**
     563 * PGMR3PhysEnumDirtyFTPages callback for syncing dirty physical pages
     564 *
     565 * @param   pVM             VM Handle.
     566 * @param   GCPhys          GC physical address
     567 * @param   pRange          HC virtual address of the page(s)
     568 * @param   cbRange         Size of the dirty range in bytes.
     569 * @param   pvUser          User argument
     570 */
     571static DECLCALLBACK(int) ftmR3SyncDirtyPage(PVM pVM, RTGCPHYS GCPhys, uint8_t *pRange, unsigned cbRange, void *pvUser)
     572{
     573    return VINF_SUCCESS;
    559574}
    560575
     
    626641    for (;;)
    627642    {
     643        rc = RTSemEventWait(pVM->ftm.s.master.hShutdownEvent, pVM->ftm.s.uInterval);
     644        if (rc != VERR_TIMEOUT)
     645            break;    /* told to quit */
     646
    628647        if (!pVM->ftm.s.fCheckpointingActive)
    629648        {
     
    632651
    633652            /* sync the changed memory with the standby node. */
     653            rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3PerformSync, 2, pVM, FTMSYNCSTATE_DELTA_MEMORY);
     654            AssertRC(rc);
     655
     656            rc = PGMR3PhysEnumDirtyFTPages(pVM, ftmR3SyncDirtyPage, NULL /* pvUser */);
     657            AssertRC(rc);
    634658
    635659            PDMCritSectLeave(&pVM->ftm.s.CritSect);
    636660        }
    637         rc = RTSemEventWait(pVM->ftm.s.master.hShutdownEvent, pVM->ftm.s.uInterval);
    638         if (rc != VERR_TIMEOUT)
    639             break;    /* told to quit */           
    640661    }
    641662    return rc;
     
    846867    pVM->ftm.s.syncstate.fEndOfStream = false;
    847868
    848     /** @todo sync state + changed memory. */
     869    /* Sync state + changed memory. */
     870    rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3PerformSync, 2, pVM, FTMSYNCSTATE_DELTA_VM);
     871    AssertRC(rc);
    849872
    850873    PDMCritSectLeave(&pVM->ftm.s.CritSect);
  • trunk/src/VBox/VMM/PGMInternal.h

    r31895 r31938  
    724724     *  - [8-9]: u2HandlerVirtStateY - the virtual handler state
    725725     *    (PGM_PAGE_HNDL_VIRT_STATE_*).
     726     *  - [10]:  u1FTDirty - indicator of dirty page for fault tolerance tracking
    726727     *  - [13-14]: u2PDEType  - paging structure needed to map the page (PGM_PAGE_PDE_TYPE_*)
    727728     *  - [15]:  fWrittenToY - flag indicating that a write monitored page was
    728729     *    written to when set.
    729      *  - [10-13]: 4 unused bits.
     730     *  - [11-13]: 3 unused bits.
    730731     * @remarks Warning! All accesses to the bits are hardcoded.
    731732     *
     
    969970 */
    970971#define PGM_PAGE_IS_WRITTEN_TO(pPage)       ( !!((pPage)->u16MiscY.au8[1] & UINT8_C(0x80)) )
     972
     973/**
     974 * Marks the page as dirty for FTM
     975 * @param   pPage       Pointer to the physical guest page tracking structure.
     976 */
     977#define PGM_PAGE_SET_FT_DIRTY(pPage)        do { (pPage)->u16MiscY.au8[1] |= UINT8_C(0x04); } while (0)
     978
     979/**
     980 * Clears the FTM dirty indicator
     981 * @param   pPage       Pointer to the physical guest page tracking structure.
     982 */
     983#define PGM_PAGE_CLEAR_FT_DIRTY(pPage)      do { (pPage)->u16MiscY.au8[1] &= UINT8_C(0xfb); } while (0)
     984
     985/**
     986 * Checks if the page was marked as dirty for FTM
     987 * @returns true/false.
     988 * @param   pPage       Pointer to the physical guest page tracking structure.
     989 */
     990#define PGM_PAGE_IS_FT_DIRTY(pPage)         ( !!((pPage)->u16MiscY.au8[1] & UINT8_C(0x04)) )
     991
    971992
    972993/** @name PT usage values (PGMPAGE::u2PDEType).
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r31895 r31938  
    980980    /** @todo pointless to write protect the physical page pointed to by RSP. */
    981981
    982     /*
    983      * Clear all the GCPhys links and rebuild the phys ext free list.
    984      */
    985982    for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
    986983         pRam;
     
    10041001                            * monitoring if the page is known to be very busy. */
    10051002                        if (PGM_PAGE_IS_WRITTEN_TO(pPage))
     1003                        {
    10061004                            PGM_PAGE_CLEAR_WRITTEN_TO(pPage);
     1005                            /* Remember this dirty page for the next (memory) sync. */
     1006                            PGM_PAGE_SET_FT_DIRTY(pPage);
     1007                        }
    10071008
    10081009                        PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_WRITE_MONITORED);
     
    10421043    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysWriteProtectRAMRendezvous, NULL);
    10431044    AssertRC(rc);
     1045    return rc;
     1046}
     1047
     1048/**
     1049 * Enumerate all dirty FT pages
     1050 *
     1051 * @returns VBox status code.
     1052 * @param   pVM         The VM handle.
     1053 * @param   pfnEnum     Enumerate callback handler
     1054 * @param   pvUser      Enumerate callback handler parameter
     1055 */
     1056VMMR3DECL(int) PGMR3PhysEnumDirtyFTPages(PVM pVM, PFNPGMENUMDIRTYFTPAGES pfnEnum, void *pvUser)
     1057{
     1058    int rc = VINF_SUCCESS;
     1059
     1060    pgmLock(pVM);
     1061    for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
     1062         pRam;
     1063         pRam = pRam->CTX_SUFF(pNext))
     1064    {
     1065        if (!PGM_RAM_RANGE_IS_AD_HOC(pRam))
     1066        {
     1067            unsigned iPage = pRam->cb >> PAGE_SHIFT;
     1068            while (iPage-- > 0)
     1069            {
     1070                PPGMPAGE pPage = &pRam->aPages[iPage];
     1071                if (RT_LIKELY(PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM))
     1072                {
     1073                    /*
     1074                     * A RAM page.
     1075                     */
     1076                    switch (PGM_PAGE_GET_STATE(pPage))
     1077                    {
     1078                    case PGM_PAGE_STATE_ALLOCATED:
     1079                        if (    !PGM_PAGE_IS_WRITTEN_TO(pPage)
     1080                            &&  PGM_PAGE_IS_FT_DIRTY(pPage))
     1081                        {
     1082                            /** @todo this is risky; the range might be changed, but little choice as the sync costs a lot of time */
     1083                            pgmUnlock(pVM);
     1084                            pfnEnum(pVM, pRam->GCPhys + iPage * PAGE_SIZE, 0, 0, pvUser);
     1085                            pgmLock(pVM);
     1086                            PGM_PAGE_CLEAR_FT_DIRTY(pPage);
     1087                        }
     1088                        break;
     1089                    }
     1090                }
     1091            }
     1092        }
     1093    }
     1094    pgmUnlock(pVM);
    10441095    return rc;
    10451096}
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