VirtualBox

Changeset 64664 in vbox for trunk


Ignore:
Timestamp:
Nov 14, 2016 4:14:02 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
111916
Message:

DrvVD: Try to get a direct pointer to the guest buffer if it fits into the 4KB page and the device supports the pfnIoReqQueryBuf callback

File:
1 edited

Legend:

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

    r64407 r64664  
    204204            /** Size of the allocated I/O buffer. */
    205205            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            };
    208225        } ReadWrite;
    209226        /** Discard specific data. */
     
    26262643    Assert(pIoReq->ReadWrite.cbIoBuf > 0);
    26272644
    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    }
    26432663    return rc;
    26442664}
     
    29002920DECLINLINE(int) drvvdMediaExIoReqBufAlloc(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, size_t cb)
    29012921{
     2922    int rc = VERR_NOT_SUPPORTED;
    29022923    LogFlowFunc(("pThis=%#p pIoReq=%#p cb=%zu\n", pThis, pIoReq, cb));
    29032924
    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        }
    29182963    }
    29192964
     
    29452990        {
    29462991            rc = PDMR3BlkCacheRead(pThis->pBlkCache, pIoReq->ReadWrite.offStart,
    2947                                    &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq);
     2992                                   pIoReq->ReadWrite.pSgBuf, cbReqIo, pIoReq);
    29482993            if (rc == VINF_SUCCESS)
    29492994                rc = VINF_VD_ASYNC_IO_FINISHED;
     
    29522997        }
    29532998        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,
    29553000                             drvvdMediaExIoReqComplete, pThis, pIoReq);
    29563001    }
    29573002    else
    29583003    {
    2959         void *pvBuf = RTSgBufGetNextSegment(&pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);
     3004        void *pvBuf = RTSgBufGetNextSegment(pIoReq->ReadWrite.pSgBuf, &cbReqIo);
    29603005
    29613006        Assert(cbReqIo > 0 && VALID_PTR(pvBuf));
     
    29943039        {
    29953040            rc = PDMR3BlkCacheWrite(pThis->pBlkCache, pIoReq->ReadWrite.offStart,
    2996                                     &pIoReq->ReadWrite.IoBuf.SgBuf, cbReqIo, pIoReq);
     3041                                    pIoReq->ReadWrite.pSgBuf, cbReqIo, pIoReq);
    29973042            if (rc == VINF_SUCCESS)
    29983043                rc = VINF_VD_ASYNC_IO_FINISHED;
     
    30013046        }
    30023047        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,
    30043049                              drvvdMediaExIoReqComplete, pThis, pIoReq);
    30053050    }
    30063051    else
    30073052    {
    3008         void *pvBuf = RTSgBufGetNextSegment(&pIoReq->ReadWrite.IoBuf.SgBuf, &cbReqIo);
     3053        void *pvBuf = RTSgBufGetNextSegment(pIoReq->ReadWrite.pSgBuf, &cbReqIo);
    30093054
    30103055        Assert(cbReqIo > 0 && VALID_PTR(pvBuf));
     
    31673212    LogFlowFunc(("pThis=%#p pIoReq=%#p{.cbIoBuf=%zu}\n", pThis, pIoReq, pIoReq->ReadWrite.cbIoBuf));
    31683213
    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)
    31713217    {
    31723218        IOBUFMgrFreeBuf(&pIoReq->ReadWrite.IoBuf);
     
    31893235                if (rc == VINF_SUCCESS)
    31903236                {
    3191                     Assert(pIoReq->ReadWrite.cbIoBuf > 0);
     3237                    Assert(pIoReqCur->ReadWrite.cbIoBuf > 0);
    31923238
    31933239                    cIoReqsWaiting--;
    31943240                    RTListNodeRemove(&pIoReqCur->NdLstWait);
     3241
     3242                    pIoReqCur->ReadWrite.fDirectBuf = false;
     3243                    pIoReqCur->ReadWrite.pSgBuf     = &pIoReqCur->ReadWrite.IoBuf.SgBuf;
    31953244
    31963245                    bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReqCur->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED);
     
    31983247                    {
    31993248                        /* Must have been canceled inbetween. */
    3200                         Assert(pIoReq->enmState == VDIOREQSTATE_CANCELED);
     3249                        Assert(pIoReqCur->enmState == VDIOREQSTATE_CANCELED);
    32013250                        drvvdMediaExIoReqCompleteWorker(pThis, pIoReqCur, VERR_PDM_MEDIAEX_IOREQ_CANCELED, true /* fUpNotify */);
    32023251                    }
     
    38313880            /*
    38323881             * Try to allocate enough I/O buffer, if this fails for some reason put it onto the
    3833              * waitign list instead of the redo list.
     3882             * waiting list instead of the redo list.
    38343883             */
    38353884            pIoReq->ReadWrite.cbIoBuf = 0;
     
    38433892                fPlaceOnRedoList = false;
    38443893                rc = VINF_SUCCESS;
     3894            }
     3895            else
     3896            {
     3897                pIoReq->ReadWrite.fDirectBuf = false;
     3898                pIoReq->ReadWrite.pSgBuf     = &pIoReq->ReadWrite.IoBuf.SgBuf;
    38453899            }
    38463900        }
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