VirtualBox

Changeset 32193 in vbox


Ignore:
Timestamp:
Sep 2, 2010 12:56:32 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
65497
Message:

FT updates

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

Legend:

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

    r32179 r32193  
    2929#include <VBox/log.h>
    3030#include <VBox/pgm.h>
     31#include <VBox/pdm.h>
    3132
    3233#include <iprt/assert.h>
     
    590591};
    591592
     593
    592594/**
    593595 * VMR3ReqCallWait callback
     
    602604}
    603605
    604 /**
    605  * Sync the VM state partially or fully
     606
     607/**
     608 * Sync the VM state
    606609 *
    607610 * @returns VBox status code.
    608611 * @param   pVM         The VM handle.
    609  * @param   enmState    Which state to sync
    610  */
    611 static int ftmR3PerformSync(PVM pVM, FTMSYNCSTATE enmState)
    612 {
    613     int rc;
    614     bool fFullSync = false;
    615 
    616     if (enmState != FTMSYNCSTATE_DELTA_MEMORY)
    617     {
    618         rc = VMR3Suspend(pVM);
    619         AssertRCReturn(rc, rc);
    620         /** Hack alert as EM is responsible for dealing with the suspend state. We must do this here ourselves, but only for this EMT.*/
    621         if (VM_IS_EMT(pVM))
    622             EMR3NotifySuspend(pVM);
    623     }
    624 
    625     switch (enmState)
    626     {
    627     case FTMSYNCSTATE_FULL:
    628         fFullSync = true;
    629         /* no break */
    630     case FTMSYNCSTATE_DELTA_VM:
    631     {
    632         bool fSuspended = false;
    633 
    634         STAM_REL_COUNTER_INC((fFullSync) ? &pVM->ftm.s.StatFullSync : &pVM->ftm.s.StatDeltaVM);
    635 
    636         RTSocketRetain(pVM->ftm.s.hSocket); /* For concurrent access by I/O thread and EMT. */
    637 
    638         /* Reset the sync state. */
    639         pVM->ftm.s.syncstate.uOffStream   = 0;
    640         pVM->ftm.s.syncstate.cbReadBlock  = 0;
    641         pVM->ftm.s.syncstate.fStopReading = false;
    642         pVM->ftm.s.syncstate.fIOError     = false;
    643         pVM->ftm.s.syncstate.fEndOfStream = false;
    644 
    645         rc = ftmR3TcpSubmitCommand(pVM, (fFullSync) ? "full-sync" : "checkpoint");
    646         AssertRC(rc);
    647 
    648         pVM->ftm.s.fDeltaLoadSaveActive = (fFullSync == false);
    649         rc = VMR3SaveFT(pVM, &g_ftmR3TcpOps, pVM, &fSuspended);
    650         pVM->ftm.s.fDeltaLoadSaveActive = false;
    651         AssertRC(rc);
    652 
    653         rc = ftmR3TcpReadACK(pVM, (fFullSync) ? "full-sync-complete" : "checkpoint-complete");
    654         AssertRC(rc);
    655 
    656         RTSocketRelease(pVM->ftm.s.hSocket);
    657         break;
    658     }
    659 
    660     case FTMSYNCSTATE_DELTA_MEMORY:
    661         /* Nothing to do as we sync the memory in an async thread; no need to block EMT. */
    662         STAM_REL_COUNTER_INC(&pVM->ftm.s.StatDeltaMem);
    663         break;
    664     }
     612 */
     613static int ftmR3PerformFullSync(PVM pVM)
     614{
     615    bool fSuspended = false;
     616
     617    int rc = VMR3Suspend(pVM);
     618    AssertRCReturn(rc, rc);
     619
     620    STAM_REL_COUNTER_INC(&pVM->ftm.s.StatFullSync);
     621
     622    RTSocketRetain(pVM->ftm.s.hSocket); /* For concurrent access by I/O thread and EMT. */
     623
     624    /* Reset the sync state. */
     625    pVM->ftm.s.syncstate.uOffStream   = 0;
     626    pVM->ftm.s.syncstate.cbReadBlock  = 0;
     627    pVM->ftm.s.syncstate.fStopReading = false;
     628    pVM->ftm.s.syncstate.fIOError     = false;
     629    pVM->ftm.s.syncstate.fEndOfStream = false;
     630
     631    rc = ftmR3TcpSubmitCommand(pVM, "full-sync");
     632    AssertRC(rc);
     633
     634    pVM->ftm.s.fDeltaLoadSaveActive = false;
     635    rc = VMR3SaveFT(pVM, &g_ftmR3TcpOps, pVM, &fSuspended, false /* fSkipStateChanges */);
     636    AssertRC(rc);
     637
     638    rc = ftmR3TcpReadACK(pVM, "full-sync-complete");
     639    AssertRC(rc);
     640
     641    RTSocketRelease(pVM->ftm.s.hSocket);
    665642
    666643    /* Write protect all memory. */
     
    668645    AssertRCReturn(rc, rc);
    669646
    670     if (enmState != FTMSYNCSTATE_DELTA_MEMORY)
    671     {
    672         rc = VMR3Resume(pVM);
    673         AssertRCReturn(rc, rc);
    674 
    675         /** Hack alert as EM is responsible for dealing with the suspend state. We must do this here ourselves, but only for this EMT.*/
    676         if (VM_IS_EMT(pVM))
    677             EMR3NotifyResume(pVM);
    678     }
    679     return VINF_SUCCESS;
    680 }
     647    rc = VMR3Resume(pVM);
     648    AssertRC(rc);
     649
     650    return rc;
     651}
     652
    681653
    682654/**
     
    773745     */
    774746
    775     rc = ftmR3PerformSync(pVM, FTMSYNCSTATE_FULL);
     747    rc = ftmR3PerformFullSync(pVM);
    776748
    777749    for (;;)
     
    790762
    791763            /* sync the changed memory with the standby node. */
    792             rc = ftmR3PerformSync(pVM, FTMSYNCSTATE_DELTA_MEMORY);
     764            /* Write protect all memory. */
     765            rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3WriteProtectMemory, 1, pVM);
     766            AssertRC(rc);
    793767
    794768            /* Enumerate all dirty pages and send them to the standby VM. */
     
    10901064}
    10911065
     1066/**
     1067 * Rendezvous callback used by FTMR3SetCheckpoint
     1068 * Sync state + changed memory with the standby node.
     1069 *
     1070 * This is only called on one of the EMTs while the other ones are waiting for
     1071 * it to complete this function.
     1072 *
     1073 * @returns VINF_SUCCESS (VBox strict status code).
     1074 * @param   pVM         The VM handle.
     1075 * @param   pVCpu       The VMCPU for the EMT we're being called on. Unused.
     1076 * @param   pvUser      User parameter
     1077 */
     1078static DECLCALLBACK(VBOXSTRICTRC) ftmR3SetCheckpointRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
     1079{
     1080    int rc = VINF_SUCCESS;
     1081    bool fSuspended = false;
     1082
     1083    /** We don't call VMR3Suspend here to avoid the overhead of state changes and notifications. This
     1084     *  is only a short suspend.
     1085     */
     1086    PDMR3Suspend(pVM);
     1087
     1088    /** Hack alert: as EM is responsible for dealing with the suspend state. We must do this here ourselves, but only for this EMT.*/
     1089    EMR3NotifySuspend(pVM);
     1090
     1091    STAM_REL_COUNTER_INC(&pVM->ftm.s.StatDeltaVM);
     1092
     1093    RTSocketRetain(pVM->ftm.s.hSocket); /* For concurrent access by I/O thread and EMT. */
     1094
     1095    /* Reset the sync state. */
     1096    pVM->ftm.s.syncstate.uOffStream   = 0;
     1097    pVM->ftm.s.syncstate.cbReadBlock  = 0;
     1098    pVM->ftm.s.syncstate.fStopReading = false;
     1099    pVM->ftm.s.syncstate.fIOError     = false;
     1100    pVM->ftm.s.syncstate.fEndOfStream = false;
     1101
     1102    rc = ftmR3TcpSubmitCommand(pVM, "checkpoint");
     1103    AssertRC(rc);
     1104
     1105    pVM->ftm.s.fDeltaLoadSaveActive = true;
     1106    rc = VMR3SaveFT(pVM, &g_ftmR3TcpOps, pVM, &fSuspended, true /* fSkipStateChanges */);
     1107    pVM->ftm.s.fDeltaLoadSaveActive = false;
     1108    AssertRC(rc);
     1109
     1110    rc = ftmR3TcpReadACK(pVM, "checkpoint-complete");
     1111    AssertRC(rc);
     1112
     1113    RTSocketRelease(pVM->ftm.s.hSocket);
     1114
     1115    /* Write protect all memory. */
     1116    rc = PGMR3PhysWriteProtectRAM(pVM);
     1117    AssertRC(rc);
     1118
     1119    /** We don't call VMR3Resume here to avoid the overhead of state changes and notifications. This
     1120     *  is only a short suspend.
     1121     */
     1122    PDMR3Resume(pVM);
     1123
     1124    /** Hack alert as EM is responsible for dealing with the suspend state. We must do this here ourselves, but only for this EMT.*/
     1125    EMR3NotifyResume(pVM);
     1126    return rc;
     1127}
    10921128
    10931129/**
     
    11471183    STAM_PROFILE_START(&pVM->ftm.s.StatCheckpoint, a);
    11481184
    1149     /* Sync state + changed memory with the standby node. */
    1150     rc = ftmR3PerformSync(pVM, FTMSYNCSTATE_DELTA_VM);
     1185    rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, ftmR3SetCheckpointRendezvous, NULL);
    11511186
    11521187    STAM_PROFILE_STOP(&pVM->ftm.s.StatCheckpoint, a);
  • trunk/src/VBox/VMM/FTMInternal.h

    r32179 r32193  
    2929 * @{
    3030 */
    31 
    32 typedef enum
    33 {
    34     /* Sync the changed memory pages. */
    35     FTMSYNCSTATE_DELTA_MEMORY,
    36     /* Sync the changed state (memory + vm/device internal state) */
    37     FTMSYNCSTATE_DELTA_VM,
    38     /* Sync the entire VM state. */
    39     FTMSYNCSTATE_FULL
    40 } FTMSYNCSTATE;
    4131
    4232
  • trunk/src/VBox/VMM/VM.cpp

    r32190 r32193  
    16241624 * @returns VBox status code.
    16251625 *
    1626  * @param   pVM             The VM handle.
    1627  * @param   cMsMaxDowntime  The maximum downtime given as milliseconds.
    1628  * @param   pszFilename     The name of the file.  NULL if pStreamOps is used.
    1629  * @param   pStreamOps      The stream methods.  NULL if pszFilename is used.
    1630  * @param   pvStreamOpsUser The user argument to the stream methods.
    1631  * @param   enmAfter        What to do afterwards.
    1632  * @param   pfnProgress     Progress callback. Optional.
    1633  * @param   pvProgressUser  User argument for the progress callback.
    1634  * @param   ppSSM           Where to return the saved state handle in case of a
    1635  *                          live snapshot scenario.
     1626 * @param   pVM                 The VM handle.
     1627 * @param   cMsMaxDowntime      The maximum downtime given as milliseconds.
     1628 * @param   pszFilename         The name of the file.  NULL if pStreamOps is used.
     1629 * @param   pStreamOps          The stream methods.  NULL if pszFilename is used.
     1630 * @param   pvStreamOpsUser     The user argument to the stream methods.
     1631 * @param   enmAfter            What to do afterwards.
     1632 * @param   pfnProgress         Progress callback. Optional.
     1633 * @param   pvProgressUser      User argument for the progress callback.
     1634 * @param   ppSSM               Where to return the saved state handle in case of a
     1635 *                              live snapshot scenario.
     1636 * @param   fSkipStateChanges   Set if we're supposed to skip state changes (FTM delta case)
     1637 *
    16361638 * @thread  EMT
    16371639 */
    16381640static DECLCALLBACK(int) vmR3Save(PVM pVM, uint32_t cMsMaxDowntime, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
    1639                                   SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, PSSMHANDLE *ppSSM)
    1640 {
     1641                                  SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, PSSMHANDLE *ppSSM,
     1642                                  bool fSkipStateChanges)
     1643{
     1644    int rc = VINF_SUCCESS;
     1645
    16411646    LogFlow(("vmR3Save: pVM=%p cMsMaxDowntime=%u pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p ppSSM=%p\n",
    16421647             pVM, cMsMaxDowntime, pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser, ppSSM));
     
    16571662     * Change the state and perform/start the saving.
    16581663     */
    1659     int rc = vmR3TrySetState(pVM, "VMR3Save", 2,
     1664    if (!fSkipStateChanges)
     1665    {
     1666        rc = vmR3TrySetState(pVM, "VMR3Save", 2,
    16601667                             VMSTATE_SAVING,     VMSTATE_SUSPENDED,
    16611668                             VMSTATE_RUNNING_LS, VMSTATE_RUNNING);
     1669    }
     1670    else
     1671    {
     1672        Assert(enmAfter != SSMAFTER_TELEPORT);
     1673        rc = 1;
     1674    }
     1675
    16621676    if (rc == 1 && enmAfter != SSMAFTER_TELEPORT)
    16631677    {
    16641678        rc = SSMR3Save(pVM, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser);
    1665         vmR3SetState(pVM, VMSTATE_SUSPENDED, VMSTATE_SAVING);
     1679        if (!fSkipStateChanges)
     1680            vmR3SetState(pVM, VMSTATE_SUSPENDED, VMSTATE_SAVING);
    16661681    }
    16671682    else if (rc == 2 || enmAfter == SSMAFTER_TELEPORT)
    16681683    {
     1684        Assert(!fSkipStateChanges);
    16691685        if (enmAfter == SSMAFTER_TELEPORT)
    16701686            pVM->vm.s.fTeleportedAndNotFullyResumedYet = true;
     
    16841700 * @returns VBox status code.
    16851701 *
    1686  * @param   pVM             The VM handle.
     1702 * @param   pVM                 The VM handle.
    16871703 * @param   cMsMaxDowntime      The maximum downtime given as milliseconds.
    1688  * @param   pszFilename     The name of the file.  NULL if pStreamOps is used.
    1689  * @param   pStreamOps      The stream methods.  NULL if pszFilename is used.
    1690  * @param   pvStreamOpsUser The user argument to the stream methods.
    1691  * @param   enmAfter        What to do afterwards.
    1692  * @param   pfnProgress     Progress callback. Optional.
    1693  * @param   pvProgressUser  User argument for the progress callback.
    1694  * @param   pfSuspended     Set if we suspended the VM.
     1704 * @param   pszFilename         The name of the file.  NULL if pStreamOps is used.
     1705 * @param   pStreamOps          The stream methods.  NULL if pszFilename is used.
     1706 * @param   pvStreamOpsUser     The user argument to the stream methods.
     1707 * @param   enmAfter            What to do afterwards.
     1708 * @param   pfnProgress         Progress callback. Optional.
     1709 * @param   pvProgressUser      User argument for the progress callback.
     1710 * @param   pfSuspended         Set if we suspended the VM.
     1711 * @param   fSkipStateChanges   Set if we're supposed to skip state changes (FTM delta case)
    16951712 *
    16961713 * @thread  Non-EMT
     
    16981715static int vmR3SaveTeleport(PVM pVM, uint32_t cMsMaxDowntime,
    16991716                            const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
    1700                             SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended)
     1717                            SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended,
     1718                            bool fSkipStateChanges)
    17011719{
    17021720    /*
     
    17051723    PSSMHANDLE pSSM;
    17061724    int rc = VMR3ReqCallWaitU(pVM->pUVM, 0 /*idDstCpu*/,
    1707                               (PFNRT)vmR3Save, 9, pVM, cMsMaxDowntime, pszFilename, pStreamOps, pvStreamOpsUser,
    1708                               enmAfter, pfnProgress, pvProgressUser, &pSSM);
     1725                              (PFNRT)vmR3Save, 10, pVM, cMsMaxDowntime, pszFilename, pStreamOps, pvStreamOpsUser,
     1726                              enmAfter, pfnProgress, pvProgressUser, &pSSM, fSkipStateChanges);
    17091727    if (    RT_SUCCESS(rc)
    17101728        &&  pSSM)
    17111729    {
     1730        Assert(!fSkipStateChanges);
     1731
    17121732        /*
    17131733         * Live snapshot.
     
    18041824    int rc = vmR3SaveTeleport(pVM, 250 /*cMsMaxDowntime*/,
    18051825                              pszFilename, NULL /* pStreamOps */, NULL /* pvStreamOpsUser */,
    1806                               enmAfter, pfnProgress, pvUser, pfSuspended);
     1826                              enmAfter, pfnProgress, pvUser, pfSuspended,
     1827                              false /* fSkipStateChanges */);
    18071828    LogFlow(("VMR3Save: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended));
    18081829    return rc;
     
    18261847 * @param   pvStreamOpsUser     The user argument to the stream methods.
    18271848 * @param   pfSuspended         Set if we suspended the VM.
     1849 * @param   fSkipStateChanges   Set if we're supposed to skip state changes (FTM delta case)
    18281850 *
    18291851 * @thread      Any
     
    18321854 *              RunningLS+SuspeningLS+SuspendedLS+Saving+Suspended.
    18331855 */
    1834 VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended)
     1856VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended,
     1857                          bool fSkipStateChanges)
    18351858{
    18361859    LogFlow(("VMR3SaveFT: pVM=%p pStreamOps=%p pvSteamOpsUser=%p pfSuspended=%p\n",
     
    18501873    int rc = vmR3SaveTeleport(pVM, 250 /*cMsMaxDowntime*/,
    18511874                              NULL, pStreamOps, pvStreamOpsUser,
    1852                               SSMAFTER_CONTINUE, NULL, NULL, pfSuspended);
     1875                              SSMAFTER_CONTINUE, NULL, NULL, pfSuspended,
     1876                              fSkipStateChanges);
    18531877    LogFlow(("VMR3SaveFT: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended));
    18541878    return rc;
     
    18951919    int rc = vmR3SaveTeleport(pVM, cMsMaxDowntime,
    18961920                              NULL /*pszFilename*/, pStreamOps, pvStreamOpsUser,
    1897                               SSMAFTER_TELEPORT, pfnProgress, pvProgressUser, pfSuspended);
     1921                              SSMAFTER_TELEPORT, pfnProgress, pvProgressUser, pfSuspended,
     1922                              false /* fSkipStateChanges */);
    18981923    LogFlow(("VMR3Teleport: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended));
    18991924    return rc;
  • trunk/src/VBox/VMM/include/internal/vm.h

    r32169 r32193  
    2121#include <VBox/vm.h>
    2222
    23 VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended);
     23VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended, bool fSkipStateChanges);
    2424
    2525#endif
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