Changeset 32307 in vbox
- Timestamp:
- Sep 8, 2010 11:34:31 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 65644
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMPhys.cpp
r32295 r32307 984 984 pRam = pRam->CTX_SUFF(pNext)) 985 985 { 986 if (!PGM_RAM_RANGE_IS_AD_HOC(pRam)) 987 { 988 unsigned cPages = pRam->cb >> PAGE_SHIFT; 989 for (unsigned iPage = 0; iPage < cPages; iPage++) 986 unsigned cPages = pRam->cb >> PAGE_SHIFT; 987 for (unsigned iPage = 0; iPage < cPages; iPage++) 988 { 989 PPGMPAGE pPage = &pRam->aPages[iPage]; 990 PGMPAGETYPE enmPageType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 991 992 if ( RT_LIKELY(enmPageType == PGMPAGETYPE_RAM) 993 || enmPageType == PGMPAGETYPE_MMIO2) 990 994 { 991 PPGMPAGE pPage = &pRam->aPages[iPage]; 992 PGMPAGETYPE enmPageType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 993 994 if ( RT_LIKELY(enmPageType == PGMPAGETYPE_RAM) 995 || enmPageType == PGMPAGETYPE_MMIO2) 995 /* 996 * A RAM page. 997 */ 998 switch (PGM_PAGE_GET_STATE(pPage)) 996 999 { 997 /*998 * A RAM page.999 */1000 switch (PGM_PAGE_GET_STATE(pPage))1000 case PGM_PAGE_STATE_ALLOCATED: 1001 /** @todo Optimize this: Don't always re-enable write 1002 * monitoring if the page is known to be very busy. */ 1003 if (PGM_PAGE_IS_WRITTEN_TO(pPage)) 1001 1004 { 1002 case PGM_PAGE_STATE_ALLOCATED: 1003 /** @todo Optimize this: Don't always re-enable write 1004 * monitoring if the page is known to be very busy. */ 1005 if (PGM_PAGE_IS_WRITTEN_TO(pPage)) 1006 { 1007 PGM_PAGE_CLEAR_WRITTEN_TO(pPage); 1008 /* Remember this dirty page for the next (memory) sync. */ 1009 PGM_PAGE_SET_FT_DIRTY(pPage); 1010 } 1011 1012 PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_WRITE_MONITORED); 1013 pVM->pgm.s.cMonitoredPages++; 1014 break; 1015 1016 case PGM_PAGE_STATE_SHARED: 1017 AssertFailed(); 1018 break; 1019 1020 case PGM_PAGE_STATE_WRITE_MONITORED: /* nothing to change. */ 1021 default: 1022 break; 1005 PGM_PAGE_CLEAR_WRITTEN_TO(pPage); 1006 /* Remember this dirty page for the next (memory) sync. */ 1007 PGM_PAGE_SET_FT_DIRTY(pPage); 1023 1008 } 1009 1010 PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_WRITE_MONITORED); 1011 pVM->pgm.s.cMonitoredPages++; 1012 break; 1013 1014 case PGM_PAGE_STATE_SHARED: 1015 AssertFailed(); 1016 break; 1017 1018 case PGM_PAGE_STATE_WRITE_MONITORED: /* nothing to change. */ 1019 default: 1020 break; 1024 1021 } 1025 1022 } … … 1067 1064 pRam = pRam->CTX_SUFF(pNext)) 1068 1065 { 1069 if (!PGM_RAM_RANGE_IS_AD_HOC(pRam)) 1070 { 1071 unsigned cPages = pRam->cb >> PAGE_SHIFT; 1072 for (unsigned iPage = 0; iPage < cPages; iPage++) 1066 unsigned cPages = pRam->cb >> PAGE_SHIFT; 1067 for (unsigned iPage = 0; iPage < cPages; iPage++) 1068 { 1069 PPGMPAGE pPage = &pRam->aPages[iPage]; 1070 PGMPAGETYPE enmPageType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 1071 1072 if ( RT_LIKELY(enmPageType == PGMPAGETYPE_RAM) 1073 || enmPageType == PGMPAGETYPE_MMIO2) 1073 1074 { 1074 PPGMPAGE pPage = &pRam->aPages[iPage]; 1075 PGMPAGETYPE enmPageType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 1076 1077 if ( RT_LIKELY(enmPageType == PGMPAGETYPE_RAM) 1078 || enmPageType == PGMPAGETYPE_MMIO2) 1075 /* 1076 * A RAM page. 1077 */ 1078 switch (PGM_PAGE_GET_STATE(pPage)) 1079 1079 { 1080 /*1081 * A RAM page.1082 */1083 switch (PGM_PAGE_GET_STATE(pPage))1080 case PGM_PAGE_STATE_ALLOCATED: 1081 case PGM_PAGE_STATE_WRITE_MONITORED: 1082 if ( !PGM_PAGE_IS_WRITTEN_TO(pPage) /* not very recently updated? */ 1083 && PGM_PAGE_IS_FT_DIRTY(pPage)) 1084 1084 { 1085 case PGM_PAGE_STATE_ALLOCATED: 1086 case PGM_PAGE_STATE_WRITE_MONITORED: 1087 if ( !PGM_PAGE_IS_WRITTEN_TO(pPage) /* not very recently updated? */ 1088 && PGM_PAGE_IS_FT_DIRTY(pPage)) 1085 unsigned cbPageRange = PAGE_SIZE; 1086 unsigned iPageClean = iPage + 1; 1087 RTGCPHYS GCPhysPage = pRam->GCPhys + iPage * PAGE_SIZE; 1088 uint8_t *pu8Page = NULL; 1089 PGMPAGEMAPLOCK Lock; 1090 1091 /* Find the next clean page, so we can merge adjacent dirty pages. */ 1092 for (; iPageClean < cPages; iPageClean++) 1089 1093 { 1090 unsigned cbPageRange = PAGE_SIZE; 1091 unsigned iPageClean = iPage + 1; 1092 RTGCPHYS GCPhysPage = pRam->GCPhys + iPage * PAGE_SIZE; 1093 uint8_t *pu8Page = NULL; 1094 PGMPAGEMAPLOCK Lock; 1095 1096 /* Find the next clean page, so we can merge adjacent dirty pages. */ 1097 for (; iPageClean < cPages; iPageClean++) 1098 { 1099 PPGMPAGE pPageNext = &pRam->aPages[iPageClean]; 1100 if ( RT_UNLIKELY(PGM_PAGE_GET_TYPE(pPageNext) != PGMPAGETYPE_RAM) 1101 || PGM_PAGE_GET_STATE(pPageNext) != PGM_PAGE_STATE_ALLOCATED 1102 || PGM_PAGE_IS_WRITTEN_TO(pPageNext) 1103 || !PGM_PAGE_IS_FT_DIRTY(pPageNext) 1104 /* Crossing a chunk boundary? */ 1105 || (GCPhysPage & GMM_PAGEID_IDX_MASK) != ((GCPhysPage + cbPageRange) & GMM_PAGEID_IDX_MASK) 1106 ) 1107 break; 1108 1109 cbPageRange += PAGE_SIZE; 1110 } 1111 1112 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhysPage, (const void **)&pu8Page, &Lock); 1113 if (RT_SUCCESS(rc)) 1114 { 1115 /** @todo this is risky; the range might be changed, but little choice as the sync costs a lot of time */ 1116 pgmUnlock(pVM); 1117 pfnEnum(pVM, GCPhysPage, pu8Page, cbPageRange, pvUser); 1118 pgmLock(pVM); 1119 PGMPhysReleasePageMappingLock(pVM, &Lock); 1120 } 1121 1122 for (iPage; iPage < iPageClean; iPage++) 1123 PGM_PAGE_CLEAR_FT_DIRTY(&pRam->aPages[iPage]); 1124 1125 iPage = iPageClean - 1; 1094 PPGMPAGE pPageNext = &pRam->aPages[iPageClean]; 1095 if ( RT_UNLIKELY(PGM_PAGE_GET_TYPE(pPageNext) != PGMPAGETYPE_RAM) 1096 || PGM_PAGE_GET_STATE(pPageNext) != PGM_PAGE_STATE_ALLOCATED 1097 || PGM_PAGE_IS_WRITTEN_TO(pPageNext) 1098 || !PGM_PAGE_IS_FT_DIRTY(pPageNext) 1099 /* Crossing a chunk boundary? */ 1100 || (GCPhysPage & GMM_PAGEID_IDX_MASK) != ((GCPhysPage + cbPageRange) & GMM_PAGEID_IDX_MASK) 1101 ) 1102 break; 1103 1104 cbPageRange += PAGE_SIZE; 1126 1105 } 1127 break; 1106 1107 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhysPage, (const void **)&pu8Page, &Lock); 1108 if (RT_SUCCESS(rc)) 1109 { 1110 /** @todo this is risky; the range might be changed, but little choice as the sync costs a lot of time */ 1111 pgmUnlock(pVM); 1112 pfnEnum(pVM, GCPhysPage, pu8Page, cbPageRange, pvUser); 1113 pgmLock(pVM); 1114 PGMPhysReleasePageMappingLock(pVM, &Lock); 1115 } 1116 1117 for (iPage; iPage < iPageClean; iPage++) 1118 PGM_PAGE_CLEAR_FT_DIRTY(&pRam->aPages[iPage]); 1119 1120 iPage = iPageClean - 1; 1128 1121 } 1122 break; 1129 1123 } 1130 1124 }
Note:
See TracChangeset
for help on using the changeset viewer.