- Timestamp:
- Nov 14, 2016 4:14:02 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 111916
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r64407 r64664 204 204 /** Size of the allocated I/O buffer. */ 205 205 size_t cbIoBuf; 206 /** I/O buffer descriptor. */ 207 IOBUFDESC IoBuf; 206 /** Pointer to the S/G buffer. */ 207 PRTSGBUF pSgBuf; 208 /** Flag whether the pointer is a direct buffer or 209 * was allocated by us. */ 210 bool fDirectBuf; 211 /** Buffer management data based on the fDirectBuf flag. */ 212 union 213 { 214 /** Direct buffer. */ 215 struct 216 { 217 /** Segment for the data buffer. */ 218 RTSGSEG Seg; 219 /** S/G buffer structure. */ 220 RTSGBUF SgBuf; 221 } Direct; 222 /** I/O buffer descriptor. */ 223 IOBUFDESC IoBuf; 224 }; 208 225 } ReadWrite; 209 226 /** Discard specific data. */ … … 2626 2643 Assert(pIoReq->ReadWrite.cbIoBuf > 0); 2627 2644 2628 /* Make sure the buffer is reset. */ 2629 RTSgBufReset(&pIoReq->ReadWrite.IoBuf.SgBuf); 2630 2631 size_t const offSrc = pIoReq->ReadWrite.cbReq - pIoReq->ReadWrite.cbReqLeft; 2632 Assert((uint32_t)offSrc == offSrc); 2633 if (fToIoBuf) 2634 rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0], (uint32_t)offSrc, 2635 &pIoReq->ReadWrite.IoBuf.SgBuf, 2636 RT_MIN(pIoReq->ReadWrite.cbIoBuf, pIoReq->ReadWrite.cbReqLeft)); 2637 else 2638 rc = pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0], (uint32_t)offSrc, 2639 &pIoReq->ReadWrite.IoBuf.SgBuf, 2640 (uint32_t)RT_MIN(pIoReq->ReadWrite.cbIoBuf, pIoReq->ReadWrite.cbReqLeft)); 2641 2642 RTSgBufReset(&pIoReq->ReadWrite.IoBuf.SgBuf); 2645 if (!pIoReq->ReadWrite.fDirectBuf) 2646 { 2647 /* Make sure the buffer is reset. */ 2648 RTSgBufReset(&pIoReq->ReadWrite.IoBuf.SgBuf); 2649 2650 size_t const offSrc = pIoReq->ReadWrite.cbReq - pIoReq->ReadWrite.cbReqLeft; 2651 Assert((uint32_t)offSrc == offSrc); 2652 if (fToIoBuf) 2653 rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0], (uint32_t)offSrc, 2654 &pIoReq->ReadWrite.IoBuf.SgBuf, 2655 RT_MIN(pIoReq->ReadWrite.cbIoBuf, pIoReq->ReadWrite.cbReqLeft)); 2656 else 2657 rc = pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0], (uint32_t)offSrc, 2658 &pIoReq->ReadWrite.IoBuf.SgBuf, 2659 (uint32_t)RT_MIN(pIoReq->ReadWrite.cbIoBuf, pIoReq->ReadWrite.cbReqLeft)); 2660 2661 RTSgBufReset(&pIoReq->ReadWrite.IoBuf.SgBuf); 2662 } 2643 2663 return rc; 2644 2664 } … … 2900 2920 DECLINLINE(int) drvvdMediaExIoReqBufAlloc(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, size_t cb) 2901 2921 { 2922 int rc = VERR_NOT_SUPPORTED; 2902 2923 LogFlowFunc(("pThis=%#p pIoReq=%#p cb=%zu\n", pThis, pIoReq, cb)); 2903 2924 2904 int rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReq->ReadWrite.IoBuf, cb, &pIoReq->ReadWrite.cbIoBuf); 2905 if (rc == VERR_NO_MEMORY) 2906 { 2907 LogFlowFunc(("Could not allocate memory for request, deferring\n")); 2908 RTCritSectEnter(&pThis->CritSectIoReqsIoBufWait); 2909 RTListAppend(&pThis->LstIoReqIoBufWait, &pIoReq->NdLstWait); 2910 RTCritSectLeave(&pThis->CritSectIoReqsIoBufWait); 2911 ASMAtomicIncU32(&pThis->cIoReqsWaiting); 2912 rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS; 2913 } 2914 else 2915 { 2916 LogFlowFunc(("Allocated %zu bytes of memory\n", pIoReq->ReadWrite.cbIoBuf)); 2917 Assert(pIoReq->ReadWrite.cbIoBuf > 0); 2925 if ( cb == _4K 2926 && pThis->pDrvMediaExPort->pfnIoReqQueryBuf) 2927 { 2928 /* Try to get a direct pointer to the buffer first. */ 2929 void *pvBuf = NULL; 2930 size_t cbBuf = 0; 2931 rc = pThis->pDrvMediaExPort->pfnIoReqQueryBuf(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0], 2932 &pvBuf, &cbBuf); 2933 if (RT_SUCCESS(rc)) 2934 { 2935 pIoReq->ReadWrite.cbIoBuf = cbBuf; 2936 pIoReq->ReadWrite.fDirectBuf = true; 2937 pIoReq->ReadWrite.Direct.Seg.pvSeg = pvBuf; 2938 pIoReq->ReadWrite.Direct.Seg.cbSeg = cbBuf; 2939 RTSgBufInit(&pIoReq->ReadWrite.Direct.SgBuf, &pIoReq->ReadWrite.Direct.Seg, 1); 2940 pIoReq->ReadWrite.pSgBuf = &pIoReq->ReadWrite.Direct.SgBuf; 2941 } 2942 } 2943 2944 if (RT_FAILURE(rc)) 2945 { 2946 rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReq->ReadWrite.IoBuf, cb, &pIoReq->ReadWrite.cbIoBuf); 2947 if (rc == VERR_NO_MEMORY) 2948 { 2949 LogFlowFunc(("Could not allocate memory for request, deferring\n")); 2950 RTCritSectEnter(&pThis->CritSectIoReqsIoBufWait); 2951 RTListAppend(&pThis->LstIoReqIoBufWait, &pIoReq->NdLstWait); 2952 RTCritSectLeave(&pThis->CritSectIoReqsIoBufWait); 2953 ASMAtomicIncU32(&pThis->cIoReqsWaiting); 2954 rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS; 2955 } 2956 else 2957 { 2958 LogFlowFunc(("Allocated %zu bytes of memory\n", pIoReq->ReadWrite.cbIoBuf)); 2959 Assert(pIoReq->ReadWrite.cbIoBuf > 0); 2960 pIoReq->ReadWrite.fDirectBuf = false; 2961 pIoReq->ReadWrite.pSgBuf = &pIoReq->ReadWrite.IoBuf.SgBuf; 2962 } 2918 2963 } 2919 2964 … … 2945 2990 { 2946 2991 rc = PDMR3BlkCacheRead(pThis->pBlkCache, pIoReq->ReadWrite.offStart, 2947 &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq);2992 pIoReq->ReadWrite.pSgBuf, cbReqIo, pIoReq); 2948 2993 if (rc == VINF_SUCCESS) 2949 2994 rc = VINF_VD_ASYNC_IO_FINISHED; … … 2952 2997 } 2953 2998 else 2954 rc = VDAsyncRead(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf,2999 rc = VDAsyncRead(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, pIoReq->ReadWrite.pSgBuf, 2955 3000 drvvdMediaExIoReqComplete, pThis, pIoReq); 2956 3001 } 2957 3002 else 2958 3003 { 2959 void *pvBuf = RTSgBufGetNextSegment( &pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);3004 void *pvBuf = RTSgBufGetNextSegment(pIoReq->ReadWrite.pSgBuf, &cbReqIo); 2960 3005 2961 3006 Assert(cbReqIo > 0 && VALID_PTR(pvBuf)); … … 2994 3039 { 2995 3040 rc = PDMR3BlkCacheWrite(pThis->pBlkCache, pIoReq->ReadWrite.offStart, 2996 &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq);3041 pIoReq->ReadWrite.pSgBuf, cbReqIo, pIoReq); 2997 3042 if (rc == VINF_SUCCESS) 2998 3043 rc = VINF_VD_ASYNC_IO_FINISHED; … … 3001 3046 } 3002 3047 else 3003 rc = VDAsyncWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf,3048 rc = VDAsyncWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, pIoReq->ReadWrite.pSgBuf, 3004 3049 drvvdMediaExIoReqComplete, pThis, pIoReq); 3005 3050 } 3006 3051 else 3007 3052 { 3008 void *pvBuf = RTSgBufGetNextSegment( &pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);3053 void *pvBuf = RTSgBufGetNextSegment(pIoReq->ReadWrite.pSgBuf, &cbReqIo); 3009 3054 3010 3055 Assert(cbReqIo > 0 && VALID_PTR(pvBuf)); … … 3167 3212 LogFlowFunc(("pThis=%#p pIoReq=%#p{.cbIoBuf=%zu}\n", pThis, pIoReq, pIoReq->ReadWrite.cbIoBuf)); 3168 3213 3169 if ( pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ 3170 || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE) 3214 if ( ( pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ 3215 || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE) 3216 && !pIoReq->ReadWrite.fDirectBuf) 3171 3217 { 3172 3218 IOBUFMgrFreeBuf(&pIoReq->ReadWrite.IoBuf); … … 3189 3235 if (rc == VINF_SUCCESS) 3190 3236 { 3191 Assert(pIoReq ->ReadWrite.cbIoBuf > 0);3237 Assert(pIoReqCur->ReadWrite.cbIoBuf > 0); 3192 3238 3193 3239 cIoReqsWaiting--; 3194 3240 RTListNodeRemove(&pIoReqCur->NdLstWait); 3241 3242 pIoReqCur->ReadWrite.fDirectBuf = false; 3243 pIoReqCur->ReadWrite.pSgBuf = &pIoReqCur->ReadWrite.IoBuf.SgBuf; 3195 3244 3196 3245 bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReqCur->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED); … … 3198 3247 { 3199 3248 /* Must have been canceled inbetween. */ 3200 Assert(pIoReq ->enmState == VDIOREQSTATE_CANCELED);3249 Assert(pIoReqCur->enmState == VDIOREQSTATE_CANCELED); 3201 3250 drvvdMediaExIoReqCompleteWorker(pThis, pIoReqCur, VERR_PDM_MEDIAEX_IOREQ_CANCELED, true /* fUpNotify */); 3202 3251 } … … 3831 3880 /* 3832 3881 * Try to allocate enough I/O buffer, if this fails for some reason put it onto the 3833 * waiti gnlist instead of the redo list.3882 * waiting list instead of the redo list. 3834 3883 */ 3835 3884 pIoReq->ReadWrite.cbIoBuf = 0; … … 3843 3892 fPlaceOnRedoList = false; 3844 3893 rc = VINF_SUCCESS; 3894 } 3895 else 3896 { 3897 pIoReq->ReadWrite.fDirectBuf = false; 3898 pIoReq->ReadWrite.pSgBuf = &pIoReq->ReadWrite.IoBuf.SgBuf; 3845 3899 } 3846 3900 }
Note:
See TracChangeset
for help on using the changeset viewer.