- Timestamp:
- Jan 31, 2011 2:32:30 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PDM.cpp
r35346 r35787 278 278 #define PDM_SAVED_STATE_VERSION 4 279 279 #define PDM_SAVED_STATE_VERSION_PRE_NMI_FF 3 280 281 282 /******************************************************************************* 283 * Structures and Typedefs * 284 *******************************************************************************/ 285 /** 286 * Statistics of asynchronous notification tasks - used by reset, suspend and 287 * power off. 288 */ 289 typedef struct PDMNOTIFYASYNCSTATS 290 { 291 /** The the start timestamp. */ 292 uint64_t uStartNsTs; 293 /** When to log the next time. */ 294 uint64_t cNsElapsedNextLog; 295 /** The loop counter. */ 296 uint32_t cLoops; 297 /** The number of pending asynchronous notification tasks. */ 298 uint32_t cAsync; 299 /** The name of the operation (log prefix). */ 300 const char *pszOp; 301 /** The current list buffer position. */ 302 size_t offList; 303 /** String containing a list of the pending tasks. */ 304 char szList[1024]; 305 } PDMNOTIFYASYNCSTATS; 306 /** Pointer to the stats of pending asynchronous notification tasks. */ 307 typedef PDMNOTIFYASYNCSTATS *PPDMNOTIFYASYNCSTATS; 280 308 281 309 … … 951 979 * 952 980 * @param pDrvIns The driver instance. 953 * @param pszDev iceNameThe parent device name.981 * @param pszDevName The parent device name. 954 982 * @param iDevInstance The parent device instance number. 955 983 * @param iLun The parent LUN number. 956 984 */ 957 DECLINLINE(int) pdmR3PowerOnDrv(PPDMDRVINS pDrvIns, const char *pszDev iceName, uint32_t iDevInstance, uint32_t iLun)985 DECLINLINE(int) pdmR3PowerOnDrv(PPDMDRVINS pDrvIns, const char *pszDevName, uint32_t iDevInstance, uint32_t iLun) 958 986 { 959 987 Assert(pDrvIns->Internal.s.fVMSuspended); … … 961 989 { 962 990 LogFlow(("PDMR3PowerOn: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 963 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));991 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 964 992 int rc = VINF_SUCCESS; pDrvIns->pReg->pfnPowerOn(pDrvIns); 965 993 if (RT_FAILURE(rc)) 966 994 { 967 995 LogRel(("PDMR3PowerOn: driver '%s'/%d on LUN#%d of device '%s'/%d -> %Rrc\n", 968 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance, rc));996 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance, rc)); 969 997 return rc; 970 998 } … … 1080 1108 1081 1109 /** 1110 * Initializes the asynchronous notifi stats structure. 1111 * 1112 * @param pThis The asynchronous notifification stats. 1113 * @param pszOp The name of the operation. 1114 */ 1115 static void pdmR3NotifyAsyncInit(PPDMNOTIFYASYNCSTATS pThis, const char *pszOp) 1116 { 1117 pThis->uStartNsTs = RTTimeNanoTS(); 1118 pThis->cNsElapsedNextLog = 0; 1119 pThis->cLoops = 0; 1120 pThis->cAsync = 0; 1121 pThis->pszOp = pszOp; 1122 pThis->offList = 0; 1123 pThis->szList[0] = '\0'; 1124 } 1125 1126 1127 /** 1128 * Begin a new loop, prepares to gather new stats. 1129 * 1130 * @param pThis The asynchronous notifification stats. 1131 */ 1132 static void pdmR3NotifyAsyncBeginLoop(PPDMNOTIFYASYNCSTATS pThis) 1133 { 1134 pThis->cLoops++; 1135 pThis->cAsync = 0; 1136 pThis->offList = 0; 1137 pThis->szList[0] = '\0'; 1138 } 1139 1140 1141 /** 1142 * Records a device or USB device with a pending asynchronous notification. 1143 * 1144 * @param pThis The asynchronous notifification stats. 1145 * @param pszName The name of the thing. 1146 * @param iInstance The instance number. 1147 */ 1148 static void pdmR3NotifyAsyncAdd(PPDMNOTIFYASYNCSTATS pThis, const char *pszName, uint32_t iInstance) 1149 { 1150 pThis->cAsync++; 1151 if (pThis->offList < sizeof(pThis->szList) - 4) 1152 pThis->offList += RTStrPrintf(&pThis->szList[pThis->offList], sizeof(pThis->szList) - pThis->offList, 1153 pThis->offList == 0 ? "%s/%u" : ", %s/%u", 1154 pszName, iInstance); 1155 } 1156 1157 1158 /** 1159 * Records the asynchronous completition of a reset, suspend or power off. 1160 * 1161 * @param pThis The asynchronous notifification stats. 1162 * @param pszDrvName The driver name. 1163 * @param iDrvInstance The driver instance number. 1164 * @param pszDevName The device or USB device name. 1165 * @param iDevInstance The device or USB device instance number. 1166 * @param iLun The LUN. 1167 */ 1168 static void pdmR3NotifyAsyncAddDrv(PPDMNOTIFYASYNCSTATS pThis, const char *pszDrvName, uint32_t iDrvInstance, 1169 const char *pszDevName, uint32_t iDevInstance, uint32_t iLun) 1170 { 1171 pThis->cAsync++; 1172 if (pThis->offList < sizeof(pThis->szList) - 8) 1173 pThis->offList += RTStrPrintf(&pThis->szList[pThis->offList], sizeof(pThis->szList) - pThis->offList, 1174 pThis->offList == 0 ? "%s/%u/%u/%s/%u" : ", %s/%u/%u/%s/%u", 1175 pszDevName, iDevInstance, iLun, pszDrvName, iDrvInstance); 1176 } 1177 1178 1179 /** 1180 * Log the stats. 1181 * 1182 * @param pThis The asynchronous notifification stats. 1183 */ 1184 static void pdmR3NotifyAsyncLog(PPDMNOTIFYASYNCSTATS pThis) 1185 { 1186 /* 1187 * Return if we shouldn't log at this point. 1188 * We log with an internval increasing from 0 sec to 60 sec. 1189 */ 1190 if (!pThis->cAsync) 1191 return; 1192 1193 uint64_t cNsElapsed = RTTimeNanoTS() - pThis->uStartNsTs; 1194 if (cNsElapsed < pThis->cNsElapsedNextLog) 1195 return; 1196 1197 if (pThis->cNsElapsedNextLog == 0) 1198 pThis->cNsElapsedNextLog = RT_NS_1SEC; 1199 else if (pThis->cNsElapsedNextLog >= RT_NS_1MIN / 2) 1200 pThis->cNsElapsedNextLog = RT_NS_1MIN; 1201 else 1202 pThis->cNsElapsedNextLog *= 2; 1203 1204 /* 1205 * Do the logging. 1206 */ 1207 LogRel(("%s: after %5llu ms, %u loops: %u async tasks - %s\n", 1208 pThis->pszOp, cNsElapsed / RT_NS_1MS, pThis->cLoops, pThis->cAsync, pThis->szList)); 1209 } 1210 1211 1212 /** 1213 * Wait for events and process pending requests. 1214 * 1215 * @param pThis The asynchronous notifification stats. 1216 * @param pVM The VM handle. 1217 */ 1218 static void pdmR3NotifyAsyncWaitAndProcessRequests(PPDMNOTIFYASYNCSTATS pThis, PVM pVM) 1219 { 1220 /** @todo This is utterly nuts and completely unsafe... will get back to it in a 1221 * bit I hope... */ 1222 VM_ASSERT_EMT0(pVM); 1223 int rc = VMR3AsyncPdmNotificationWaitU(&pVM->pUVM->aCpus[0]); 1224 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc - %s - %s\n", rc, pThis->pszOp, pThis->szList)); 1225 1226 rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY); 1227 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc - %s - %s\n", rc, pThis->pszOp, pThis->szList)); 1228 rc = VMR3ReqProcessU(pVM->pUVM, 0/*idDstCpu*/); 1229 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc - %s - %s\n", rc, pThis->pszOp, pThis->szList)); 1230 } 1231 1232 1233 /** 1082 1234 * Worker for PDMR3Reset that deals with one driver. 1083 1235 * 1084 1236 * @param pDrvIns The driver instance. 1085 * @param pcAsync The asynchronous reset notification counter. 1086 * @param pszDeviceName The parent device name. 1237 * @param pAsync The structure for recording asynchronous 1238 * notification tasks. 1239 * @param pszDevName The parent device name. 1087 1240 * @param iDevInstance The parent device instance number. 1088 1241 * @param iLun The parent LUN number. 1089 1242 */ 1090 DECLINLINE(bool) pdmR3ResetDrv(PPDMDRVINS pDrvIns, unsigned *pcAsync,1091 const char *pszDev iceName, uint32_t iDevInstance, uint32_t iLun)1243 DECLINLINE(bool) pdmR3ResetDrv(PPDMDRVINS pDrvIns, PPDMNOTIFYASYNCSTATS pAsync, 1244 const char *pszDevName, uint32_t iDevInstance, uint32_t iLun) 1092 1245 { 1093 1246 if (!pDrvIns->Internal.s.fVMReset) … … 1099 1252 { 1100 1253 LogFlow(("PDMR3Reset: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1101 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1254 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1102 1255 pDrvIns->pReg->pfnReset(pDrvIns); 1103 1256 if (pDrvIns->Internal.s.pfnAsyncNotify) 1104 1257 LogFlow(("PDMR3Reset: Async notification started - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1105 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1258 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1106 1259 } 1107 1260 else if (pDrvIns->Internal.s.pfnAsyncNotify(pDrvIns)) … … 1109 1262 pDrvIns->Internal.s.pfnAsyncNotify = false; 1110 1263 LogFlow(("PDMR3Reset: Async notification completed - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1111 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1264 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1112 1265 } 1113 1266 if (pDrvIns->Internal.s.pfnAsyncNotify) 1114 1267 { 1115 1268 pDrvIns->Internal.s.fVMReset = false; 1116 (*pcAsync)++; 1269 pdmR3NotifyAsyncAddDrv(pAsync, pDrvIns->Internal.s.pDrv->pReg->szName, pDrvIns->iInstance, 1270 pszDevName, iDevInstance, iLun); 1117 1271 return false; 1118 1272 } … … 1127 1281 * 1128 1282 * @param pUsbIns The USB device instance. 1129 * @param pcAsync The asynchronous reset notification counter. 1130 */ 1131 DECLINLINE(void) pdmR3ResetUsb(PPDMUSBINS pUsbIns, unsigned *pcAsync) 1283 * @param pAsync The structure for recording asynchronous 1284 * notification tasks. 1285 */ 1286 DECLINLINE(void) pdmR3ResetUsb(PPDMUSBINS pUsbIns, PPDMNOTIFYASYNCSTATS pAsync) 1132 1287 { 1133 1288 if (!pUsbIns->Internal.s.fVMReset) … … 1151 1306 { 1152 1307 pUsbIns->Internal.s.fVMReset = false; 1153 (*pcAsync)++;1308 pdmR3NotifyAsyncAdd(pAsync, pUsbIns->Internal.s.pUsbDev->pReg->szName, pUsbIns->iInstance); 1154 1309 } 1155 1310 } … … 1162 1317 * 1163 1318 * @param pDevIns The device instance. 1164 * @param pcAsync The asynchronous reset notification counter. 1165 */ 1166 DECLINLINE(void) pdmR3ResetDev(PPDMDEVINS pDevIns, unsigned *pcAsync) 1319 * @param pAsync The structure for recording asynchronous 1320 * notification tasks. 1321 */ 1322 DECLINLINE(void) pdmR3ResetDev(PPDMDEVINS pDevIns, PPDMNOTIFYASYNCSTATS pAsync) 1167 1323 { 1168 1324 if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_RESET)) … … 1186 1342 { 1187 1343 pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_RESET; 1188 (*pcAsync)++;1344 pdmR3NotifyAsyncAdd(pAsync, pDevIns->Internal.s.pDevR3->pReg->szName, pDevIns->iInstance); 1189 1345 } 1190 1346 } … … 1242 1398 * The outer loop repeats until there are no more async requests. 1243 1399 */ 1244 unsigned cAsync; 1245 for (unsigned iLoop = 0; ; iLoop++) 1246 { 1400 PDMNOTIFYASYNCSTATS Async; 1401 pdmR3NotifyAsyncInit(&Async, "PDMR3Reset"); 1402 for (;;) 1403 { 1404 pdmR3NotifyAsyncBeginLoop(&Async); 1405 1247 1406 /* 1248 1407 * Iterate thru the device instances and USB device instances, 1249 1408 * processing the drivers associated with those. 1250 1409 */ 1251 cAsync = 0;1252 1410 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3) 1253 1411 { 1254 unsigned const cAsyncStart = cAsync;1255 1256 if ( cAsync == cAsyncStart)1412 unsigned const cAsyncStart = Async.cAsync; 1413 1414 if (Async.cAsync == cAsyncStart) 1257 1415 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext) 1258 1416 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1259 if (!pdmR3ResetDrv(pDrvIns, & cAsync, pDevIns->pReg->szName, pDevIns->iInstance, pLun->iLun))1417 if (!pdmR3ResetDrv(pDrvIns, &Async, pDevIns->pReg->szName, pDevIns->iInstance, pLun->iLun)) 1260 1418 break; 1261 1419 1262 if ( cAsync == cAsyncStart)1263 pdmR3ResetDev(pDevIns, & cAsync);1420 if (Async.cAsync == cAsyncStart) 1421 pdmR3ResetDev(pDevIns, &Async); 1264 1422 } 1265 1423 … … 1267 1425 for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext) 1268 1426 { 1269 unsigned const cAsyncStart = cAsync;1427 unsigned const cAsyncStart = Async.cAsync; 1270 1428 1271 1429 for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext) 1272 1430 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1273 if (!pdmR3ResetDrv(pDrvIns, & cAsync, pUsbIns->pReg->szName, pUsbIns->iInstance, pLun->iLun))1431 if (!pdmR3ResetDrv(pDrvIns, &Async, pUsbIns->pReg->szName, pUsbIns->iInstance, pLun->iLun)) 1274 1432 break; 1275 1433 1276 if ( cAsync == cAsyncStart)1277 pdmR3ResetUsb(pUsbIns, & cAsync);1434 if (Async.cAsync == cAsyncStart) 1435 pdmR3ResetUsb(pUsbIns, &Async); 1278 1436 } 1279 1437 #endif 1280 if (! cAsync)1438 if (!Async.cAsync) 1281 1439 break; 1282 1283 /* 1284 * Process requests. 1285 */ 1286 /** @todo This is utterly nuts and completely unsafe... will get back to it in a 1287 * bit I hope... */ 1288 int rc = VMR3AsyncPdmNotificationWaitU(&pVM->pUVM->aCpus[0]); 1289 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1290 rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY); 1291 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1292 rc = VMR3ReqProcessU(pVM->pUVM, 0/*idDstCpu*/); 1293 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1440 pdmR3NotifyAsyncLog(&Async); 1441 pdmR3NotifyAsyncWaitAndProcessRequests(&Async, pVM); 1294 1442 } 1295 1443 … … 1309 1457 * 1310 1458 * @param pDrvIns The driver instance. 1311 * @param pcAsync The asynchronous suspend notification counter. 1312 * @param pszDeviceName The parent device name. 1459 * @param pAsync The structure for recording asynchronous 1460 * notification tasks. 1461 * @param pszDevName The parent device name. 1313 1462 * @param iDevInstance The parent device instance number. 1314 1463 * @param iLun The parent LUN number. 1315 1464 */ 1316 DECLINLINE(bool) pdmR3SuspendDrv(PPDMDRVINS pDrvIns, unsigned *pcAsync,1317 const char *pszDev iceName, uint32_t iDevInstance, uint32_t iLun)1465 DECLINLINE(bool) pdmR3SuspendDrv(PPDMDRVINS pDrvIns, PPDMNOTIFYASYNCSTATS pAsync, 1466 const char *pszDevName, uint32_t iDevInstance, uint32_t iLun) 1318 1467 { 1319 1468 if (!pDrvIns->Internal.s.fVMSuspended) … … 1325 1474 { 1326 1475 LogFlow(("PDMR3Suspend: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1327 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1476 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1328 1477 pDrvIns->pReg->pfnSuspend(pDrvIns); 1329 1478 if (pDrvIns->Internal.s.pfnAsyncNotify) 1330 1479 LogFlow(("PDMR3Suspend: Async notification started - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1331 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1480 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1332 1481 } 1333 1482 else if (pDrvIns->Internal.s.pfnAsyncNotify(pDrvIns)) 1334 1483 { 1335 pDrvIns->Internal.s.pfnAsyncNotify = false;1484 pDrvIns->Internal.s.pfnAsyncNotify = NULL; 1336 1485 LogFlow(("PDMR3Suspend: Async notification completed - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1337 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1486 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1338 1487 } 1339 1488 if (pDrvIns->Internal.s.pfnAsyncNotify) 1340 1489 { 1341 1490 pDrvIns->Internal.s.fVMSuspended = false; 1342 (*pcAsync)++;1491 pdmR3NotifyAsyncAddDrv(pAsync, pDrvIns->Internal.s.pDrv->pReg->szName, pDrvIns->iInstance, pszDevName, iDevInstance, iLun); 1343 1492 return false; 1344 1493 } … … 1353 1502 * 1354 1503 * @param pUsbIns The USB device instance. 1355 * @param pcAsync The asynchronous suspend notification counter. 1356 */ 1357 DECLINLINE(void) pdmR3SuspendUsb(PPDMUSBINS pUsbIns, unsigned *pcAsync) 1504 * @param pAsync The structure for recording asynchronous 1505 * notification tasks. 1506 */ 1507 DECLINLINE(void) pdmR3SuspendUsb(PPDMUSBINS pUsbIns, PPDMNOTIFYASYNCSTATS pAsync) 1358 1508 { 1359 1509 if (!pUsbIns->Internal.s.fVMSuspended) … … 1377 1527 { 1378 1528 pUsbIns->Internal.s.fVMSuspended = false; 1379 (*pcAsync)++;1529 pdmR3NotifyAsyncAdd(pAsync, pUsbIns->Internal.s.pUsbDev->pReg->szName, pUsbIns->iInstance); 1380 1530 } 1381 1531 } … … 1388 1538 * 1389 1539 * @param pDevIns The device instance. 1390 * @param pcAsync The asynchronous suspend notification counter. 1391 */ 1392 DECLINLINE(void) pdmR3SuspendDev(PPDMDEVINS pDevIns, unsigned *pcAsync) 1540 * @param pAsync The structure for recording asynchronous 1541 * notification tasks. 1542 */ 1543 DECLINLINE(void) pdmR3SuspendDev(PPDMDEVINS pDevIns, PPDMNOTIFYASYNCSTATS pAsync) 1393 1544 { 1394 1545 if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_SUSPENDED)) … … 1412 1563 { 1413 1564 pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_SUSPENDED; 1414 (*pcAsync)++;1565 pdmR3NotifyAsyncAdd(pAsync, pDevIns->Internal.s.pDevR3->pReg->szName, pDevIns->iInstance); 1415 1566 } 1416 1567 } … … 1439 1590 * on failure. 1440 1591 */ 1441 unsigned cAsync; 1442 for (unsigned iLoop = 0; ; iLoop++) 1443 { 1592 PDMNOTIFYASYNCSTATS Async; 1593 pdmR3NotifyAsyncInit(&Async, "PDMR3Suspend"); 1594 for (;;) 1595 { 1596 pdmR3NotifyAsyncBeginLoop(&Async); 1597 1444 1598 /* 1445 1599 * Iterate thru the device instances and USB device instances, … … 1451 1605 * taking any. (DrvVD changes to read-only in this particular case.) 1452 1606 */ 1453 cAsync = 0;1454 1607 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3) 1455 1608 { 1456 unsigned const cAsyncStart = cAsync;1609 unsigned const cAsyncStart = Async.cAsync; 1457 1610 1458 1611 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION) 1459 pdmR3SuspendDev(pDevIns, & cAsync);1460 1461 if ( cAsync == cAsyncStart)1612 pdmR3SuspendDev(pDevIns, &Async); 1613 1614 if (Async.cAsync == cAsyncStart) 1462 1615 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext) 1463 1616 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1464 if (!pdmR3SuspendDrv(pDrvIns, & cAsync, pDevIns->pReg->szName, pDevIns->iInstance, pLun->iLun))1617 if (!pdmR3SuspendDrv(pDrvIns, &Async, pDevIns->pReg->szName, pDevIns->iInstance, pLun->iLun)) 1465 1618 break; 1466 1619 1467 if ( cAsync == cAsyncStart1620 if ( Async.cAsync == cAsyncStart 1468 1621 && !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION)) 1469 pdmR3SuspendDev(pDevIns, & cAsync);1622 pdmR3SuspendDev(pDevIns, &Async); 1470 1623 } 1471 1624 … … 1473 1626 for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext) 1474 1627 { 1475 unsigned const cAsyncStart = cAsync;1628 unsigned const cAsyncStart = Async.cAsync; 1476 1629 1477 1630 for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext) 1478 1631 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1479 if (!pdmR3SuspendDrv(pDrvIns, & cAsync, pUsbIns->pReg->szName, pUsbIns->iInstance, pLun->iLun))1632 if (!pdmR3SuspendDrv(pDrvIns, &Async, pUsbIns->pReg->szName, pUsbIns->iInstance, pLun->iLun)) 1480 1633 break; 1481 1634 1482 if ( cAsync == cAsyncStart)1483 pdmR3SuspendUsb(pUsbIns, & cAsync);1635 if (Async.cAsync == cAsyncStart) 1636 pdmR3SuspendUsb(pUsbIns, &Async); 1484 1637 } 1485 1638 #endif 1486 if (! cAsync)1639 if (!Async.cAsync) 1487 1640 break; 1488 1489 /* 1490 * Process requests. 1491 */ 1492 /** @todo This is utterly nuts and completely unsafe... will get back to it in a 1493 * bit I hope... */ 1494 int rc = VMR3AsyncPdmNotificationWaitU(&pVM->pUVM->aCpus[0]); 1495 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1496 rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY); 1497 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1498 rc = VMR3ReqProcessU(pVM->pUVM, 0/*idDstCpu*/); 1499 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1641 pdmR3NotifyAsyncLog(&Async); 1642 pdmR3NotifyAsyncWaitAndProcessRequests(&Async, pVM); 1500 1643 } 1501 1644 … … 1513 1656 * 1514 1657 * @param pDrvIns The driver instance. 1515 * @param pszDev iceNameThe parent device name.1658 * @param pszDevName The parent device name. 1516 1659 * @param iDevInstance The parent device instance number. 1517 1660 * @param iLun The parent LUN number. 1518 1661 */ 1519 DECLINLINE(int) pdmR3ResumeDrv(PPDMDRVINS pDrvIns, const char *pszDev iceName, uint32_t iDevInstance, uint32_t iLun)1662 DECLINLINE(int) pdmR3ResumeDrv(PPDMDRVINS pDrvIns, const char *pszDevName, uint32_t iDevInstance, uint32_t iLun) 1520 1663 { 1521 1664 Assert(pDrvIns->Internal.s.fVMSuspended); … … 1523 1666 { 1524 1667 LogFlow(("PDMR3Resume: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1525 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1668 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1526 1669 int rc = VINF_SUCCESS; pDrvIns->pReg->pfnResume(pDrvIns); 1527 1670 if (RT_FAILURE(rc)) 1528 1671 { 1529 1672 LogRel(("PDMR3Resume: driver '%s'/%d on LUN#%d of device '%s'/%d -> %Rrc\n", 1530 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance, rc));1673 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance, rc)); 1531 1674 return rc; 1532 1675 } … … 1647 1790 * 1648 1791 * @param pDrvIns The driver instance. 1649 * @param pcAsync The asynchronous power off notification counter. 1650 * @param pszDeviceName The parent device name. 1792 * @param pAsync The structure for recording asynchronous 1793 * notification tasks. 1794 * @param pszDevName The parent device name. 1651 1795 * @param iDevInstance The parent device instance number. 1652 1796 * @param iLun The parent LUN number. 1653 1797 */ 1654 DECLINLINE(bool) pdmR3PowerOffDrv(PPDMDRVINS pDrvIns, unsigned *pcAsync,1655 const char *pszDev iceName, uint32_t iDevInstance, uint32_t iLun)1798 DECLINLINE(bool) pdmR3PowerOffDrv(PPDMDRVINS pDrvIns, PPDMNOTIFYASYNCSTATS pAsync, 1799 const char *pszDevName, uint32_t iDevInstance, uint32_t iLun) 1656 1800 { 1657 1801 if (!pDrvIns->Internal.s.fVMSuspended) … … 1663 1807 { 1664 1808 LogFlow(("PDMR3PowerOff: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1665 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1809 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1666 1810 pDrvIns->pReg->pfnPowerOff(pDrvIns); 1667 1811 if (pDrvIns->Internal.s.pfnAsyncNotify) 1668 1812 LogFlow(("PDMR3PowerOff: Async notification started - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1669 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1813 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1670 1814 } 1671 1815 else if (pDrvIns->Internal.s.pfnAsyncNotify(pDrvIns)) … … 1673 1817 pDrvIns->Internal.s.pfnAsyncNotify = false; 1674 1818 LogFlow(("PDMR3PowerOff: Async notification completed - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1675 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDev iceName, iDevInstance));1819 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance)); 1676 1820 } 1677 1821 if (pDrvIns->Internal.s.pfnAsyncNotify) 1678 1822 { 1679 1823 pDrvIns->Internal.s.fVMSuspended = false; 1680 (*pcAsync)++; 1824 pdmR3NotifyAsyncAddDrv(pAsync, pDrvIns->Internal.s.pDrv->pReg->szName, pDrvIns->iInstance, 1825 pszDevName, iDevInstance, iLun); 1681 1826 return false; 1682 1827 } … … 1691 1836 * 1692 1837 * @param pUsbIns The USB device instance. 1693 * @param pcAsync The asynchronous power off notification counter. 1694 */ 1695 DECLINLINE(void) pdmR3PowerOffUsb(PPDMUSBINS pUsbIns, unsigned *pcAsync) 1838 * @param pAsync The structure for recording asynchronous 1839 * notification tasks. 1840 */ 1841 DECLINLINE(void) pdmR3PowerOffUsb(PPDMUSBINS pUsbIns, PPDMNOTIFYASYNCSTATS pAsync) 1696 1842 { 1697 1843 if (!pUsbIns->Internal.s.fVMSuspended) … … 1715 1861 { 1716 1862 pUsbIns->Internal.s.fVMSuspended = false; 1717 (*pcAsync)++;1863 pdmR3NotifyAsyncAdd(pAsync, pUsbIns->Internal.s.pUsbDev->pReg->szName, pUsbIns->iInstance); 1718 1864 } 1719 1865 } … … 1726 1872 * 1727 1873 * @param pDevIns The device instance. 1728 * @param pcAsync The asynchronous power off notification counter. 1729 */ 1730 DECLINLINE(void) pdmR3PowerOffDev(PPDMDEVINS pDevIns, unsigned *pcAsync) 1874 * @param pAsync The structure for recording asynchronous 1875 * notification tasks. 1876 */ 1877 DECLINLINE(void) pdmR3PowerOffDev(PPDMDEVINS pDevIns, PPDMNOTIFYASYNCSTATS pAsync) 1731 1878 { 1732 1879 if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_SUSPENDED)) … … 1750 1897 { 1751 1898 pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_SUSPENDED; 1752 (*pcAsync)++;1899 pdmR3NotifyAsyncAdd(pAsync, pDevIns->Internal.s.pDevR3->pReg->szName, pDevIns->iInstance); 1753 1900 } 1754 1901 } … … 1770 1917 * The outer loop repeats until there are no more async requests. 1771 1918 */ 1772 unsigned cAsync; 1773 for (unsigned iLoop = 0; ; iLoop++) 1774 { 1919 PDMNOTIFYASYNCSTATS Async; 1920 pdmR3NotifyAsyncInit(&Async, "PDMR3PowerOff"); 1921 for (;;) 1922 { 1923 pdmR3NotifyAsyncBeginLoop(&Async); 1924 1775 1925 /* 1776 1926 * Iterate thru the device instances and USB device instances, … … 1782 1932 * taking any. (DrvVD changes to read-only in this particular case.) 1783 1933 */ 1784 cAsync = 0;1785 1934 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3) 1786 1935 { 1787 unsigned const cAsyncStart = cAsync;1936 unsigned const cAsyncStart = Async.cAsync; 1788 1937 1789 1938 if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION) 1790 pdmR3PowerOffDev(pDevIns, & cAsync);1791 1792 if ( cAsync == cAsyncStart)1939 pdmR3PowerOffDev(pDevIns, &Async); 1940 1941 if (Async.cAsync == cAsyncStart) 1793 1942 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext) 1794 1943 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1795 if (!pdmR3PowerOffDrv(pDrvIns, & cAsync, pDevIns->pReg->szName, pDevIns->iInstance, pLun->iLun))1944 if (!pdmR3PowerOffDrv(pDrvIns, &Async, pDevIns->pReg->szName, pDevIns->iInstance, pLun->iLun)) 1796 1945 break; 1797 1946 1798 if ( cAsync == cAsyncStart1947 if ( Async.cAsync == cAsyncStart 1799 1948 && !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION)) 1800 pdmR3PowerOffDev(pDevIns, & cAsync);1949 pdmR3PowerOffDev(pDevIns, &Async); 1801 1950 } 1802 1951 … … 1804 1953 for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext) 1805 1954 { 1806 unsigned const cAsyncStart = cAsync;1955 unsigned const cAsyncStart = Async.cAsync; 1807 1956 1808 1957 for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext) 1809 1958 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1810 if (!pdmR3PowerOffDrv(pDrvIns, & cAsync, pUsbIns->pReg->szName, pUsbIns->iInstance, pLun->iLun))1959 if (!pdmR3PowerOffDrv(pDrvIns, &Async, pUsbIns->pReg->szName, pUsbIns->iInstance, pLun->iLun)) 1811 1960 break; 1812 1961 1813 if ( cAsync == cAsyncStart)1814 pdmR3PowerOffUsb(pUsbIns, & cAsync);1962 if (Async.cAsync == cAsyncStart) 1963 pdmR3PowerOffUsb(pUsbIns, &Async); 1815 1964 } 1816 1965 #endif 1817 if (! cAsync)1966 if (!Async.cAsync) 1818 1967 break; 1819 1820 /* 1821 * Process requests. 1822 */ 1823 /** @todo This is utterly nuts and completely unsafe... will get back to it in a 1824 * bit I hope... */ 1825 int rc = VMR3AsyncPdmNotificationWaitU(&pVM->pUVM->aCpus[0]); 1826 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1827 rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY); 1828 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1829 rc = VMR3ReqProcessU(pVM->pUVM, 0/*idDstCpu*/); 1830 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1968 pdmR3NotifyAsyncLog(&Async); 1969 pdmR3NotifyAsyncWaitAndProcessRequests(&Async, pVM); 1831 1970 } 1832 1971
Note:
See TracChangeset
for help on using the changeset viewer.