VirtualBox

Changeset 32427 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Sep 11, 2010 2:42:42 PM (14 years ago)
Author:
vboxsync
Message:

AsyncCompletion: Make submitting requests to the host error prove. Fail the responsible request in case of an error (VERR_DISK_FULL) instead of aborting I/O processing

File:
1 edited

Legend:

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

    r30111 r32427  
    4343                                                         PPDMACFILERANGELOCK pRangeLock);
    4444
     45static void pdmacFileAioMgrNormalReqCompleteRc(PPDMACEPFILEMGR pAioMgr, RTFILEAIOREQ hReq,
     46                                               int rc, size_t cbTransfered);
     47
    4548int pdmacFileAioMgrNormalInit(PPDMACEPFILEMGR pAioMgr)
    4649{
     
    553556    if (RT_FAILURE(rc))
    554557    {
    555         PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->Core.pEpClass;
    556         unsigned cReqsResubmit = 0;
    557         RTFILEAIOREQ ahReqsResubmit[20];
    558 
    559         /*
    560          * We run out of resources.
    561          * Need to check which requests got queued
    562          * and put the rest on the pending list again.
    563          */
    564         for (size_t i = 0; i < cReqs; i++)
    565         {
    566             int rcReq = RTFileAioReqGetRC(pahReqs[i], NULL);
    567 
    568             if (rcReq != VERR_FILE_AIO_IN_PROGRESS)
    569             {
    570                 PPDMACTASKFILE pTask = (PPDMACTASKFILE)RTFileAioReqGetUser(pahReqs[i]);
    571 
    572                 if (pTask->enmTransferType == PDMACTASKFILETRANSFER_FLUSH)
    573                 {
    574                     /* Mark as not supported. */
    575                     if (rcReq != VERR_FILE_AIO_NOT_SUBMITTED)
     558        if (rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES)
     559        {
     560            PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->Core.pEpClass;
     561
     562            /* Append any not submitted task to the waiting list. */
     563            for (size_t i = 0; i < cReqs; i++)
     564            {
     565                int rcReq = RTFileAioReqGetRC(pahReqs[i], NULL);
     566
     567                if (rcReq != VERR_FILE_AIO_IN_PROGRESS)
     568                {
     569                    PPDMACTASKFILE pTask = (PPDMACTASKFILE)RTFileAioReqGetUser(pahReqs[i]);
     570
     571                    Assert(pTask->hReq == pahReqs[i]);
     572                    pdmacFileAioMgrEpAddTask(pEndpoint, pTask);
     573                    pAioMgr->cRequestsActive--;
     574                    pEndpoint->AioMgr.cRequestsActive--;
     575
     576                    if (pTask->enmTransferType == PDMACTASKFILETRANSFER_FLUSH)
    576577                    {
    577                         LogFlow(("Async flushes are not supported for this endpoint, disabling\n"));
    578                         pEndpoint->fAsyncFlushSupported = false;
    579                         pdmacFileAioMgrNormalRequestFree(pAioMgr, pahReqs[i]);
    580                         rc = VINF_SUCCESS;
    581                     }
    582                     else
    583                     {
    584                         AssertMsg(rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES, ("Flush wasn't submitted but we are not out of ressources\n"));
    585578                        /* Clear the pending flush */
    586                         pdmacFileAioMgrEpAddTask(pEndpoint, pTask);
    587579                        Assert(pEndpoint->pFlushReq == pTask);
    588580                        pEndpoint->pFlushReq = NULL;
    589581                    }
    590582                }
    591                 else
    592                 {
    593                     AssertMsg(rcReq == VERR_FILE_AIO_NOT_SUBMITTED,
    594                               ("Request returned unexpected return code: rc=%Rrc\n", rcReq));
    595 
    596                     if (rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES)
    597                     {
    598                         pTask->hReq = pahReqs[i];
    599                         pdmacFileAioMgrEpAddTask(pEndpoint, pTask);
    600                     }
    601                     else
    602                     {
    603                         ahReqsResubmit[cReqsResubmit] = pahReqs[i];
    604                         cReqsResubmit++;
    605                     }
    606                 }
    607 
    608                 pEndpoint->AioMgr.cRequestsActive--;
    609                 pAioMgr->cRequestsActive--;
    610 
    611                 if (cReqsResubmit == RT_ELEMENTS(ahReqsResubmit))
    612                 {
    613                     int rc2 = RTFileAioCtxSubmit(pAioMgr->hAioCtx, ahReqsResubmit, cReqsResubmit);
    614                     AssertRC(rc2);
    615                     pEndpoint->AioMgr.cRequestsActive += cReqsResubmit;
    616                     pAioMgr->cRequestsActive += cReqsResubmit;
    617                     cReqsResubmit = 0;
    618                 }
    619             }
    620 
    621             /* Resubmit tasks. */
    622             if (cReqsResubmit)
    623             {
    624                 int rc2 = RTFileAioCtxSubmit(pAioMgr->hAioCtx, ahReqsResubmit, cReqsResubmit);
    625                 AssertRC(rc2);
    626                 pEndpoint->AioMgr.cRequestsActive += cReqsResubmit;
    627                 pAioMgr->cRequestsActive += cReqsResubmit;
    628                 cReqsResubmit = 0;
    629             }
    630             else if (    pEndpoint->pFlushReq
    631                      && !pAioMgr->cRequestsActive
    632                      && !pEndpoint->fAsyncFlushSupported)
     583            }
     584
     585            pAioMgr->cRequestsActiveMax = pAioMgr->cRequestsActive;
     586
     587            /* Print an entry in the release log */
     588            if (RT_UNLIKELY(!pEpClass->fOutOfResourcesWarningPrinted))
     589            {
     590                pEpClass->fOutOfResourcesWarningPrinted = true;
     591                LogRel(("AIOMgr: Host limits number of active IO requests to %u. Expect a performance impact.\n",
     592                        pAioMgr->cRequestsActive));
     593            }
     594
     595            LogFlow(("Removed requests. I/O manager has a total of %u active requests now\n", pAioMgr->cRequestsActive));
     596            LogFlow(("Endpoint has a total of %u active requests now\n", pEndpoint->AioMgr.cRequestsActive));
     597            rc = VINF_SUCCESS;
     598        }
     599        else /* Another kind of error happened (full disk, ...) */
     600        {
     601            /* An error happened. Find out which one caused the error and resubmit all other tasks. */
     602            for (size_t i = 0; i < cReqs; i++)
     603            {
     604                int rcReq = RTFileAioReqGetRC(pahReqs[i], NULL);
     605
     606                if (rcReq == VERR_FILE_AIO_NOT_SUBMITTED)
     607                {
     608                    /* We call ourself again to do any error handling which might come up now. */
     609                    rc = pdmacFileAioMgrNormalReqsEnqueue(pAioMgr, pEndpoint, &pahReqs[i], 1);
     610                    AssertRC(rc);
     611                }
     612                else if (rcReq != VERR_FILE_AIO_IN_PROGRESS)
     613                {
     614                    PPDMACTASKFILE pTask = (PPDMACTASKFILE)RTFileAioReqGetUser(pahReqs[i]);
     615
     616                    pdmacFileAioMgrNormalReqCompleteRc(pAioMgr, pahReqs[i], rcReq, 0);
     617                }
     618            }
     619
     620
     621            if (    pEndpoint->pFlushReq
     622                && !pAioMgr->cRequestsActive
     623                && !pEndpoint->fAsyncFlushSupported)
    633624            {
    634625                /*
     
    644635            }
    645636        }
    646 
    647         if (rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES)
    648         {
    649             pAioMgr->cRequestsActiveMax = pAioMgr->cRequestsActive;
    650 
    651             /* Print an entry in the release log */
    652             if (RT_UNLIKELY(!pEpClass->fOutOfResourcesWarningPrinted))
    653             {
    654                 pEpClass->fOutOfResourcesWarningPrinted = true;
    655                 LogRel(("AIOMgr: Host limits number of active IO requests to %u. Expect a performance impact.\n",
    656                         pAioMgr->cRequestsActive));
    657             }
    658         }
    659 
    660         LogFlow(("Removed requests. I/O manager has a total of %u active requests now\n", pAioMgr->cRequestsActive));
    661         LogFlow(("Endpoint has a total of %u active requests now\n", pEndpoint->AioMgr.cRequestsActive));
    662     }
    663 
    664     return rc;
     637    }
     638
     639    return VINF_SUCCESS;
    665640}
    666641
     
    13331308}
    13341309
     1310/**
     1311 * Wrapper around pdmacFileAioMgrNormalReqCompleteRc().
     1312 */
    13351313static void pdmacFileAioMgrNormalReqComplete(PPDMACEPFILEMGR pAioMgr, RTFILEAIOREQ hReq)
     1314{
     1315    size_t cbTransfered = 0;
     1316    int rcReq = RTFileAioReqGetRC(hReq, &cbTransfered);
     1317
     1318    pdmacFileAioMgrNormalReqCompleteRc(pAioMgr, hReq, rcReq, cbTransfered);
     1319}
     1320
     1321static void pdmacFileAioMgrNormalReqCompleteRc(PPDMACEPFILEMGR pAioMgr, RTFILEAIOREQ hReq,
     1322                                               int rcReq, size_t cbTransfered)
    13361323{
    13371324    int rc = VINF_SUCCESS;
    13381325    PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
    1339     size_t cbTransfered  = 0;
    1340     int rcReq            = RTFileAioReqGetRC(hReq, &cbTransfered);
    13411326    PPDMACTASKFILE pTask = (PPDMACTASKFILE)RTFileAioReqGetUser(hReq);
    13421327    PPDMACTASKFILE pTasksWaiting;
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