Changeset 29443 in vbox
- Timestamp:
- May 13, 2010 10:10:40 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
r29412 r29443 61 61 DRVDISKAIOTXDIR enmTxDir; 62 62 /** Start offset. */ 63 uint64_t off;63 uint64_t off; 64 64 /** Transfer size. */ 65 size_t cbTransfer;65 size_t cbTransfer; 66 66 /** Segment array. */ 67 PCRTSGSEG paSeg;67 PCRTSGSEG paSeg; 68 68 /** Number of array entries. */ 69 unsigned cSeg;69 unsigned cSeg; 70 70 /** User argument */ 71 void *pvUser;71 void *pvUser; 72 72 /** Slot in the array. */ 73 unsigned iSlot; 73 unsigned iSlot; 74 /** Start timestamp */ 75 uint64_t tsStart; 76 /** Completion timestamp. */ 77 uint64_t tsComplete; 74 78 } DRVDISKAIOREQ, *PDRVDISKAIOREQ; 75 79 … … 162 166 /** Next free slot in the array */ 163 167 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; 164 177 } DRVDISKINTEGRITY, *PDRVDISKINTEGRITY; 165 178 … … 189 202 pIoReq->cSeg = cSeg; 190 203 pIoReq->pvUser = pvUser; 204 pIoReq->iSlot = 0; 205 pIoReq->tsStart = RTTimeSystemMilliTS(); 206 pIoReq->tsComplete = 0; 191 207 } 192 208 193 209 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 */ 219 static 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); 194 248 } 195 249 … … 414 468 415 469 Assert(!pReqActive->pIoReq); 416 pReqActive->tsStart = RTTimeSystemMilliTS();470 pReqActive->tsStart = pIoReq->tsStart; 417 471 pReqActive->pIoReq = pIoReq; 418 472 pIoReq->iSlot = pThis->iNextFreeSlot; … … 705 759 } 706 760 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); 709 766 710 767 return rc; … … 758 815 RTSemEventSignal(pThis->SemEvent); 759 816 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 } 760 828 } 761 829 } … … 779 847 "TraceRequests\0" 780 848 "CheckIntervalMs\0" 781 "ExpireIntervalMs\0")) 849 "ExpireIntervalMs\0" 850 "CheckDoubleCompletions\0" 851 "HistorySize\0")) 782 852 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; 783 853 … … 789 859 AssertRC(rc); 790 860 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); 791 865 AssertRC(rc); 792 866 … … 863 937 0, RTTHREADTYPE_INFREQUENT_POLLER, 0, "DiskIntegrity"); 864 938 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); 865 946 } 866 947
Note:
See TracChangeset
for help on using the changeset viewer.