VirtualBox

Changeset 28719 in vbox for trunk


Ignore:
Timestamp:
Apr 25, 2010 8:48:36 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
60591
Message:

AsyncCompletion: Increase the maximum number of requests the I/O manager can handle if required instead of using a static value

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h

    r28317 r28719  
    126126     */
    127127    PDMACEPFILEMGRSTATE_SHUTDOWN,
     128    /** The I/O manager waits for all active requests to complete and doesn't queue
     129     * new ones because it needs to grow to handle more requests.
     130     */
     131    PDMACEPFILEMGRSTATE_GROWING,
    128132    /** 32bit hack */
    129133    PDMACEPFILEMGRSTATE_32BIT_HACK = 0x7fffffff
     
    163167    /** Pointer to an array of free async I/O request handles. */
    164168    RTFILEAIOREQ                          *pahReqsFree;
    165     /** Next free position for a free request handle. */
    166     unsigned                               iFreeEntryNext;
    167     /** Position of the next free task handle */
    168     unsigned                               iFreeReqNext;
     169    /** Index of the next free entry in the cache. */
     170    uint32_t                               iFreeEntry;
    169171    /** Size of the array. */
    170172    unsigned                               cReqEntries;
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp

    r28317 r28719  
    3434#define PDMACEPFILEMGR_LOAD_UPDATE_PERIOD 1000
    3535/** Maximum number of requests a manager will handle. */
    36 #define PDMACEPFILEMGR_REQS_MAX 512 /* @todo: Find better solution wrt. the request number*/
     36#define PDMACEPFILEMGR_REQS_STEP 512
    3737
    3838/*******************************************************************************
     
    5151    int rc = VINF_SUCCESS;
    5252
    53     pAioMgr->cRequestsActiveMax = PDMACEPFILEMGR_REQS_MAX;
     53    pAioMgr->cRequestsActiveMax = PDMACEPFILEMGR_REQS_STEP;
    5454
    5555    rc = RTFileAioCtxCreate(&pAioMgr->hAioCtx, RTFILEAIO_UNLIMITED_REQS);
    5656    if (rc == VERR_OUT_OF_RANGE)
    57         rc = RTFileAioCtxCreate(&pAioMgr->hAioCtx, PDMACEPFILEMGR_REQS_MAX);
     57        rc = RTFileAioCtxCreate(&pAioMgr->hAioCtx, pAioMgr->cRequestsActiveMax);
    5858
    5959    if (RT_SUCCESS(rc))
    6060    {
    6161        /* Initialize request handle array. */
    62         pAioMgr->iFreeEntryNext = 0;
    63         pAioMgr->iFreeReqNext   = 0;
    64         pAioMgr->cReqEntries    = pAioMgr->cRequestsActiveMax + 1;
     62        pAioMgr->iFreeEntry = 0;
     63        pAioMgr->cReqEntries    = pAioMgr->cRequestsActiveMax;
    6564        pAioMgr->pahReqsFree    = (RTFILEAIOREQ *)RTMemAllocZ(pAioMgr->cReqEntries * sizeof(RTFILEAIOREQ));
    6665
     
    8988    RTFileAioCtxDestroy(pAioMgr->hAioCtx);
    9089
    91     while (pAioMgr->iFreeReqNext != pAioMgr->iFreeEntryNext)
    92     {
    93         RTFileAioReqDestroy(pAioMgr->pahReqsFree[pAioMgr->iFreeReqNext]);
    94         pAioMgr->iFreeReqNext = (pAioMgr->iFreeReqNext + 1) % pAioMgr->cReqEntries;
     90    while (pAioMgr->iFreeEntry > 0)
     91    {
     92        pAioMgr->iFreeEntry--;
     93        Assert(pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] != NIL_RTFILEAIOREQ);
     94        RTFileAioReqDestroy(pAioMgr->pahReqsFree[pAioMgr->iFreeEntry]);
    9595    }
    9696
     
    316316
    317317/**
     318 * Increase the maximum number of active requests for the given I/O manager.
     319 *
     320 * @returns VBox status code.
     321 * @param   pAioMgr    The I/O manager to grow.
     322 */
     323static int pdmacFileAioMgrNormalGrow(PPDMACEPFILEMGR pAioMgr)
     324{
     325    int rc = VINF_SUCCESS;
     326    RTFILEAIOCTX hAioCtxNew = NIL_RTFILEAIOCTX;
     327
     328    LogFlowFunc(("pAioMgr=%#p\n", pAioMgr));
     329
     330    AssertMsg(    pAioMgr->enmState == PDMACEPFILEMGRSTATE_GROWING
     331              && !pAioMgr->cRequestsActive,
     332              ("Invalid state of the I/O manager\n"));
     333
     334    /*
     335     * Reopen the files of all assigned endpoints first so we can assign them to the new
     336     * I/O context.
     337     */
     338    PPDMASYNCCOMPLETIONENDPOINTFILE pCurr = pAioMgr->pEndpointsHead;
     339
     340    while (pCurr)
     341    {
     342        RTFileClose(pCurr->File);
     343        rc = RTFileOpen(&pCurr->File, pCurr->Core.pszUri, pCurr->fFlags);
     344        AssertRC(rc);
     345
     346        pCurr = pCurr->AioMgr.pEndpointNext;
     347    }
     348
     349    /* Create the new bigger context. */
     350    pAioMgr->cRequestsActiveMax += PDMACEPFILEMGR_REQS_STEP;
     351
     352    rc = RTFileAioCtxCreate(&hAioCtxNew, RTFILEAIO_UNLIMITED_REQS);
     353    if (rc == VERR_OUT_OF_RANGE)
     354        rc = RTFileAioCtxCreate(&hAioCtxNew, pAioMgr->cRequestsActiveMax);
     355
     356    if (RT_SUCCESS(rc))
     357    {
     358        /* Close the old context. */
     359        rc = RTFileAioCtxDestroy(pAioMgr->hAioCtx);
     360        AssertRC(rc);
     361
     362        pAioMgr->hAioCtx = hAioCtxNew;
     363
     364        /* Create a new I/O task handle array */
     365        uint32_t cReqEntriesNew = pAioMgr->cRequestsActiveMax + 1;
     366        RTFILEAIOREQ *pahReqNew = (RTFILEAIOREQ *)RTMemAllocZ(cReqEntriesNew * sizeof(RTFILEAIOREQ));
     367
     368        if (pahReqNew)
     369        {
     370            /* Copy the cached request handles. */
     371            for (uint32_t iReq = 0; iReq < pAioMgr->cReqEntries; iReq++)
     372                pahReqNew[iReq] = pAioMgr->pahReqsFree[iReq];
     373
     374            RTMemFree(pAioMgr->pahReqsFree);
     375            pAioMgr->pahReqsFree = pahReqNew;
     376            pAioMgr->cReqEntries = cReqEntriesNew;
     377            LogFlowFunc(("I/O manager increased to handle a maximum of %u requests\n",
     378                         pAioMgr->cRequestsActiveMax));
     379        }
     380        else
     381            rc = VERR_NO_MEMORY;
     382    }
     383
     384    /* Assign the file to the new context. */
     385    pCurr = pAioMgr->pEndpointsHead;
     386
     387    while (pCurr)
     388    {
     389        rc = RTFileAioCtxAssociateWithFile(pAioMgr->hAioCtx, pCurr->File);
     390        AssertRC(rc);
     391
     392        pCurr = pCurr->AioMgr.pEndpointNext;
     393    }
     394
     395    if (RT_FAILURE(rc))
     396    {
     397        LogFlow(("Increasing size of the I/O manager failed with rc=%Rrc\n", rc));
     398        pAioMgr->cRequestsActiveMax -= PDMACEPFILEMGR_REQS_STEP;
     399    }
     400
     401    pAioMgr->enmState = PDMACEPFILEMGRSTATE_RUNNING;
     402    LogFlowFunc(("returns rc=%Rrc\n", rc));
     403
     404    return rc;
     405}
     406
     407/**
    318408 * Error handler which will create the failsafe managers and destroy the failed I/O manager.
    319409 *
     
    383473
    384474/**
     475 * Allocates a async I/O request.
     476 *
     477 * @returns Handle to the request.
     478 * @param   pAioMgr    The I/O manager.
     479 */
     480static RTFILEAIOREQ pdmacFileAioMgrNormalRequestAlloc(PPDMACEPFILEMGR pAioMgr)
     481{
     482    RTFILEAIOREQ hReq = NIL_RTFILEAIOREQ;
     483
     484    /* Get a request handle. */
     485    if (pAioMgr->iFreeEntry > 0)
     486    {
     487        pAioMgr->iFreeEntry--;
     488        hReq = pAioMgr->pahReqsFree[pAioMgr->iFreeEntry];
     489        pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] = NIL_RTFILEAIOREQ;
     490        Assert(hReq != NIL_RTFILEAIOREQ);
     491    }
     492    else
     493    {
     494        int rc = RTFileAioReqCreate(&hReq);
     495        AssertRC(rc);
     496    }
     497
     498    return hReq;
     499}
     500
     501/**
     502 * Frees a async I/O request handle.
     503 *
     504 * @returns nothing.
     505 * @param   pAioMgr    The I/O manager.
     506 * @param   hReq       The I/O request handle to free.
     507 */
     508static void pdmacFileAioMgrNormalRequestFree(PPDMACEPFILEMGR pAioMgr, RTFILEAIOREQ hReq)
     509{
     510    Assert(pAioMgr->iFreeEntry < pAioMgr->cReqEntries);
     511    Assert(pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] == NIL_RTFILEAIOREQ);
     512
     513    pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] = hReq;
     514    pAioMgr->iFreeEntry++;
     515}
     516
     517/**
    385518 * Wrapper around RTFIleAioCtxSubmit() which is also doing error handling.
    386519 */
     
    428561                    PPDMACTASKFILE pTasksWaiting;
    429562
    430                     /* Put the entry on the free array */
    431                     pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = pahReqs[i];
    432                     pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries;
     563                    pdmacFileAioMgrNormalRequestFree(pAioMgr, pahReqs[i]);
    433564
    434565                    if (pTask->cbBounceBuffer)
     
    459590
    460591    return rc;
    461 }
    462 
    463 /**
    464  * Allocates a async I/O request.
    465  *
    466  * @returns Handle to the request.
    467  * @param   pAioMgr    The I/O manager.
    468  */
    469 static RTFILEAIOREQ pdmacFileAioMgrNormalRequestAlloc(PPDMACEPFILEMGR pAioMgr)
    470 {
    471     RTFILEAIOREQ hReq = NIL_RTFILEAIOREQ;
    472 
    473     /* Get a request handle. */
    474     if (pAioMgr->iFreeReqNext != pAioMgr->iFreeEntryNext)
    475     {
    476         hReq = pAioMgr->pahReqsFree[pAioMgr->iFreeReqNext];
    477         pAioMgr->pahReqsFree[pAioMgr->iFreeReqNext] = NIL_RTFILEAIOREQ;
    478         pAioMgr->iFreeReqNext = (pAioMgr->iFreeReqNext + 1) % pAioMgr->cReqEntries;
    479     }
    480     else
    481     {
    482         int rc = RTFileAioReqCreate(&hReq);
    483         AssertRC(rc);
    484     }
    485 
    486     return hReq;
    487592}
    488593
     
    8971002                        && !pAioMgr->fBwLimitReached))
    8981003        {
     1004#if 0
    8991005            /*
    9001006             * The I/O manager has no room left for more requests
     
    9031009             */
    9041010            pdmacFileAioMgrNormalBalanceLoad(pAioMgr);
     1011#else
     1012            /* Grow the I/O manager */
     1013            pAioMgr->enmState = PDMACEPFILEMGRSTATE_GROWING;
     1014#endif
    9051015        }
    9061016    }
     
    11341244    {
    11351245        /* Free bounce buffers and the IPRT request. */
    1136         pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = hReq;
    1137         pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries;
     1246        pdmacFileAioMgrNormalRequestFree(pAioMgr, hReq);
    11381247
    11391248        /* Free the lock and process pending tasks if neccessary */
     
    12291338            }
    12301339
    1231             /* Put the entry on the free array */
    1232             pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = hReq;
    1233             pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries;
     1340            pdmacFileAioMgrNormalRequestFree(pAioMgr, hReq);
    12341341
    12351342            pAioMgr->cRequestsActive--;
     
    13861493
    13871494                /* Check endpoints for new requests. */
    1388                 rc = pdmacFileAioMgrNormalCheckEndpoints(pAioMgr);
    1389                 CHECK_RC(pAioMgr, rc);
     1495                if (pAioMgr->enmState != PDMACEPFILEMGRSTATE_GROWING)
     1496                {
     1497                    rc = pdmacFileAioMgrNormalCheckEndpoints(pAioMgr);
     1498                    CHECK_RC(pAioMgr, rc);
     1499                }
    13901500            } /* while requests are active. */
     1501
     1502            if (pAioMgr->enmState == PDMACEPFILEMGRSTATE_GROWING)
     1503            {
     1504                rc = pdmacFileAioMgrNormalGrow(pAioMgr);
     1505                AssertRC(rc);
     1506                Assert(pAioMgr->enmState == PDMACEPFILEMGRSTATE_RUNNING);
     1507            }
    13911508        } /* if still running */
    13921509    } /* while running */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette