VirtualBox

Changeset 29443 in vbox


Ignore:
Timestamp:
May 13, 2010 10:10:40 AM (15 years ago)
Author:
vboxsync
Message:

DrvDiskIntegrity: Check for double completion of requests

File:
1 edited

Legend:

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

    r29412 r29443  
    6161    DRVDISKAIOTXDIR enmTxDir;
    6262    /** Start offset. */
    63     uint64_t  off;
     63    uint64_t        off;
    6464    /** Transfer size. */
    65     size_t    cbTransfer;
     65    size_t          cbTransfer;
    6666    /** Segment array. */
    67     PCRTSGSEG paSeg;
     67    PCRTSGSEG       paSeg;
    6868    /** Number of array entries. */
    69     unsigned  cSeg;
     69    unsigned        cSeg;
    7070    /** User argument */
    71     void     *pvUser;
     71    void           *pvUser;
    7272    /** Slot in the array. */
    73     unsigned  iSlot;
     73    unsigned        iSlot;
     74    /** Start timestamp */
     75    uint64_t        tsStart;
     76    /** Completion timestamp. */
     77    uint64_t        tsComplete;
    7478} DRVDISKAIOREQ, *PDRVDISKAIOREQ;
    7579
     
    162166    /** Next free slot in the array */
    163167    volatile unsigned       iNextFreeSlot;
     168
     169    /** Flag whether we check for requests completing twice. */
     170    bool                    fCheckDoubleCompletion;
     171    /** Number of requests we go back. */
     172    unsigned                cEntries;
     173    /** Array of completed but still observed requests. */
     174    PDRVDISKAIOREQ          *papIoReq;
     175    /** Current entry in the array. */
     176    unsigned                iEntry;
    164177} DRVDISKINTEGRITY, *PDRVDISKINTEGRITY;
    165178
     
    189202        pIoReq->cSeg       = cSeg;
    190203        pIoReq->pvUser     = pvUser;
     204        pIoReq->iSlot      = 0;
     205        pIoReq->tsStart    = RTTimeSystemMilliTS();
     206        pIoReq->tsComplete = 0;
    191207    }
    192208
    193209    return pIoReq;
     210}
     211
     212/**
     213 * Free a async I/O request.
     214 *
     215 * @returns nothing.
     216 * @param   pThis     Disk driver.
     217 * @param   pIoReq    The I/O request to free.
     218 */
     219static void drvdiskintIoReqFree(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
     220{
     221    if (pThis->fCheckDoubleCompletion)
     222    {
     223        /* Search if the I/O request completed already. */
     224        for (unsigned i = 0; i < pThis->cEntries; i++)
     225        {
     226            if (RT_UNLIKELY(pThis->papIoReq[i] == pIoReq))
     227            {
     228                RTMsgError("Request %#p completed already!\n", pIoReq);
     229                RTMsgError("Start timestamp %llu Completion timestamp %llu (completed after %llu ms)\n",
     230                           pIoReq->tsStart, pIoReq->tsComplete, pIoReq->tsComplete - pIoReq->tsStart);
     231                RTAssertDebugBreak();
     232            }
     233        }
     234
     235        pIoReq->tsComplete = RTTimeSystemMilliTS();
     236        Assert(!pThis->papIoReq[pThis->iEntry]);
     237        pThis->papIoReq[pThis->iEntry] = pIoReq;
     238
     239        pThis->iEntry = (pThis->iEntry+1) % pThis->cEntries;
     240        if (pThis->papIoReq[pThis->iEntry])
     241        {
     242            RTMemFree(pThis->papIoReq[pThis->iEntry]);
     243            pThis->papIoReq[pThis->iEntry] = NULL;
     244        }
     245    }
     246    else
     247        RTMemFree(pIoReq);
    194248}
    195249
     
    414468
    415469    Assert(!pReqActive->pIoReq);
    416     pReqActive->tsStart = RTTimeSystemMilliTS();
     470    pReqActive->tsStart = pIoReq->tsStart;
    417471    pReqActive->pIoReq  = pIoReq;
    418472    pIoReq->iSlot = pThis->iNextFreeSlot;
     
    705759    }
    706760
    707     rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pIoReq->pvUser, rcReq);
    708     RTMemFree(pIoReq);
     761    void *pvUserComplete = pIoReq->pvUser;
     762
     763    drvdiskintIoReqFree(pThis, pIoReq);
     764
     765    rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
    709766
    710767    return rc;
     
    758815        RTSemEventSignal(pThis->SemEvent);
    759816        RTSemEventDestroy(pThis->SemEvent);
     817    }
     818
     819    if (pThis->fCheckDoubleCompletion)
     820    {
     821        /* Free all requests */
     822        while (pThis->papIoReq[pThis->iEntry])
     823        {
     824            RTMemFree(pThis->papIoReq[pThis->iEntry]);
     825            pThis->papIoReq[pThis->iEntry] = NULL;
     826            pThis->iEntry = (pThis->iEntry+1) % pThis->cEntries;
     827        }
    760828    }
    761829}
     
    779847                                    "TraceRequests\0"
    780848                                    "CheckIntervalMs\0"
    781                                     "ExpireIntervalMs\0"))
     849                                    "ExpireIntervalMs\0"
     850                                    "CheckDoubleCompletions\0"
     851                                    "HistorySize\0"))
    782852        return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
    783853
     
    789859    AssertRC(rc);
    790860    rc = CFGMR3QueryU32Def(pCfg, "ExpireIntervalMs", &pThis->uExpireIntervalMs, 20000); /* 20 seconds */
     861    AssertRC(rc);
     862    rc = CFGMR3QueryBoolDef(pCfg, "CheckDoubleCompletions", &pThis->fCheckDoubleCompletion, false);
     863    AssertRC(rc);
     864    rc = CFGMR3QueryU32Def(pCfg, "HistorySize", &pThis->cEntries, 512);
    791865    AssertRC(rc);
    792866
     
    863937                            0, RTTHREADTYPE_INFREQUENT_POLLER, 0, "DiskIntegrity");
    864938        AssertRC(rc);
     939    }
     940
     941    if (pThis->fCheckDoubleCompletion)
     942    {
     943        pThis->iEntry = 0;
     944        pThis->papIoReq = (PDRVDISKAIOREQ *)RTMemAllocZ(pThis->cEntries * sizeof(PDRVDISKAIOREQ));
     945        AssertPtr(pThis->papIoReq);
    865946    }
    866947
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