VirtualBox

Changeset 26147 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 2, 2010 1:55:20 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
57156
Message:

AsyncCompletion: Fix incorrect count of outstanding write tasks. Fixes hangs during flush requests. Return VINF_AIO_TASK_PENDING if data needs to be read from the file

Location:
trunk/src/VBox
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r26001 r26147  
    353353
    354354    Assert(!pStorageBackend->fSyncIoPending);
    355     pStorageBackend->fSyncIoPending = true;
     355    ASMAtomicXchgBool(&pStorageBackend->fSyncIoPending, true);
    356356    DataSeg.cbSeg = cbRead;
    357357    DataSeg.pvSeg = pvBuf;
     
    361361        return rc;
    362362
    363     /* Wait */
    364     rc = RTSemEventWait(pStorageBackend->EventSem, RT_INDEFINITE_WAIT);
    365     AssertRC(rc);
     363    if (rc == VINF_AIO_TASK_PENDING)
     364    {
     365        /* Wait */
     366        rc = RTSemEventWait(pStorageBackend->EventSem, RT_INDEFINITE_WAIT);
     367        AssertRC(rc);
     368    }
     369    else
     370        ASMAtomicXchgBool(&pStorageBackend->fSyncIoPending, false);
    366371
    367372    if (pcbRead)
     
    380385
    381386    Assert(!pStorageBackend->fSyncIoPending);
    382     pStorageBackend->fSyncIoPending = true;
     387    ASMAtomicXchgBool(&pStorageBackend->fSyncIoPending, true);
    383388    DataSeg.cbSeg = cbWrite;
    384389    DataSeg.pvSeg = (void *)pvBuf;
     
    388393        return rc;
    389394
    390     /* Wait */
    391     rc = RTSemEventWait(pStorageBackend->EventSem, RT_INDEFINITE_WAIT);
    392     AssertRC(rc);
     395    if (rc == VINF_AIO_TASK_PENDING)
     396    {
     397        /* Wait */
     398        rc = RTSemEventWait(pStorageBackend->EventSem, RT_INDEFINITE_WAIT);
     399        AssertRC(rc);
     400    }
     401    else
     402        ASMAtomicXchgBool(&pStorageBackend->fSyncIoPending, false);
    393403
    394404    if (pcbWritten)
     
    405415
    406416    Assert(!pStorageBackend->fSyncIoPending);
    407     pStorageBackend->fSyncIoPending = true;
     417    ASMAtomicXchgBool(&pStorageBackend->fSyncIoPending, true);
    408418
    409419    int rc = PDMR3AsyncCompletionEpFlush(pStorageBackend->pEndpoint, NULL, &pTask);
     
    411421        return rc;
    412422
    413     /* Wait */
    414     rc = RTSemEventWait(pStorageBackend->EventSem, RT_INDEFINITE_WAIT);
    415     AssertRC(rc);
     423    if (rc == VINF_AIO_TASK_PENDING)
     424    {
     425        /* Wait */
     426        rc = RTSemEventWait(pStorageBackend->EventSem, RT_INDEFINITE_WAIT);
     427        AssertRC(rc);
     428    }
     429    else
     430        ASMAtomicXchgBool(&pStorageBackend->fSyncIoPending, false);
    416431
    417432    return VINF_SUCCESS;
     
    11041119                break;
    11051120            }
    1106             rc = CFGMR3QueryBoolDef(pCurNode, "UseNewIo", &fUseNewIo, false);
     1121            rc = CFGMR3QueryBoolDef(pCurNode, "UseNewIo", &fUseNewIo, true);
    11071122            if (RT_FAILURE(rc))
    11081123            {
     
    12481263        if (rc == VERR_NOT_SUPPORTED)
    12491264        {
    1250             /* Seems async I/O is not supported by the backend, open in normal mode. */
    12511265            pThis->fAsyncIOSupported = false;
    12521266            uOpenFlags &= ~VD_OPEN_FLAGS_ASYNC_IO;
  • trunk/src/VBox/VMM/PDMAsyncCompletion.cpp

    r26108 r26147  
    545545}
    546546
    547 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask)
    548 {
    549     LogFlow(("%s: pTask=%p\n", __FUNCTION__, pTask));
    550 
    551     PPDMASYNCCOMPLETIONTEMPLATE pTemplate = pTask->pEndpoint->pTemplate;
    552 
    553     switch (pTemplate->enmType)
    554     {
    555         case PDMASYNCCOMPLETIONTEMPLATETYPE_DEV:
    556         {
    557             pTemplate->u.Dev.pfnCompleted(pTemplate->u.Dev.pDevIns, pTask->pvUser);
    558             break;
     547void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, bool fCallCompletionHandler)
     548{
     549    LogFlow(("%s: pTask=%#p fCallCompletionHandler=%RTbool\n", __FUNCTION__, pTask, fCallCompletionHandler));
     550
     551    if (fCallCompletionHandler)
     552    {
     553        PPDMASYNCCOMPLETIONTEMPLATE pTemplate = pTask->pEndpoint->pTemplate;
     554
     555        switch (pTemplate->enmType)
     556        {
     557            case PDMASYNCCOMPLETIONTEMPLATETYPE_DEV:
     558            {
     559                pTemplate->u.Dev.pfnCompleted(pTemplate->u.Dev.pDevIns, pTask->pvUser);
     560                break;
     561            }
     562            case PDMASYNCCOMPLETIONTEMPLATETYPE_DRV:
     563            {
     564                pTemplate->u.Drv.pfnCompleted(pTemplate->u.Drv.pDrvIns, pTemplate->u.Drv.pvTemplateUser, pTask->pvUser);
     565                break;
     566            }
     567            case PDMASYNCCOMPLETIONTEMPLATETYPE_USB:
     568            {
     569                pTemplate->u.Usb.pfnCompleted(pTemplate->u.Usb.pUsbIns, pTask->pvUser);
     570                break;
     571            }
     572            case PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL:
     573            {
     574                pTemplate->u.Int.pfnCompleted(pTemplate->pVM, pTask->pvUser, pTemplate->u.Int.pvUser);
     575                break;
     576            }
     577            default:
     578                AssertMsgFailed(("Unknown template type!\n"));
    559579        }
    560         case PDMASYNCCOMPLETIONTEMPLATETYPE_DRV:
    561         {
    562             pTemplate->u.Drv.pfnCompleted(pTemplate->u.Drv.pDrvIns, pTemplate->u.Drv.pvTemplateUser, pTask->pvUser);
    563             break;
    564         }
    565         case PDMASYNCCOMPLETIONTEMPLATETYPE_USB:
    566         {
    567             pTemplate->u.Usb.pfnCompleted(pTemplate->u.Usb.pUsbIns, pTask->pvUser);
    568             break;
    569         }
    570         case PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL:
    571         {
    572             pTemplate->u.Int.pfnCompleted(pTemplate->pVM, pTask->pvUser, pTemplate->u.Int.pvUser);
    573             break;
    574         }
    575         default:
    576             AssertMsgFailed(("Unknown template type!\n"));
    577580    }
    578581
  • trunk/src/VBox/VMM/PDMAsyncCompletionFile.cpp

    r25757 r26147  
    2626#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
    2727#define RT_STRICT
     28//#define DEBUG
    2829#include "PDMInternal.h"
    2930#include <VBox/pdm.h>
     
    321322    if (pTask->enmTransferType == PDMACTASKFILETRANSFER_FLUSH)
    322323    {
    323         pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core);
     324        pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, true);
    324325    }
    325326    else
     
    329330        if (!(uOld - pTask->DataSeg.cbSeg)
    330331            && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true))
    331             pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core);
     332            pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, true);
    332333    }
    333334}
     
    372373    if (ASMAtomicReadS32(&pTaskFile->cbTransferLeft) == 0
    373374        && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true))
    374         pdmR3AsyncCompletionCompleteTask(pTask);
    375 
    376     return VINF_SUCCESS;
     375        pdmR3AsyncCompletionCompleteTask(pTask, false);
     376    else
     377        rc = VINF_AIO_TASK_PENDING;
     378
     379    return rc;
    377380}
    378381
     
    683686
    684687        rc = RTFileGetSize(pEpFile->File, (uint64_t *)&pEpFile->cbFile);
     688        if (RT_SUCCESS(rc) && (pEpFile->cbFile == 0))
     689        {
     690            /* Could be a block device */
     691            rc = RTFileSeek(pEpFile->File, 0, RTFILE_SEEK_END, (uint64_t *)&pEpFile->cbFile);
     692        }
     693
    685694        if (RT_SUCCESS(rc))
    686695        {
     
    871880        pIoTask->pfnCompleted    = pdmacFileEpTaskCompleted;
    872881        pdmacFileEpAddTask(pEpFile, pIoTask);
     882        rc = VINF_AIO_TASK_PENDING;
    873883    }
    874884
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp

    r25647 r26147  
    4545*******************************************************************************/
    4646#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
    47 #define RT_STRICT
    4847#include <iprt/types.h>
    4948#include <iprt/mem.h>
     
    558557    pIoTask->pvUser          = pEntry;
    559558    pIoTask->pfnCompleted    = pdmacFileCacheTaskCompleted;
     559    ASMAtomicIncU32(&pEntry->pEndpoint->DataCache.cWritesOutstanding);
    560560
    561561    /* Send it off to the I/O manager. */
     
    579579    if (!(uOld - pTaskSeg->cbTransfer)
    580580        && !ASMAtomicXchgBool(&pTaskSeg->pTask->fCompleted, true))
    581     {
    582         pdmR3AsyncCompletionCompleteTask(&pTaskSeg->pTask->Core);
    583 
    584         if (pTaskSeg->fWrite)
    585         {
    586             /* Complete a pending flush if all writes have completed */
    587             uint32_t cWritesOutstanding = ASMAtomicDecU32(&pEndpointCache->cWritesOutstanding);
    588             PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL);
    589 
    590             if (!cWritesOutstanding && pTaskFlush)
    591                 pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core);
    592         }
    593     }
     581        pdmR3AsyncCompletionCompleteTask(&pTaskSeg->pTask->Core, true);
    594582
    595583    RTMemFree(pTaskSeg);
     
    629617    if (pTask->enmTransferType == PDMACTASKFILETRANSFER_WRITE)
    630618    {
     619        AssertMsg(pEndpointCache->cWritesOutstanding > 0, ("Completed write request but outstanding task count is 0\n"));
     620        ASMAtomicDecU32(&pEndpointCache->cWritesOutstanding);
     621
    631622        if (pEntry->fFlags & PDMACFILECACHE_ENTRY_IS_DEPRECATED)
    632623        {
     
    674665    if (pEntry->fFlags & PDMACFILECACHE_ENTRY_IS_DIRTY)
    675666        pdmacFileCacheWriteToEndpoint(pEntry);
     667
     668    /* Complete a pending flush if all writes have completed */
     669    if (!ASMAtomicReadU32(&pEndpointCache->cWritesOutstanding))
     670    {
     671        PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL);
     672        if (pTaskFlush)
     673            pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core, true);
     674    }
    676675
    677676    RTSemRWReleaseWrite(pEndpoint->DataCache.SemRWEntries);
     
    14971496    if (ASMAtomicReadS32(&pTask->cbTransferLeft) == 0
    14981497        && !ASMAtomicXchgBool(&pTask->fCompleted, true))
    1499         pdmR3AsyncCompletionCompleteTask(&pTask->Core);
     1498        pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);
     1499    else
     1500        rc = VINF_AIO_TASK_PENDING;
     1501
     1502    LogFlowFunc((": Leave rc=%Rrc\n", rc));
    15001503
    15011504   return rc;
     
    15281531    /* Set to completed to make sure that the task is valid while we access it. */
    15291532    ASMAtomicWriteBool(&pTask->fCompleted, true);
    1530     ASMAtomicIncU32(&pEndpointCache->cWritesOutstanding);
    15311533
    15321534    int iSegCurr       = 0;
     
    19311933        && !ASMAtomicXchgBool(&pTask->fCompleted, true))
    19321934    {
    1933         pdmR3AsyncCompletionCompleteTask(&pTask->Core);
     1935        pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);
    19341936
    19351937        /* Complete a pending flush if all writes have completed */
    1936         uint32_t cWritesOutstanding = ASMAtomicDecU32(&pEndpointCache->cWritesOutstanding);
    1937         PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL);
    1938 
    1939         if (!cWritesOutstanding && pTaskFlush)
    1940             pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core);
    1941     }
    1942 
    1943     return VINF_SUCCESS;
     1938        if (!ASMAtomicReadU32(&pEndpointCache->cWritesOutstanding))
     1939        {
     1940            PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL);
     1941            if (pTaskFlush)
     1942                pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core, true);
     1943        }
     1944    }
     1945    else
     1946        rc = VINF_AIO_TASK_PENDING;
     1947
     1948    LogFlowFunc((": Leave rc=%Rrc\n", rc));
     1949
     1950    return rc;
    19441951}
    19451952
     
    19491956{
    19501957    int rc = VINF_SUCCESS;
     1958
     1959    LogFlowFunc((": pEndpoint=%#p{%s} pTask=%#p\n",
     1960                 pEndpoint, pEndpoint->Core.pszUri, pTask));
    19511961
    19521962    if (ASMAtomicReadPtr((void * volatile *)&pEndpoint->DataCache.pTaskFlush))
     
    19551965    {
    19561966        if (ASMAtomicReadU32(&pEndpoint->DataCache.cWritesOutstanding) > 0)
     1967        {
    19571968            ASMAtomicWritePtr((void * volatile *)&pEndpoint->DataCache.pTaskFlush, pTask);
     1969            rc = VINF_AIO_TASK_PENDING;
     1970        }
    19581971        else
    1959             pdmR3AsyncCompletionCompleteTask(&pTask->Core);
    1960     }
    1961 
     1972            pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);
     1973    }
     1974
     1975    LogFlowFunc((": Leave rc=%Rrc\n", rc));
    19621976    return rc;
    19631977}
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileFailsafe.cpp

    r25270 r26147  
    2121 */
    2222#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
    23 #define RT_STRICT
    2423#include <iprt/types.h>
    2524#include <iprt/assert.h>
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp

    r24530 r26147  
    2121 */
    2222#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
    23 #define RT_STRICT
    2423#include <iprt/types.h>
    2524#include <iprt/asm.h>
  • trunk/src/VBox/VMM/PDMAsyncCompletionInternal.h

    r26108 r26147  
    269269 *
    270270 * @returns nothing
    271  * @param   pTask    Pointer to the finished task.
    272  */
    273 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask);
     271 * @param   pTask                     Pointer to the finished task.
     272 * @param   fCallCompletionHandler    Flag whether the completion handler should be called to
     273 *                                    inform the owner of the task that it has completed.
     274 */
     275void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, bool fCallCompletionHandler);
    274276
    275277RT_C_DECLS_END
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