Changeset 32193 in vbox
- Timestamp:
- Sep 2, 2010 12:56:32 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 65497
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/FTM.cpp
r32179 r32193 29 29 #include <VBox/log.h> 30 30 #include <VBox/pgm.h> 31 #include <VBox/pdm.h> 31 32 32 33 #include <iprt/assert.h> … … 590 591 }; 591 592 593 592 594 /** 593 595 * VMR3ReqCallWait callback … … 602 604 } 603 605 604 /** 605 * Sync the VM state partially or fully 606 607 /** 608 * Sync the VM state 606 609 * 607 610 * @returns VBox status code. 608 611 * @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 */ 613 static 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); 665 642 666 643 /* Write protect all memory. */ … … 668 645 AssertRCReturn(rc, rc); 669 646 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 681 653 682 654 /** … … 773 745 */ 774 746 775 rc = ftmR3Perform Sync(pVM, FTMSYNCSTATE_FULL);747 rc = ftmR3PerformFullSync(pVM); 776 748 777 749 for (;;) … … 790 762 791 763 /* 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); 793 767 794 768 /* Enumerate all dirty pages and send them to the standby VM. */ … … 1090 1064 } 1091 1065 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 */ 1078 static 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 } 1092 1128 1093 1129 /** … … 1147 1183 STAM_PROFILE_START(&pVM->ftm.s.StatCheckpoint, a); 1148 1184 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); 1151 1186 1152 1187 STAM_PROFILE_STOP(&pVM->ftm.s.StatCheckpoint, a); -
trunk/src/VBox/VMM/FTMInternal.h
r32179 r32193 29 29 * @{ 30 30 */ 31 32 typedef enum33 {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_FULL40 } FTMSYNCSTATE;41 31 42 32 -
trunk/src/VBox/VMM/VM.cpp
r32190 r32193 1624 1624 * @returns VBox status code. 1625 1625 * 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 * 1636 1638 * @thread EMT 1637 1639 */ 1638 1640 static 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 1641 1646 LogFlow(("vmR3Save: pVM=%p cMsMaxDowntime=%u pszFilename=%p:{%s} pStreamOps=%p pvStreamOpsUser=%p enmAfter=%d pfnProgress=%p pvProgressUser=%p ppSSM=%p\n", 1642 1647 pVM, cMsMaxDowntime, pszFilename, pszFilename, pStreamOps, pvStreamOpsUser, enmAfter, pfnProgress, pvProgressUser, ppSSM)); … … 1657 1662 * Change the state and perform/start the saving. 1658 1663 */ 1659 int rc = vmR3TrySetState(pVM, "VMR3Save", 2, 1664 if (!fSkipStateChanges) 1665 { 1666 rc = vmR3TrySetState(pVM, "VMR3Save", 2, 1660 1667 VMSTATE_SAVING, VMSTATE_SUSPENDED, 1661 1668 VMSTATE_RUNNING_LS, VMSTATE_RUNNING); 1669 } 1670 else 1671 { 1672 Assert(enmAfter != SSMAFTER_TELEPORT); 1673 rc = 1; 1674 } 1675 1662 1676 if (rc == 1 && enmAfter != SSMAFTER_TELEPORT) 1663 1677 { 1664 1678 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); 1666 1681 } 1667 1682 else if (rc == 2 || enmAfter == SSMAFTER_TELEPORT) 1668 1683 { 1684 Assert(!fSkipStateChanges); 1669 1685 if (enmAfter == SSMAFTER_TELEPORT) 1670 1686 pVM->vm.s.fTeleportedAndNotFullyResumedYet = true; … … 1684 1700 * @returns VBox status code. 1685 1701 * 1686 * @param pVM The VM handle.1702 * @param pVM The VM handle. 1687 1703 * @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) 1695 1712 * 1696 1713 * @thread Non-EMT … … 1698 1715 static int vmR3SaveTeleport(PVM pVM, uint32_t cMsMaxDowntime, 1699 1716 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) 1701 1719 { 1702 1720 /* … … 1705 1723 PSSMHANDLE pSSM; 1706 1724 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); 1709 1727 if ( RT_SUCCESS(rc) 1710 1728 && pSSM) 1711 1729 { 1730 Assert(!fSkipStateChanges); 1731 1712 1732 /* 1713 1733 * Live snapshot. … … 1804 1824 int rc = vmR3SaveTeleport(pVM, 250 /*cMsMaxDowntime*/, 1805 1825 pszFilename, NULL /* pStreamOps */, NULL /* pvStreamOpsUser */, 1806 enmAfter, pfnProgress, pvUser, pfSuspended); 1826 enmAfter, pfnProgress, pvUser, pfSuspended, 1827 false /* fSkipStateChanges */); 1807 1828 LogFlow(("VMR3Save: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended)); 1808 1829 return rc; … … 1826 1847 * @param pvStreamOpsUser The user argument to the stream methods. 1827 1848 * @param pfSuspended Set if we suspended the VM. 1849 * @param fSkipStateChanges Set if we're supposed to skip state changes (FTM delta case) 1828 1850 * 1829 1851 * @thread Any … … 1832 1854 * RunningLS+SuspeningLS+SuspendedLS+Saving+Suspended. 1833 1855 */ 1834 VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended) 1856 VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended, 1857 bool fSkipStateChanges) 1835 1858 { 1836 1859 LogFlow(("VMR3SaveFT: pVM=%p pStreamOps=%p pvSteamOpsUser=%p pfSuspended=%p\n", … … 1850 1873 int rc = vmR3SaveTeleport(pVM, 250 /*cMsMaxDowntime*/, 1851 1874 NULL, pStreamOps, pvStreamOpsUser, 1852 SSMAFTER_CONTINUE, NULL, NULL, pfSuspended); 1875 SSMAFTER_CONTINUE, NULL, NULL, pfSuspended, 1876 fSkipStateChanges); 1853 1877 LogFlow(("VMR3SaveFT: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended)); 1854 1878 return rc; … … 1895 1919 int rc = vmR3SaveTeleport(pVM, cMsMaxDowntime, 1896 1920 NULL /*pszFilename*/, pStreamOps, pvStreamOpsUser, 1897 SSMAFTER_TELEPORT, pfnProgress, pvProgressUser, pfSuspended); 1921 SSMAFTER_TELEPORT, pfnProgress, pvProgressUser, pfSuspended, 1922 false /* fSkipStateChanges */); 1898 1923 LogFlow(("VMR3Teleport: returns %Rrc (*pfSuspended=%RTbool)\n", rc, *pfSuspended)); 1899 1924 return rc; -
trunk/src/VBox/VMM/include/internal/vm.h
r32169 r32193 21 21 #include <VBox/vm.h> 22 22 23 VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended );23 VMMR3DECL(int) VMR3SaveFT(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended, bool fSkipStateChanges); 24 24 25 25 #endif
Note:
See TracChangeset
for help on using the changeset viewer.