VirtualBox

Changeset 59990 in vbox


Ignore:
Timestamp:
Mar 11, 2016 12:39:06 PM (9 years ago)
Author:
vboxsync
Message:

NetLwf/Win(bugref:8283): dynamic allocation of MDLs which fixes jumbo frame issue

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetLwf-win.cpp

    r59971 r59990  
    1616#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
    1717
    18 //#define VBOXNETLWF_TEST_NO_FRAMES_OVER_2K
    19 //#define VBOXNETLWF_TEST_NO_REALLOCATE
    20 
    2118//#define VBOXNETLWF_SYNC_SEND
    22 /* Payload + Ethernet header + VLAN tag = Max Ethernet frame size */
    23 #define VBOXNETLWF_MAX_FRAME_SIZE(mtu) (mtu +  sizeof(RTNETETHERHDR) + 4)
     19
     20/*
     21 * Don't ask me why it is 42. Empirically this is what goes down the stack.
     22 * OTOH, as we know from trustworthy sources, 42 is the answer, so be it.
     23 */
     24#define VBOXNETLWF_MAX_FRAME_SIZE(mtu) (mtu + 42)
    2425
    2526#include <VBox/version.h>
     
    198199    /** MAC address of underlying adapter */
    199200    RTMAC MacAddr;
    200     /** Saved MTU size */
    201     ULONG uMtuSize;
    202201    /** Saved offload configuration */
    203202    NDIS_OFFLOAD SavedOffloadConfig;
     
    912911#endif /* !VBOXNETLWF_SYNC_SEND */
    913912
    914 #ifdef VBOXNETLWF_TEST_NO_REALLOCATE
    915913    /* Allocate buffer pools */
    916914    NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
     
    923921    PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
    924922    PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
    925 #ifndef VBOXNETLWF_SYNC_SEND
    926     PoolParams.DataSize = 9088;
    927 #endif /* !VBOXNETLWF_SYNC_SEND */
    928923               
    929924    pModuleCtx->hPool = NdisAllocateNetBufferListPool(hFilter, &PoolParams);
     
    936931    }
    937932    Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool 0x%p\n", pModuleCtx->hPool));
    938 #endif /* VBOXNETLWF_TEST_NO_REALLOCATE */
    939933
    940934    NDIS_FILTER_ATTRIBUTES Attributes;
     
    10501044    PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
    10511045    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Restarting, LwfState_Paused);
    1052 
     1046    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Running, LwfState_Restarting);
    10531047    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
    1054 #ifndef VBOXNETLWF_TEST_NO_REALLOCATE
    1055     ULONG uNewMtuSize = 1500; /* If we fail to find out MTU, we can always assume 1500. */
    1056     PNDIS_RESTART_ATTRIBUTES pAttributes = pParameters->RestartAttributes;
    1057     while (pAttributes && pAttributes->Oid != OID_GEN_MINIPORT_RESTART_ATTRIBUTES)
    1058         pAttributes = pAttributes->Next;
    1059     if (pAttributes)
    1060     {
    1061         PNDIS_RESTART_GENERAL_ATTRIBUTES pGenAttrs = (PNDIS_RESTART_GENERAL_ATTRIBUTES)pAttributes->Data;
    1062         uNewMtuSize = pGenAttrs->MtuSize;
    1063     }
    1064 
    1065     /* Let's see if MTU has changed. Re-allocate the pool if it has. */
    1066     if (pModuleCtx->uMtuSize != uNewMtuSize)
    1067     {
    1068         pModuleCtx->uMtuSize = uNewMtuSize;
    1069         if (pModuleCtx->hPool)
    1070         {
    1071             /*
    1072              * Don't need to wait for pending sends to complete since we are already
    1073              * in paused state. Just free the old pool.
    1074              */
    1075             NdisFreeNetBufferListPool(pModuleCtx->hPool);
    1076             pModuleCtx->hPool = NULL;
    1077         }
    1078     }
    1079     if (!pModuleCtx->hPool)
    1080     {
    1081         /* Allocate a new pool. */
    1082         NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
    1083         NdisZeroMemory(&PoolParams, sizeof(PoolParams));
    1084         PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    1085         PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
    1086         PoolParams.Header.Size = sizeof(PoolParams);
    1087         PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
    1088         PoolParams.fAllocateNetBuffer = TRUE;
    1089         PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
    1090         PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
    1091 #ifndef VBOXNETLWF_SYNC_SEND
    1092         PoolParams.DataSize = VBOXNETLWF_MAX_FRAME_SIZE(pModuleCtx->uMtuSize);
    1093 #endif /* !VBOXNETLWF_SYNC_SEND */
    1094 
    1095         pModuleCtx->hPool = NdisAllocateNetBufferListPool(pModuleCtx->hFilter, &PoolParams);
    1096         if (!pModuleCtx->hPool)
    1097         {
    1098             LogError(("vboxNetLwfWinRestart: NdisAllocateNetBufferListPool failed\n"));
    1099             Status = NDIS_STATUS_RESOURCES;
    1100         }
    1101         else
    1102         {
    1103             Log4(("vboxNetLwfWinRestart: allocated NBL+NB pool 0x%p with MTU=%u\n",
    1104                   pModuleCtx->hPool, pModuleCtx->uMtuSize));
    1105         }
    1106     }
    1107 
    1108     vboxNetLwfWinChangeState(pModuleCtx, Status == NDIS_STATUS_SUCCESS ? LwfState_Running : LwfState_Paused, LwfState_Restarting);
    1109 #else /* !VBOXNETLWF_TEST_NO_REALLOCATE */
    1110     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Running, LwfState_Restarting);
    1111 #endif /* !VBOXNETLWF_TEST_NO_REALLOCATE */
    11121048    LogFlow(("<==vboxNetLwfWinRestart: Status = 0x%x\n", Status));
    11131049    return Status;
     
    11211057        for (PNET_BUFFER pBuf = NET_BUFFER_LIST_FIRST_NB(pList); pBuf; pBuf = NET_BUFFER_NEXT_NB(pBuf))
    11221058        {
    1123             Log(("%s packet: cb=%d\n", pszMsg, NET_BUFFER_DATA_LENGTH(pBuf)));
     1059            Log6(("%s packet: cb=%d offset=%d", pszMsg, NET_BUFFER_DATA_LENGTH(pBuf), NET_BUFFER_DATA_OFFSET(pBuf)));
     1060            for (PMDL pMdl = NET_BUFFER_FIRST_MDL(pBuf);
     1061                 pMdl != NULL;
     1062                 pMdl = NDIS_MDL_LINKAGE(pMdl))
     1063            {
     1064                Log6((" MDL: cb=%d", MmGetMdlByteCount(pMdl)));
     1065            }
     1066            Log6(("\n"));
    11241067        }
    11251068    }
     
    12871230DECLINLINE(void) vboxNetLwfWinFreeMdlChain(PMDL pMdl)
    12881231{
    1289 #ifdef VBOXNETLWF_SYNC_SEND
    12901232    PMDL pMdlNext;
    12911233    while (pMdl)
    12921234    {
    12931235        pMdlNext = pMdl->Next;
     1236#ifndef VBOXNETLWF_SYNC_SEND
     1237        PUCHAR pDataBuf;
     1238        ULONG cb = 0;
     1239        NdisQueryMdl(pMdl, &pDataBuf, &cb, NormalPagePriority);
     1240#endif /* !VBOXNETLWF_SYNC_SEND */
    12941241        NdisFreeMdl(pMdl);
    12951242        Log4(("vboxNetLwfWinFreeMdlChain: freed MDL 0x%p\n", pMdl));
     1243#ifndef VBOXNETLWF_SYNC_SEND
     1244        NdisFreeMemory(pDataBuf, 0, 0);
     1245        Log4(("vboxNetLwfWinFreeMdlChain: freed data buffer 0x%p\n", pDataBuf));
     1246#endif /* !VBOXNETLWF_SYNC_SEND */
    12961247        pMdl = pMdlNext;
    12971248    }
    1298 #endif /* VBOXNETLWF_SYNC_SEND */
    12991249}
    13001250
     
    13541304    }
    13551305#else /* !VBOXNETLWF_SYNC_SEND */
    1356 #ifdef VBOXNETLWF_TEST_NO_FRAMES_OVER_2K
    1357     AssertReturn(pSG->cbTotal < 2048, NULL);
    1358 #else /* !VBOXNETLWF_TEST_NO_FRAMES_OVER_2K */
    1359     AssertReturn(pSG->cbTotal <= VBOXNETLWF_MAX_FRAME_SIZE(pModule->uMtuSize), NULL);
    1360 #endif /* !VBOXNETLWF_TEST_NO_FRAMES_OVER_2K */
    1361     PNET_BUFFER_LIST pBufList = NdisAllocateNetBufferList(pModule->hPool,
    1362                                                           0 /** @todo ContextSize */,
    1363                                                           0 /** @todo ContextBackFill */);
    1364     NET_BUFFER_LIST_NEXT_NBL(pBufList) = NULL; /** @todo Is it even needed? */
    1365     NET_BUFFER *pBuffer = NET_BUFFER_LIST_FIRST_NB(pBufList);
    1366     NDIS_STATUS Status = NdisRetreatNetBufferDataStart(pBuffer, pSG->cbTotal, 0 /** @todo DataBackfill */, NULL);
    1367     if (Status == NDIS_STATUS_SUCCESS)
    1368     {
    1369         uint8_t *pDst = (uint8_t*)NdisGetDataBuffer(pBuffer, pSG->cbTotal, NULL, 1, 0);
    1370         if (pDst)
    1371         {
    1372             for (int i = 0; i < pSG->cSegsUsed; i++)
    1373             {
    1374                 NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb);
    1375                 pDst += pSG->aSegs[i].cb;
    1376             }
    1377             Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB+MDL+Data 0x%p\n", pBufList));
     1306    PNET_BUFFER_LIST pBufList = NULL;
     1307    ULONG cbMdl = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal);
     1308    ULONG uDataOffset = cbMdl - pSG->cbTotal;
     1309    PUCHAR pDataBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pModule->hFilter, cbMdl,
     1310                                                                VBOXNETLWF_MEM_TAG, NormalPoolPriority);
     1311    if (pDataBuf)
     1312    {
     1313        Log4(("vboxNetLwfWinSGtoNB: allocated data buffer (cb=%u) 0x%p\n", cbMdl, pDataBuf));
     1314        PMDL pMdl = NdisAllocateMdl(pModule->hFilter, pDataBuf, cbMdl);
     1315        if (!pMdl)
     1316        {
     1317            NdisFreeMemory(pDataBuf, 0, 0);
     1318            Log4(("vboxNetLwfWinSGtoNB: freed data buffer 0x%p\n", pDataBuf));
     1319            LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL (cb=%u)\n", cbMdl));
     1320            LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
     1321            return NULL;
     1322        }
     1323        PUCHAR pDst = pDataBuf + uDataOffset;
     1324        for (int i = 0; i < pSG->cSegsUsed; i++)
     1325        {
     1326            NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb);
     1327            pDst += pSG->aSegs[i].cb;
     1328        }
     1329        pBufList = NdisAllocateNetBufferAndNetBufferList(pModule->hPool,
     1330                                                         0 /* ContextSize */,
     1331                                                         0 /* ContextBackFill */,
     1332                                                         pMdl,
     1333                                                         uDataOffset,
     1334                                                         pSG->cbTotal);
     1335        if (pBufList)
     1336        {
     1337            Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
    13781338            pBufList->SourceHandle = pModule->hFilter;
    13791339            /** @todo Do we need to initialize anything else? */
     
    13811341        else
    13821342        {
    1383             LogError(("vboxNetLwfWinSGtoNB: failed to obtain the buffer pointer (size=%u)\n", pSG->cbTotal));
    1384             NdisAdvanceNetBufferDataStart(pBuffer, pSG->cbTotal, false, NULL); /** @todo why bother? */
    1385             NdisFreeNetBufferList(pBufList);
    1386             pBufList = NULL;
     1343            LogError(("vboxNetLwfWinSGtoNB: failed to allocate an NBL+NB\n"));
     1344            vboxNetLwfWinFreeMdlChain(pMdl);
    13871345        }
    13881346    }
    13891347    else
    13901348    {
    1391         LogError(("vboxNetLwfWinSGtoNB: NdisRetreatNetBufferDataStart failed with 0x%x (size=%u)\n", Status, pSG->cbTotal));
    1392         NdisFreeNetBufferList(pBufList);
    1393         pBufList = NULL;
     1349        LogError(("vboxNetLwfWinSGtoNB: failed to allocate data buffer (size=%u)\n", cbMdl));
    13941350    }
    13951351#endif /* !VBOXNETLWF_SYNC_SEND */
     
    15691525    LogFlow(("==>vboxNetLwfWinSendNetBufferLists: module=%p\n", hModuleCtx));
    15701526    PVBOXNETLWF_MODULE pModule = (PVBOXNETLWF_MODULE)hModuleCtx;
     1527    vboxNetLwfWinDumpPackets("vboxNetLwfWinSendNetBufferLists: got", pBufLists);
    15711528
    15721529    if (!ASMAtomicReadBool(&pModule->fActive))
     
    17041661    LogFlow(("==>vboxNetLwfWinReceiveNetBufferLists: module=%p\n", hModuleCtx));
    17051662    PVBOXNETLWF_MODULE pModule = (PVBOXNETLWF_MODULE)hModuleCtx;
     1663    vboxNetLwfWinDumpPackets("vboxNetLwfWinReceiveNetBufferLists: got", pBufLists);
    17061664
    17071665    if (!ASMAtomicReadBool(&pModule->fActive))
     
    22132171        if (pBufList)
    22142172        {
     2173            vboxNetLwfWinDumpPackets("vboxNetFltPortOsXmit: sending down", pBufList);
    22152174#ifdef VBOXNETLWF_SYNC_SEND
    22162175            aEvents[nEvents++] = &pModule->EventWire;
     
    22272186        if (pBufList)
    22282187        {
     2188            vboxNetLwfWinDumpPackets("vboxNetFltPortOsXmit: sending up", pBufList);
    22292189#ifdef VBOXNETLWF_SYNC_SEND
    22302190            aEvents[nEvents++] = &pModule->EventHost;
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