VirtualBox

Ignore:
Timestamp:
Apr 7, 2010 6:37:43 AM (15 years ago)
Author:
vboxsync
Message:

intnet, VBoxNet*, network device & drivers: GSO preps.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r27973 r28025  
    2525#define LOG_GROUP LOG_GROUP_DRV_INTNET
    2626#include <VBox/pdmdrv.h>
     27#include <VBox/pdmnetinline.h>
    2728#include <VBox/pdmnetifs.h>
    2829#include <VBox/cfgm.h>
     
    196197    int         rc    = VINF_SUCCESS;
    197198    Assert(cbMin < UINT32_MAX / 2);
    198 AssertReturn(!pGso, VERR_NOT_IMPLEMENTED); /** @todo GSO buffer allocation. */
    199199
    200200    /*
     
    205205    {
    206206        PINTNETHDR pHdr;
    207         rc = INTNETRingAllocateFrame(&pThis->pBufR3->Send, (uint32_t)cbMin,
    208                                      &pHdr, &pSgBuf->aSegs[0].pvSeg);
     207        if (pGso)
     208            rc = INTNETRingAllocateGsoFrame(&pThis->pBufR3->Send, (uint32_t)cbMin, pGso,
     209                                            &pHdr, &pSgBuf->aSegs[0].pvSeg);
     210        else
     211            rc = INTNETRingAllocateFrame(&pThis->pBufR3->Send, (uint32_t)cbMin,
     212                                         &pHdr, &pSgBuf->aSegs[0].pvSeg);
     213
    209214#if 1 /** @todo implement VERR_TRY_AGAIN once this moves to EMT. */
    210215        if (    RT_FAILURE(rc)
     
    218223            PDMDrvHlpSUPCallVMMR0Ex(pThis->pDrvInsR3, VMMR0_DO_INTNET_IF_SEND, &SendReq, sizeof(SendReq));
    219224
    220             rc = INTNETRingAllocateFrame(&pThis->pBufR3->Send, (uint32_t)cbMin,
    221                                          &pHdr, &pSgBuf->aSegs[0].pvSeg);
     225            if (pGso)
     226                rc = INTNETRingAllocateGsoFrame(&pThis->pBufR3->Send, (uint32_t)cbMin, pGso,
     227                                                &pHdr, &pSgBuf->aSegs[0].pvSeg);
     228            else
     229                rc = INTNETRingAllocateFrame(&pThis->pBufR3->Send, (uint32_t)cbMin,
     230                                             &pHdr, &pSgBuf->aSegs[0].pvSeg);
    222231        }
    223232#endif
     
    227236            pSgBuf->cbUsed          = 0;
    228237            pSgBuf->cbAvailable     = cbMin;
    229             pSgBuf->pvUser          = pHdr;
     238            pSgBuf->pvAllocator     = pHdr;
     239            pSgBuf->pvUser          = pGso ? (PPDMNETWORKGSO)pSgBuf->aSegs[0].pvSeg - 1 : NULL;
    230240            pSgBuf->cSegs           = 1;
    231241            pSgBuf->aSegs[0].cbSeg  = cbMin;
     
    257267{
    258268    PDRVINTNET  pThis = RT_FROM_MEMBER(pInterface, DRVINTNET, INetworkUpR3);
    259     PINTNETHDR  pHdr  = (PINTNETHDR)pSgBuf->pvUser;
     269    PINTNETHDR  pHdr  = (PINTNETHDR)pSgBuf->pvAllocator;
    260270    Assert(pSgBuf->fFlags == (PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1));
    261271    Assert(pSgBuf->cbUsed <= pSgBuf->cbAvailable);
    262     Assert(pHdr->u16Type == INTNETHDR_TYPE_FRAME);
     272    Assert(   pHdr->u16Type == INTNETHDR_TYPE_FRAME
     273           || pHdr->u16Type == INTNETHDR_TYPE_GSO);
    263274
    264275    /** @todo LATER: try unalloc the frame. */
     
    285296     * Commit the frame and push it thru the switch.
    286297     */
    287     PINTNETHDR pHdr = (PINTNETHDR)pSgBuf->pvUser;
     298    PINTNETHDR pHdr = (PINTNETHDR)pSgBuf->pvAllocator;
    288299    INTNETRingCommitFrameEx(&pThis->pBufR3->Send, pHdr, pSgBuf->cbUsed);
    289300
     
    411422    return rc;
    412423}
     424
     425
    413426
    414427
     
    450463
    451464            Log2(("pHdr=%p offRead=%#x: %.8Rhxs\n", pHdr, pRingBuf->offReadX, pHdr));
    452             if (    pHdr->u16Type == INTNETHDR_TYPE_FRAME
     465            uint16_t u16Type = pHdr->u16Type;
     466            if (    (   u16Type == INTNETHDR_TYPE_FRAME
     467                     || u16Type == INTNETHDR_TYPE_GSO)
    453468                &&  !pThis->fLinkDown)
    454469            {
     
    460475                if (rc == VINF_SUCCESS)
    461476                {
     477                    if (u16Type == INTNETHDR_TYPE_FRAME)
     478                    {
     479                        /*
     480                         * Normal frame.
     481                         */
    462482#ifdef LOG_ENABLED
    463                     uint64_t u64Now = RTTimeProgramNanoTS();
    464                     LogFlow(("drvR3IntNetAsyncIoRun: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
    465                              cbFrame, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS));
    466                     pThis->u64LastReceiveTS = u64Now;
    467                     Log2(("drvR3IntNetAsyncIoRun: cbFrame=%#x\n"
    468                           "%.*Rhxd\n",
    469                           cbFrame, cbFrame, INTNETHdrGetFramePtr(pHdr, pBuf)));
     483                        if (LogIsEnabled())
     484                        {
     485                            uint64_t u64Now = RTTimeProgramNanoTS();
     486                            LogFlow(("drvR3IntNetAsyncIoRun: %-4d bytes at %llu ns  deltas: r=%llu t=%llu\n",
     487                                     cbFrame, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS));
     488                            pThis->u64LastReceiveTS = u64Now;
     489                            Log2(("drvR3IntNetAsyncIoRun: cbFrame=%#x\n"
     490                                  "%.*Rhxd\n",
     491                                  cbFrame, cbFrame, INTNETHdrGetFramePtr(pHdr, pBuf)));
     492                        }
    470493#endif
    471                     rc = pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, INTNETHdrGetFramePtr(pHdr, pBuf), cbFrame);
    472                     AssertRC(rc);
    473 
    474                     /* skip to the next frame. */
    475                     INTNETRingSkipFrame(pRingBuf);
     494                        rc = pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, INTNETHdrGetFramePtr(pHdr, pBuf), cbFrame);
     495                        AssertRC(rc);
     496
     497                        /* skip to the next frame. */
     498                        INTNETRingSkipFrame(pRingBuf);
     499                    }
     500                    else
     501                    {
     502                        /*
     503                         * Generic segment offload frame (INTNETHDR_TYPE_GSO).
     504                         *
     505                         * This is where we do the offloading since we don't
     506                         * emulate any NICs with large receive offload (LRO).
     507                         */
     508                        PCPDMNETWORKGSO     pGso = INTNETHdrGetGsoContext(pHdr, pBuf);
     509                        if (PDMNetGsoIsValid(pGso, cbFrame, cbFrame - sizeof(PDMNETWORKGSO)))
     510                        {
     511                            uint8_t         abHdrScratch[256];
     512                            uint32_t const  cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame);
     513#ifdef LOG_ENABLED
     514                            if (LogIsEnabled())
     515                            {
     516                                uint64_t u64Now = RTTimeProgramNanoTS();
     517                                LogFlow(("drvR3IntNetAsyncIoRun: %-4d bytes at %llu ns  deltas: r=%llu t=%llu; GSO - %u segs\n",
     518                                         cbFrame, u64Now, u64Now - pThis->u64LastReceiveTS, u64Now - pThis->u64LastTransferTS, cSegs));
     519                                pThis->u64LastReceiveTS = u64Now;
     520                                Log2(("drvR3IntNetAsyncIoRun: cbFrame=%#x type=%d cbHdrs=%#x Hdr1=%#x/%#x Hdr2=%#x/%#x MMS=%#x\n"
     521                                      "%.*Rhxd\n",
     522                                      cbFrame, pGso->u8Type, pGso->cbHdrs, pGso->offHdr1, pGso->cbHdr1, pGso->offHdr2, pGso->cbHdr2,
     523                                      pGso->cbMaxSeg, cbFrame - sizeof(*pGso), pGso + 1));
     524                            }
     525#endif
     526                            for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
     527                            {
     528                                uint32_t cbSegFrame;
     529                                void    *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)(pGso + 1), cbFrame, abHdrScratch,
     530                                                                              iSeg, cSegs, &cbSegFrame);
     531                                rc = drvR3IntNetAsyncIoWaitForSpace(pThis);
     532                                if (RT_FAILURE(rc))
     533                                {
     534                                    Log(("drvR3IntNetAsyncIoRun: drvR3IntNetAsyncIoWaitForSpace -> %Rrc; iSeg=%u cSegs=%u\n", iSeg, cSegs));
     535                                    break; /* we drop the rest. */
     536                                }
     537                                rc = pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, pvSegFrame, cbSegFrame);
     538                                AssertRC(rc);
     539                            }
     540                        }
     541                        else
     542                        {
     543                            AssertMsgFailed(("cbFrame=%#x type=%d cbHdrs=%#x Hdr1=%#x/%#x Hdr2=%#x/%#x MMS=%#x\n",
     544                                             cbFrame, pGso->u8Type, pGso->cbHdrs, pGso->offHdr1, pGso->cbHdr1, pGso->offHdr2, pGso->cbHdr2, pGso->cbMaxSeg));
     545                            STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames);
     546                        }
     547
     548                        INTNETRingSkipFrame(pRingBuf);
     549                    }
    476550                }
    477551                else
     
    488562                             * NIC is going down, likely because the VM is being reset. Skip the frame.
    489563                             */
    490                             AssertMsg(   pHdr->u16Type == INTNETHDR_TYPE_FRAME
    491                                       || pHdr->u16Type == INTNETHDR_TYPE_PADDING,
    492                                       ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
     564                            AssertMsg(INETNETIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
    493565                            INTNETRingSkipFrame(pRingBuf);
    494566                        }
     
    507579                 * Link down or unknown frame - skip to the next frame.
    508580                 */
    509                 AssertMsg(   pHdr->u16Type == INTNETHDR_TYPE_FRAME
    510                           || pHdr->u16Type == INTNETHDR_TYPE_PADDING,
    511                           ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
     581                AssertMsg(INETNETIsValidFrameType(pHdr->u16Type), ("Unknown frame type %RX16! offRead=%#x\n", pHdr->u16Type, pRingBuf->offReadX));
    512582                INTNETRingSkipFrame(pRingBuf);
    513583                STAM_REL_COUNTER_INC(&pBuf->cStatBadFrames);
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