VirtualBox

Changeset 35787 in vbox for trunk


Ignore:
Timestamp:
Jan 31, 2011 2:32:30 PM (14 years ago)
Author:
vboxsync
Message:

PDM.cpp: Instrumented the asynchronous reset, suspend and poweroff notifications.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r35346 r35787  
    278278#define PDM_SAVED_STATE_VERSION             4
    279279#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 */
     289typedef 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. */
     307typedef PDMNOTIFYASYNCSTATS *PPDMNOTIFYASYNCSTATS;
    280308
    281309
     
    951979 *
    952980 * @param   pDrvIns             The driver instance.
    953  * @param   pszDeviceName       The parent device name.
     981 * @param   pszDevName          The parent device name.
    954982 * @param   iDevInstance        The parent device instance number.
    955983 * @param   iLun                The parent LUN number.
    956984 */
    957 DECLINLINE(int) pdmR3PowerOnDrv(PPDMDRVINS pDrvIns, const char *pszDeviceName, uint32_t iDevInstance, uint32_t iLun)
     985DECLINLINE(int) pdmR3PowerOnDrv(PPDMDRVINS pDrvIns, const char *pszDevName, uint32_t iDevInstance, uint32_t iLun)
    958986{
    959987    Assert(pDrvIns->Internal.s.fVMSuspended);
     
    961989    {
    962990        LogFlow(("PDMR3PowerOn: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    963                  pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     991                 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    964992        int rc = VINF_SUCCESS; pDrvIns->pReg->pfnPowerOn(pDrvIns);
    965993        if (RT_FAILURE(rc))
    966994        {
    967995            LogRel(("PDMR3PowerOn: driver '%s'/%d on LUN#%d of device '%s'/%d -> %Rrc\n",
    968                     pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance, rc));
     996                    pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance, rc));
    969997            return rc;
    970998        }
     
    10801108
    10811109/**
     1110 * Initializes the asynchronous notifi stats structure.
     1111 *
     1112 * @param   pThis               The asynchronous notifification stats.
     1113 * @param   pszOp               The name of the operation.
     1114 */
     1115static 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 */
     1132static 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 */
     1148static 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 */
     1168static 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 */
     1184static 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 */
     1218static 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/**
    10821234 * Worker for PDMR3Reset that deals with one driver.
    10831235 *
    10841236 * @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.
    10871240 * @param   iDevInstance        The parent device instance number.
    10881241 * @param   iLun                The parent LUN number.
    10891242 */
    1090 DECLINLINE(bool) pdmR3ResetDrv(PPDMDRVINS pDrvIns, unsigned *pcAsync,
    1091                                const char *pszDeviceName, uint32_t iDevInstance, uint32_t iLun)
     1243DECLINLINE(bool) pdmR3ResetDrv(PPDMDRVINS pDrvIns, PPDMNOTIFYASYNCSTATS pAsync,
     1244                               const char *pszDevName, uint32_t iDevInstance, uint32_t iLun)
    10921245{
    10931246    if (!pDrvIns->Internal.s.fVMReset)
     
    10991252            {
    11001253                LogFlow(("PDMR3Reset: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1101                          pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1254                         pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    11021255                pDrvIns->pReg->pfnReset(pDrvIns);
    11031256                if (pDrvIns->Internal.s.pfnAsyncNotify)
    11041257                    LogFlow(("PDMR3Reset: Async notification started - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1105                              pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1258                             pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    11061259            }
    11071260            else if (pDrvIns->Internal.s.pfnAsyncNotify(pDrvIns))
     
    11091262                pDrvIns->Internal.s.pfnAsyncNotify = false;
    11101263                LogFlow(("PDMR3Reset: Async notification completed - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1111                          pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1264                         pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    11121265            }
    11131266            if (pDrvIns->Internal.s.pfnAsyncNotify)
    11141267            {
    11151268                pDrvIns->Internal.s.fVMReset = false;
    1116                 (*pcAsync)++;
     1269                pdmR3NotifyAsyncAddDrv(pAsync, pDrvIns->Internal.s.pDrv->pReg->szName, pDrvIns->iInstance,
     1270                                       pszDevName, iDevInstance, iLun);
    11171271                return false;
    11181272            }
     
    11271281 *
    11281282 * @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 */
     1286DECLINLINE(void) pdmR3ResetUsb(PPDMUSBINS pUsbIns, PPDMNOTIFYASYNCSTATS pAsync)
    11321287{
    11331288    if (!pUsbIns->Internal.s.fVMReset)
     
    11511306            {
    11521307                pUsbIns->Internal.s.fVMReset = false;
    1153                 (*pcAsync)++;
     1308                pdmR3NotifyAsyncAdd(pAsync, pUsbIns->Internal.s.pUsbDev->pReg->szName, pUsbIns->iInstance);
    11541309            }
    11551310        }
     
    11621317 *
    11631318 * @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 */
     1322DECLINLINE(void) pdmR3ResetDev(PPDMDEVINS pDevIns, PPDMNOTIFYASYNCSTATS pAsync)
    11671323{
    11681324    if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_RESET))
     
    11861342            {
    11871343                pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_RESET;
    1188                 (*pcAsync)++;
     1344                pdmR3NotifyAsyncAdd(pAsync, pDevIns->Internal.s.pDevR3->pReg->szName, pDevIns->iInstance);
    11891345            }
    11901346        }
     
    12421398     * The outer loop repeats until there are no more async requests.
    12431399     */
    1244     unsigned cAsync;
    1245     for (unsigned iLoop = 0; ; iLoop++)
    1246     {
     1400    PDMNOTIFYASYNCSTATS     Async;
     1401    pdmR3NotifyAsyncInit(&Async, "PDMR3Reset");
     1402    for (;;)
     1403    {
     1404        pdmR3NotifyAsyncBeginLoop(&Async);
     1405
    12471406        /*
    12481407         * Iterate thru the device instances and USB device instances,
    12491408         * processing the drivers associated with those.
    12501409         */
    1251         cAsync = 0;
    12521410        for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
    12531411        {
    1254             unsigned const cAsyncStart = cAsync;
    1255 
    1256             if (cAsync == cAsyncStart)
     1412            unsigned const cAsyncStart = Async.cAsync;
     1413
     1414            if (Async.cAsync == cAsyncStart)
    12571415                for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)
    12581416                    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))
    12601418                            break;
    12611419
    1262                         if (cAsync == cAsyncStart)
    1263                 pdmR3ResetDev(pDevIns, &cAsync);
     1420                        if (Async.cAsync == cAsyncStart)
     1421                pdmR3ResetDev(pDevIns, &Async);
    12641422        }
    12651423
     
    12671425        for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext)
    12681426        {
    1269             unsigned const cAsyncStart = cAsync;
     1427            unsigned const cAsyncStart = Async.cAsync;
    12701428
    12711429            for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext)
    12721430                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))
    12741432                        break;
    12751433
    1276             if (cAsync == cAsyncStart)
    1277                 pdmR3ResetUsb(pUsbIns, &cAsync);
     1434            if (Async.cAsync == cAsyncStart)
     1435                pdmR3ResetUsb(pUsbIns, &Async);
    12781436        }
    12791437#endif
    1280         if (!cAsync)
     1438        if (!Async.cAsync)
    12811439            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);
    12941442    }
    12951443
     
    13091457 *
    13101458 * @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.
    13131462 * @param   iDevInstance        The parent device instance number.
    13141463 * @param   iLun                The parent LUN number.
    13151464 */
    1316 DECLINLINE(bool) pdmR3SuspendDrv(PPDMDRVINS pDrvIns, unsigned *pcAsync,
    1317                                  const char *pszDeviceName, uint32_t iDevInstance, uint32_t iLun)
     1465DECLINLINE(bool) pdmR3SuspendDrv(PPDMDRVINS pDrvIns, PPDMNOTIFYASYNCSTATS pAsync,
     1466                                 const char *pszDevName, uint32_t iDevInstance, uint32_t iLun)
    13181467{
    13191468    if (!pDrvIns->Internal.s.fVMSuspended)
     
    13251474            {
    13261475                LogFlow(("PDMR3Suspend: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1327                          pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1476                         pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    13281477                pDrvIns->pReg->pfnSuspend(pDrvIns);
    13291478                if (pDrvIns->Internal.s.pfnAsyncNotify)
    13301479                    LogFlow(("PDMR3Suspend: Async notification started - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1331                              pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1480                             pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    13321481            }
    13331482            else if (pDrvIns->Internal.s.pfnAsyncNotify(pDrvIns))
    13341483            {
    1335                 pDrvIns->Internal.s.pfnAsyncNotify = false;
     1484                pDrvIns->Internal.s.pfnAsyncNotify = NULL;
    13361485                LogFlow(("PDMR3Suspend: Async notification completed - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1337                          pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1486                         pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    13381487            }
    13391488            if (pDrvIns->Internal.s.pfnAsyncNotify)
    13401489            {
    13411490                pDrvIns->Internal.s.fVMSuspended = false;
    1342                 (*pcAsync)++;
     1491                pdmR3NotifyAsyncAddDrv(pAsync, pDrvIns->Internal.s.pDrv->pReg->szName, pDrvIns->iInstance, pszDevName, iDevInstance, iLun);
    13431492                return false;
    13441493            }
     
    13531502 *
    13541503 * @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 */
     1507DECLINLINE(void) pdmR3SuspendUsb(PPDMUSBINS pUsbIns, PPDMNOTIFYASYNCSTATS pAsync)
    13581508{
    13591509    if (!pUsbIns->Internal.s.fVMSuspended)
     
    13771527            {
    13781528                pUsbIns->Internal.s.fVMSuspended = false;
    1379                 (*pcAsync)++;
     1529                pdmR3NotifyAsyncAdd(pAsync, pUsbIns->Internal.s.pUsbDev->pReg->szName, pUsbIns->iInstance);
    13801530            }
    13811531        }
     
    13881538 *
    13891539 * @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 */
     1543DECLINLINE(void) pdmR3SuspendDev(PPDMDEVINS pDevIns, PPDMNOTIFYASYNCSTATS pAsync)
    13931544{
    13941545    if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_SUSPENDED))
     
    14121563            {
    14131564                pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_SUSPENDED;
    1414                 (*pcAsync)++;
     1565                pdmR3NotifyAsyncAdd(pAsync, pDevIns->Internal.s.pDevR3->pReg->szName, pDevIns->iInstance);
    14151566            }
    14161567        }
     
    14391590     *       on failure.
    14401591     */
    1441     unsigned cAsync;
    1442     for (unsigned iLoop = 0; ; iLoop++)
    1443     {
     1592    PDMNOTIFYASYNCSTATS Async;
     1593    pdmR3NotifyAsyncInit(&Async, "PDMR3Suspend");
     1594    for (;;)
     1595    {
     1596        pdmR3NotifyAsyncBeginLoop(&Async);
     1597
    14441598        /*
    14451599         * Iterate thru the device instances and USB device instances,
     
    14511605         * taking any. (DrvVD changes to read-only in this particular case.)
    14521606         */
    1453         cAsync = 0;
    14541607        for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
    14551608        {
    1456             unsigned const cAsyncStart = cAsync;
     1609            unsigned const cAsyncStart = Async.cAsync;
    14571610
    14581611            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)
    14621615                for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)
    14631616                    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))
    14651618                            break;
    14661619
    1467             if (    cAsync == cAsyncStart
     1620            if (    Async.cAsync == cAsyncStart
    14681621                && !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION))
    1469                 pdmR3SuspendDev(pDevIns, &cAsync);
     1622                pdmR3SuspendDev(pDevIns, &Async);
    14701623        }
    14711624
     
    14731626        for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext)
    14741627        {
    1475             unsigned const cAsyncStart = cAsync;
     1628            unsigned const cAsyncStart = Async.cAsync;
    14761629
    14771630            for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext)
    14781631                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))
    14801633                        break;
    14811634
    1482             if (cAsync == cAsyncStart)
    1483                 pdmR3SuspendUsb(pUsbIns, &cAsync);
     1635            if (Async.cAsync == cAsyncStart)
     1636                pdmR3SuspendUsb(pUsbIns, &Async);
    14841637        }
    14851638#endif
    1486         if (!cAsync)
     1639        if (!Async.cAsync)
    14871640            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);
    15001643    }
    15011644
     
    15131656 *
    15141657 * @param   pDrvIns             The driver instance.
    1515  * @param   pszDeviceName       The parent device name.
     1658 * @param   pszDevName          The parent device name.
    15161659 * @param   iDevInstance        The parent device instance number.
    15171660 * @param   iLun                The parent LUN number.
    15181661 */
    1519 DECLINLINE(int) pdmR3ResumeDrv(PPDMDRVINS pDrvIns, const char *pszDeviceName, uint32_t iDevInstance, uint32_t iLun)
     1662DECLINLINE(int) pdmR3ResumeDrv(PPDMDRVINS pDrvIns, const char *pszDevName, uint32_t iDevInstance, uint32_t iLun)
    15201663{
    15211664    Assert(pDrvIns->Internal.s.fVMSuspended);
     
    15231666    {
    15241667        LogFlow(("PDMR3Resume: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1525                  pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1668                 pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    15261669        int rc = VINF_SUCCESS; pDrvIns->pReg->pfnResume(pDrvIns);
    15271670        if (RT_FAILURE(rc))
    15281671        {
    15291672            LogRel(("PDMR3Resume: driver '%s'/%d on LUN#%d of device '%s'/%d -> %Rrc\n",
    1530                     pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance, rc));
     1673                    pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance, rc));
    15311674            return rc;
    15321675        }
     
    16471790 *
    16481791 * @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.
    16511795 * @param   iDevInstance        The parent device instance number.
    16521796 * @param   iLun                The parent LUN number.
    16531797 */
    1654 DECLINLINE(bool) pdmR3PowerOffDrv(PPDMDRVINS pDrvIns, unsigned *pcAsync,
    1655                                   const char *pszDeviceName, uint32_t iDevInstance, uint32_t iLun)
     1798DECLINLINE(bool) pdmR3PowerOffDrv(PPDMDRVINS pDrvIns, PPDMNOTIFYASYNCSTATS pAsync,
     1799                                  const char *pszDevName, uint32_t iDevInstance, uint32_t iLun)
    16561800{
    16571801    if (!pDrvIns->Internal.s.fVMSuspended)
     
    16631807            {
    16641808                LogFlow(("PDMR3PowerOff: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1665                          pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1809                         pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    16661810                pDrvIns->pReg->pfnPowerOff(pDrvIns);
    16671811                if (pDrvIns->Internal.s.pfnAsyncNotify)
    16681812                    LogFlow(("PDMR3PowerOff: Async notification started - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1669                              pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1813                             pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    16701814            }
    16711815            else if (pDrvIns->Internal.s.pfnAsyncNotify(pDrvIns))
     
    16731817                pDrvIns->Internal.s.pfnAsyncNotify = false;
    16741818                LogFlow(("PDMR3PowerOff: Async notification completed - driver '%s'/%d on LUN#%d of device '%s'/%d\n",
    1675                          pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance));
     1819                         pDrvIns->pReg->szName, pDrvIns->iInstance, iLun, pszDevName, iDevInstance));
    16761820            }
    16771821            if (pDrvIns->Internal.s.pfnAsyncNotify)
    16781822            {
    16791823                pDrvIns->Internal.s.fVMSuspended = false;
    1680                 (*pcAsync)++;
     1824                pdmR3NotifyAsyncAddDrv(pAsync, pDrvIns->Internal.s.pDrv->pReg->szName, pDrvIns->iInstance,
     1825                                       pszDevName, iDevInstance, iLun);
    16811826                return false;
    16821827            }
     
    16911836 *
    16921837 * @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 */
     1841DECLINLINE(void) pdmR3PowerOffUsb(PPDMUSBINS pUsbIns, PPDMNOTIFYASYNCSTATS pAsync)
    16961842{
    16971843    if (!pUsbIns->Internal.s.fVMSuspended)
     
    17151861            {
    17161862                pUsbIns->Internal.s.fVMSuspended = false;
    1717                 (*pcAsync)++;
     1863                pdmR3NotifyAsyncAdd(pAsync, pUsbIns->Internal.s.pUsbDev->pReg->szName, pUsbIns->iInstance);
    17181864            }
    17191865        }
     
    17261872 *
    17271873 * @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 */
     1877DECLINLINE(void) pdmR3PowerOffDev(PPDMDEVINS pDevIns, PPDMNOTIFYASYNCSTATS pAsync)
    17311878{
    17321879    if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_SUSPENDED))
     
    17501897            {
    17511898                pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_SUSPENDED;
    1752                 (*pcAsync)++;
     1899                pdmR3NotifyAsyncAdd(pAsync, pDevIns->Internal.s.pDevR3->pReg->szName, pDevIns->iInstance);
    17531900            }
    17541901        }
     
    17701917     * The outer loop repeats until there are no more async requests.
    17711918     */
    1772     unsigned cAsync;
    1773     for (unsigned iLoop = 0; ; iLoop++)
    1774     {
     1919    PDMNOTIFYASYNCSTATS Async;
     1920    pdmR3NotifyAsyncInit(&Async, "PDMR3PowerOff");
     1921    for (;;)
     1922    {
     1923        pdmR3NotifyAsyncBeginLoop(&Async);
     1924
    17751925        /*
    17761926         * Iterate thru the device instances and USB device instances,
     
    17821932         * taking any. (DrvVD changes to read-only in this particular case.)
    17831933         */
    1784         cAsync = 0;
    17851934        for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
    17861935        {
    1787             unsigned const cAsyncStart = cAsync;
     1936            unsigned const cAsyncStart = Async.cAsync;
    17881937
    17891938            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)
    17931942                for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)
    17941943                    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))
    17961945                            break;
    17971946
    1798             if (    cAsync == cAsyncStart
     1947            if (    Async.cAsync == cAsyncStart
    17991948                && !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION))
    1800                 pdmR3PowerOffDev(pDevIns, &cAsync);
     1949                pdmR3PowerOffDev(pDevIns, &Async);
    18011950        }
    18021951
     
    18041953        for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext)
    18051954        {
    1806             unsigned const cAsyncStart = cAsync;
     1955            unsigned const cAsyncStart = Async.cAsync;
    18071956
    18081957            for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext)
    18091958                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))
    18111960                        break;
    18121961
    1813             if (cAsync == cAsyncStart)
    1814                 pdmR3PowerOffUsb(pUsbIns, &cAsync);
     1962            if (Async.cAsync == cAsyncStart)
     1963                pdmR3PowerOffUsb(pUsbIns, &Async);
    18151964        }
    18161965#endif
    1817         if (!cAsync)
     1966        if (!Async.cAsync)
    18181967            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);
    18311970    }
    18321971
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