VirtualBox

Changeset 22851 in vbox


Ignore:
Timestamp:
Sep 8, 2009 11:38:47 PM (15 years ago)
Author:
vboxsync
Message:

Fixes for async I/O manager

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

Legend:

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

    r22757 r22851  
    723723    PPDMACFILECACHEENTRY  pEntry = (PPDMACFILECACHEENTRY)pNode;
    724724    PPDMACFILECACHEGLOBAL pCache = (PPDMACFILECACHEGLOBAL)pvUser;
     725    PPDMACFILEENDPOINTCACHE pEndpointCache = &pEntry->pEndpoint->DataCache;
     726
     727    while (pEntry->fFlags & (PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY))
     728    {
     729        RTSemRWReleaseWrite(pEndpointCache->SemRWEntries);
     730        RTThreadSleep(250);
     731        RTSemRWRequestWrite(pEndpointCache->SemRWEntries, RT_INDEFINITE_WAIT);
     732    }
    725733
    726734    AssertMsg(!(pEntry->fFlags & (PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY)),
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h

    r22757 r22851  
    497497    /** Pointer to the used bounce buffer if any. */
    498498    void                                *pvBounceBuffer;
     499    /** Start offset in the bounce buffer to copy from. */
     500    uint32_t                             uBounceBufOffset;
     501    /** Flag whether this is a prefetch request. */
     502    bool                                 fPrefetch;
    499503    /** Completion function to call on completion. */
    500504    PFNPDMACTASKCOMPLETED                pfnCompleted;
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp

    r22757 r22851  
    368368                AssertMsg(hReq != NIL_RTFILEAIOREQ, ("Out of request handles\n"));
    369369
    370                 /* Check if the alignment requirements are met. */
    371                 if ((pEpClassFile->uBitmaskAlignment & (RTR3UINTPTR)pvBuf) != (RTR3UINTPTR)pvBuf)
     370                /* Check if the alignment requirements are met.
     371                 * Offset, transfer size and buffer address
     372                 * need to be on a 512 boundary. */
     373                size_t cbToTransfer = RT_ALIGN_Z(pCurr->DataSeg.cbSeg, 512);
     374                RTFOFF OffStart = pCurr->Off & ~(RTFOFF)(512-1);
     375                PDMACTASKFILETRANSFER enmTransferType = pCurr->enmTransferType;
     376
     377                AssertMsg((  (pCurr->enmTransferType == PDMACTASKFILETRANSFER_WRITE)
     378                           || (OffStart + cbToTransfer <= pEndpoint->cbFile)),
     379                          ("Read exceeds file size OffStart=%RTfoff cbToTransfer=%d cbFile=%llu\n",
     380                          OffStart, cbToTransfer, pEndpoint->cbFile));
     381
     382                pCurr->fPrefetch = false;
     383
     384                if (   RT_UNLIKELY(cbToTransfer != pCurr->DataSeg.cbSeg)
     385                    || RT_UNLIKELY(OffStart != pCurr->Off)
     386                    || ((pEpClassFile->uBitmaskAlignment & (RTR3UINTPTR)pvBuf) != (RTR3UINTPTR)pvBuf))
    372387                {
    373388                    /* Create bounce buffer. */
    374389                    pCurr->fBounceBuffer = true;
     390
     391                    AssertMsg(pCurr->Off >= OffStart, ("Overflow in calculation Off=%llu OffStart=%llu\n",
     392                              pCurr->Off, OffStart));
     393                    pCurr->uBounceBufOffset = pCurr->Off - OffStart;
    375394
    376395                    /** @todo: I think we need something like a RTMemAllocAligned method here.
     
    379398                     * so we can use RTMemPageAlloc here.
    380399                     */
    381                     pCurr->pvBounceBuffer = RTMemPageAlloc(pCurr->DataSeg.cbSeg);
     400                    pCurr->pvBounceBuffer = RTMemPageAlloc(cbToTransfer);
    382401                    AssertPtr(pCurr->pvBounceBuffer);
    383402                    pvBuf = pCurr->pvBounceBuffer;
    384403
    385404                    if (pCurr->enmTransferType == PDMACTASKFILETRANSFER_WRITE)
    386                         memcpy(pvBuf, pCurr->DataSeg.pvSeg, pCurr->DataSeg.cbSeg);
     405                    {
     406                        if (   RT_UNLIKELY(cbToTransfer != pCurr->DataSeg.cbSeg)
     407                            || RT_UNLIKELY(OffStart != pCurr->Off))
     408                        {
     409                            /* We have to fill the buffer first before we can update the data. */
     410                            pCurr->fPrefetch = true;
     411                            enmTransferType = PDMACTASKFILETRANSFER_READ;
     412                        }
     413                        else
     414                            memcpy(pvBuf, pCurr->DataSeg.pvSeg, pCurr->DataSeg.cbSeg);
     415                    }
    387416                }
    388417                else
     
    392421                            ("AIO: Alignment restrictions not met!\n"));
    393422
    394                 if (pCurr->enmTransferType == PDMACTASKFILETRANSFER_WRITE)
     423                if (enmTransferType == PDMACTASKFILETRANSFER_WRITE)
    395424                {
    396425                    /* Grow the file if needed. */
     
    402431
    403432                    rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->File,
    404                                                   pCurr->Off, pvBuf, pCurr->DataSeg.cbSeg, pCurr);
     433                                                  OffStart, pvBuf, cbToTransfer, pCurr);
    405434                }
    406435                else
    407436                    rc = RTFileAioReqPrepareRead(hReq, pEndpoint->File,
    408                                                  pCurr->Off, pvBuf, pCurr->DataSeg.cbSeg, pCurr);
     437                                                 OffStart, pvBuf, cbToTransfer, pCurr);
    409438                AssertRC(rc);
    410439
     
    687716
    688717                    AssertMsg(   RT_SUCCESS(rcReq)
    689                               && (cbTransfered == pTask->DataSeg.cbSeg),
     718                              && (   (cbTransfered == pTask->DataSeg.cbSeg)
     719                                  || (pTask->fBounceBuffer)),
    690720                              ("Task didn't completed successfully (rc=%Rrc) or was incomplete (cbTransfered=%u)\n", rc, cbTransfered));
    691721
    692                     if (pTask->fBounceBuffer)
    693                     {
    694                         if (pTask->enmTransferType == PDMACTASKFILETRANSFER_READ)
    695                             memcpy(pTask->DataSeg.pvSeg, pTask->pvBounceBuffer, pTask->DataSeg.cbSeg);
    696 
    697                         RTMemPageFree(pTask->pvBounceBuffer);
    698                     }
    699 
    700                     /* Put the entry on the free array */
    701                     pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = apReqs[i];
    702                     pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) %pAioMgr->cReqEntries;
    703 
    704                     pAioMgr->cRequestsActive--;
    705                     pEndpoint->AioMgr.cReqsProcessed++;
    706 
    707                     /* Call completion callback */
    708                     pTask->pfnCompleted(pTask, pTask->pvUser);
    709                     pdmacFileTaskFree(pEndpoint, pTask);
    710 
    711                     /*
    712                      * If there is no request left on the endpoint but a flush request is set
    713                      * it completed now and we notify the owner.
    714                      * Furthermore we look for new requests and continue.
    715                      */
    716                     if (!pEndpoint->AioMgr.cRequestsActive && pEndpoint->pFlushReq)
    717                     {
     722                    if (pTask->fPrefetch)
     723                    {
     724                        Assert(pTask->enmTransferType == PDMACTASKFILETRANSFER_WRITE);
     725                        Assert(pTask->fBounceBuffer);
     726
     727                        memcpy(((uint8_t *)pTask->pvBounceBuffer) + pTask->uBounceBufOffset,
     728                                pTask->DataSeg.pvSeg,
     729                                pTask->DataSeg.cbSeg);
     730
     731                        /* Write it now. */
     732                        pTask->fPrefetch = false;
     733                        size_t cbToTransfer = RT_ALIGN_Z(pTask->DataSeg.cbSeg, 512);
     734                        RTFOFF OffStart = pTask->Off & ~(RTFOFF)(512-1);
     735
     736                        /* Grow the file if needed. */
     737                        if (RT_UNLIKELY((pTask->Off + pTask->DataSeg.cbSeg) > pEndpoint->cbFile))
     738                        {
     739                            ASMAtomicWriteU64(&pEndpoint->cbFile, pTask->Off + pTask->DataSeg.cbSeg);
     740                            RTFileSetSize(pEndpoint->File, pTask->Off + pTask->DataSeg.cbSeg);
     741                        }
     742
     743                        rc = RTFileAioReqPrepareWrite(apReqs[i], pEndpoint->File,
     744                                                      OffStart, pTask->pvBounceBuffer, cbToTransfer, pTask);
     745                        AssertRC(rc);
     746                        rc = RTFileAioCtxSubmit(pAioMgr->hAioCtx, &apReqs[i], 1);
     747                        AssertRC(rc);
     748                    }
     749                    else
     750                    {
     751                        if (pTask->fBounceBuffer)
     752                        {
     753                            if (pTask->enmTransferType == PDMACTASKFILETRANSFER_READ)
     754                                memcpy(pTask->DataSeg.pvSeg,
     755                                       ((uint8_t *)pTask->pvBounceBuffer) + pTask->uBounceBufOffset,
     756                                       pTask->DataSeg.cbSeg);
     757
     758                            RTMemPageFree(pTask->pvBounceBuffer);
     759                        }
     760
     761                        /* Put the entry on the free array */
     762                        pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = apReqs[i];
     763                        pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) %pAioMgr->cReqEntries;
     764
     765                        pAioMgr->cRequestsActive--;
     766                        pEndpoint->AioMgr.cReqsProcessed++;
     767
    718768                        /* Call completion callback */
    719                         pTask = pEndpoint->pFlushReq;
    720                         pEndpoint->pFlushReq = NULL;
    721 
    722                         AssertMsg(pTask->pEndpoint == pEndpoint, ("Endpoint of the flush request does not match assigned one\n"));
    723 
    724769                        pTask->pfnCompleted(pTask, pTask->pvUser);
    725770                        pdmacFileTaskFree(pEndpoint, pTask);
     771
     772                        /*
     773                         * If there is no request left on the endpoint but a flush request is set
     774                         * it completed now and we notify the owner.
     775                         * Furthermore we look for new requests and continue.
     776                         */
     777                        if (!pEndpoint->AioMgr.cRequestsActive && pEndpoint->pFlushReq)
     778                        {
     779                            /* Call completion callback */
     780                            pTask = pEndpoint->pFlushReq;
     781                            pEndpoint->pFlushReq = NULL;
     782
     783                            AssertMsg(pTask->pEndpoint == pEndpoint, ("Endpoint of the flush request does not match assigned one\n"));
     784
     785                            pTask->pfnCompleted(pTask, pTask->pvUser);
     786                            pdmacFileTaskFree(pEndpoint, pTask);
     787                        }
    726788                    }
    727789
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