VirtualBox

Changeset 30309 in vbox for trunk/src


Ignore:
Timestamp:
Jun 18, 2010 12:25:12 PM (15 years ago)
Author:
vboxsync
Message:

Storage/iSCSI: switch to sending in a single call, avoiding separate sending of iSCSI PDU header separately on some IP stacks. Adjustments to VBoxHDD, DrvVD and MediumImpl to pass the required VD interface methods.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r30045 r30309  
    150150 VBoxDD_DEFS           += VBOX_WITH_AHCI
    151151endif
    152 ifdef VBOX_WITH_ISCSI
    153  VBoxDD_DEFS           += VBOX_WITH_ISCSI
    154  ifdef VBOX_WITH_INIP
    155   VBoxDD_DEFS          += VBOX_WITH_INIP
    156  endif
     152ifdef VBOX_WITH_INIP
     153 VBoxDD_DEFS           += VBOX_WITH_INIP
    157154endif
    158155ifdef VBOX_WITH_E1000
     
    819816Drivers_DEFS           += VBOX_WITH_NETFLT
    820817endif
     818ifdef VBOX_WITH_INIP
     819Drivers_DEFS           += VBOX_WITH_INIP
     820endif
    821821ifdef VBOX_WITH_DRV_DISK_INTEGRITY
    822822Drivers_DEFS           += VBOX_WITH_DRV_DISK_INTEGRITY
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r30221 r30309  
    586586*******************************************************************************/
    587587
     588typedef union INIPSOCKADDRUNION
     589{
     590    struct sockaddr     Addr;
     591    struct sockaddr_in  Ipv4;
     592} INIPSOCKADDRUNION;
     593
     594static DECLCALLBACK(int) drvvdINIPFlush(RTSOCKET Sock);
     595
    588596/** @copydoc VDINTERFACETCPNET::pfnClientConnect */
    589597static DECLCALLBACK(int) drvvdINIPClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock)
     
    605613    }
    606614    /* Create socket and connect. */
    607     RTSOCKET Sock = lwip_socket(PF_INET, SOCK_STREAM, 0);
     615    int Sock = lwip_socket(PF_INET, SOCK_STREAM, 0);
    608616    if (Sock != -1)
    609617    {
     
    614622        if (!lwip_connect(Sock, (struct sockaddr *)&InAddr, sizeof(InAddr)))
    615623        {
    616             *pSock = Sock;
     624            *pSock = (RTSOCKET)Sock;
    617625            return VINF_SUCCESS;
    618626        }
     
    628636static DECLCALLBACK(int) drvvdINIPClientClose(RTSOCKET Sock)
    629637{
    630     lwip_close(Sock);
     638    lwip_close((uintptr_t)Sock);
    631639    return VINF_SUCCESS; /** @todo real solution needed */
    632640}
     
    637645    fd_set fdsetR;
    638646    FD_ZERO(&fdsetR);
    639     FD_SET(Sock, &fdsetR);
     647    FD_SET((uintptr_t)Sock, &fdsetR);
    640648    fd_set fdsetE = fdsetR;
    641649
    642650    int rc;
    643651    if (cMillies == RT_INDEFINITE_WAIT)
    644         rc = lwip_select(Sock + 1, &fdsetR, NULL, &fdsetE, NULL);
     652        rc = lwip_select((uintptr_t)Sock + 1, &fdsetR, NULL, &fdsetE, NULL);
    645653    else
    646654    {
     
    648656        timeout.tv_sec = cMillies / 1000;
    649657        timeout.tv_usec = (cMillies % 1000) * 1000;
    650         rc = lwip_select(Sock + 1, &fdsetR, NULL, &fdsetE, &timeout);
     658        rc = lwip_select((uintptr_t)Sock + 1, &fdsetR, NULL, &fdsetE, &timeout);
    651659    }
    652660    if (rc > 0)
     
    678686         * needed it, so I added it here, too). Didn't investigate if this
    679687         * really has issues. Better be safe than sorry. */
    680         ssize_t cbBytesRead = lwip_recv(Sock, (char *)pvBuffer + cbRead,
     688        ssize_t cbBytesRead = lwip_recv((uintptr_t)Sock, (char *)pvBuffer + cbRead,
    681689                                        RT_MIN(cbToRead, 32768), 0);
    682690        if (cbBytesRead < 0)
     
    712720         * don't get any wraparounds. This should be moved to DevINIP
    713721         * stack interface once that's implemented. */
    714         ssize_t cbWritten = lwip_send(Sock, (void *)pvBuffer,
     722        ssize_t cbWritten = lwip_send((uintptr_t)Sock, (void *)pvBuffer,
    715723                                      RT_MIN(cbBuffer, 32768), 0);
    716724        if (cbWritten < 0)
     
    725733}
    726734
     735/** @copydoc VDINTERFACETCPNET::pfnSgWrite */
     736static DECLCALLBACK(int) drvvdINIPSgWrite(RTSOCKET Sock, PCRTSGBUF pSgBuf)
     737{
     738    int rc = VINF_SUCCESS;
     739
     740    /* This is an extremely crude emulation, however it's good enough
     741     * for our iSCSI code. INIP has no sendmsg(). */
     742    for (unsigned i = 0; i < pSgBuf->cSeg; i++)
     743    {
     744        rc = drvvdINIPWrite(Sock, pSgBuf->pcaSeg[i].pvSeg,
     745                            pSgBuf->pcaSeg[i].cbSeg);
     746        if (RT_FAILURE(rc))
     747            break;
     748    }
     749    if (RT_SUCCESS(rc))
     750        drvvdINIPFlush(Sock);
     751
     752    return rc;
     753}
     754
    727755/** @copydoc VDINTERFACETCPNET::pfnFlush */
    728756static DECLCALLBACK(int) drvvdINIPFlush(RTSOCKET Sock)
    729757{
    730758    int fFlag = 1;
    731     lwip_setsockopt(Sock, IPPROTO_TCP, TCP_NODELAY,
     759    lwip_setsockopt((uintptr_t)Sock, IPPROTO_TCP, TCP_NODELAY,
    732760                    (const char *)&fFlag, sizeof(fFlag));
    733761    fFlag = 0;
    734     lwip_setsockopt(Sock, IPPROTO_TCP, TCP_NODELAY,
     762    lwip_setsockopt((uintptr_t)Sock, IPPROTO_TCP, TCP_NODELAY,
    735763                    (const char *)&fFlag, sizeof(fFlag));
    736764    return VINF_SUCCESS;
    737765}
    738766
     767/** @copydoc VDINTERFACETCPNET::pfnSetSendCoalescing */
     768static DECLCALLBACK(int) drvvdINIPSetSendCoalescing(RTSOCKET Sock, bool fEnable)
     769{
     770    int fFlag = fEnable ? 0 : 1;
     771    lwip_setsockopt((uintptr_t)Sock, IPPROTO_TCP, TCP_NODELAY,
     772                    (const char *)&fFlag, sizeof(fFlag));
     773    return VINF_SUCCESS;
     774}
     775
    739776/** @copydoc VDINTERFACETCPNET::pfnGetLocalAddress */
    740777static DECLCALLBACK(int) drvvdINIPGetLocalAddress(RTSOCKET Sock, PRTNETADDR pAddr)
    741778{
    742    union
    743     {
    744         struct sockaddr     Addr;
    745         struct sockaddr_in  Ipv4;
    746     }               u;
    747     socklen_t       cbAddr = sizeof(u);
     779    INIPSOCKADDRUNION u;
     780    socklen_t cbAddr = sizeof(u);
    748781    RT_ZERO(u);
    749     if (!lwip_getsockname(Sock, &u.Addr, &cbAddr))
     782    if (!lwip_getsockname((uintptr_t)Sock, &u.Addr, &cbAddr))
    750783    {
    751784        /*
     
    770803static DECLCALLBACK(int) drvvdINIPGetPeerAddress(RTSOCKET Sock, PRTNETADDR pAddr)
    771804{
    772    union
    773     {
    774         struct sockaddr     Addr;
    775         struct sockaddr_in  Ipv4;
    776     }               u;
    777     socklen_t       cbAddr = sizeof(u);
     805    INIPSOCKADDRUNION u;
     806    socklen_t cbAddr = sizeof(u);
    778807    RT_ZERO(u);
    779     if (!lwip_getpeername(Sock, &u.Addr, &cbAddr))
     808    if (!lwip_getpeername((uintptr_t)Sock, &u.Addr, &cbAddr))
    780809    {
    781810        /*
     
    13861415            pThis->VDITcpNetCallbacks.pfnRead = RTTcpRead;
    13871416            pThis->VDITcpNetCallbacks.pfnWrite = RTTcpWrite;
     1417            pThis->VDITcpNetCallbacks.pfnSgWrite = RTTcpSgWrite;
    13881418            pThis->VDITcpNetCallbacks.pfnFlush = RTTcpFlush;
     1419            pThis->VDITcpNetCallbacks.pfnSetSendCoalescing = RTTcpSetSendCoalescing;
    13891420            pThis->VDITcpNetCallbacks.pfnGetLocalAddress = RTTcpGetLocalAddress;
    13901421            pThis->VDITcpNetCallbacks.pfnGetPeerAddress = RTTcpGetPeerAddress;
     
    14031434            pThis->VDITcpNetCallbacks.pfnRead = drvvdINIPRead;
    14041435            pThis->VDITcpNetCallbacks.pfnWrite = drvvdINIPWrite;
     1436            pThis->VDITcpNetCallbacks.pfnSgWrite = drvvdINIPSgWrite;
    14051437            pThis->VDITcpNetCallbacks.pfnFlush = drvvdINIPFlush;
     1438            pThis->VDITcpNetCallbacks.pfnSetSendCoalescing = drvvdINIPSetSendCoalescing;
    14061439            pThis->VDITcpNetCallbacks.pfnGetLocalAddress = drvvdINIPGetLocalAddress;
    14071440            pThis->VDITcpNetCallbacks.pfnGetPeerAddress = drvvdINIPGetPeerAddress;
  • trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp

    r29498 r30309  
    218218/** ISCSI BHS word 0: response includes status. */
    219219#define ISCSI_STATUS_BIT 0x00010000
     220
     221/** Maximum number of scatter/gather segments needed to send a PDU. */
     222#define ISCSI_SG_SEGMENTS_MAX 4
    220223
    221224
     
    548551        return rc;
    549552    }
     553
     554    /* Disable Nagle algorithm, we want things to be sent immediately. */
     555    pImage->pInterfaceNetCallbacks->pfnSetSendCoalescing(pImage->Socket, false);
    550556
    551557    /* Make initiator name and ISID unique on this host. */
     
    714720    if (RT_SUCCESS(rc))
    715721    {
     722        /* Construct scatter/gather buffer for entire request, worst case
     723         * needs twice as many entries to allow for padding. */
     724        unsigned cBuf = 0;
    716725        for (i = 0; i < cnRequest; i++)
    717726        {
    718             /* Write one chunk of data. */
    719             rc = pImage->pInterfaceNetCallbacks->pfnWrite(pImage->Socket,
    720                                                           paRequest[i].pcvSeg,
    721                                                           paRequest[i].cbSeg);
    722             if (RT_FAILURE(rc))
    723                 break;
    724             /* Insert proper padding before the next chunk us written. */
     727            cBuf++;
     728            if (paRequest[i].cbSeg & 3)
     729                cBuf++;
     730        }
     731        Assert(cBuf < ISCSI_SG_SEGMENTS_MAX);
     732        RTSGBUF buf;
     733        RTSGSEG aSeg[ISCSI_SG_SEGMENTS_MAX];
     734        static char aPad[4] = { 0, 0, 0, 0 };
     735        RTSgBufInit(&buf, &aSeg[0], cBuf);
     736        unsigned iBuf = 0;
     737        for (i = 0; i < cnRequest; i++)
     738        {
     739            /* Actual data chunk. */
     740            aSeg[iBuf].pvSeg = (void *)paRequest[i].pcvSeg;
     741            aSeg[iBuf].cbSeg = paRequest[i].cbSeg;
     742            iBuf++;
     743            /* Insert proper padding before the next chunk. */
    725744            if (paRequest[i].cbSeg & 3)
    726745            {
    727                 rc = pImage->pInterfaceNetCallbacks->pfnWrite(pImage->Socket,
    728                                                               &pad,
    729                                                               4 - (paRequest[i].cbSeg & 3));
    730                 if (RT_FAILURE(rc))
    731                     break;
     746                aSeg[iBuf].pvSeg = &aPad[0];
     747                aSeg[iBuf].cbSeg = 4 - (paRequest[i].cbSeg & 3);
     748                iBuf++;
    732749            }
    733750        }
    734         /* Send out the request as soon as possible, otherwise the target will
    735          * answer after an unnecessary delay. */
    736         pImage->pInterfaceNetCallbacks->pfnFlush(pImage->Socket);
     751        /* Send out the request, the socket is set to send data immediately,
     752         * avoiding unnecessary delays. */
     753        rc = pImage->pInterfaceNetCallbacks->pfnSgWrite(pImage->Socket, &buf);
     754
    737755    }
    738756
  • trunk/src/VBox/Main/MediumImpl.cpp

    r30292 r30309  
    673673    m->vdIfCallsTcpNet.pfnRead = RTTcpRead;
    674674    m->vdIfCallsTcpNet.pfnWrite = RTTcpWrite;
     675    m->vdIfCallsTcpNet.pfnSgWrite = RTTcpSgWrite;
    675676    m->vdIfCallsTcpNet.pfnFlush = RTTcpFlush;
     677    m->vdIfCallsTcpNet.pfnSetSendCoalescing = RTTcpSetSendCoalescing;
    676678    m->vdIfCallsTcpNet.pfnGetLocalAddress = RTTcpGetLocalAddress;
    677679    m->vdIfCallsTcpNet.pfnGetPeerAddress = RTTcpGetPeerAddress;
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