VirtualBox

vbox的更動 59998 路徑 trunk/src/VBox/HostDrivers


忽略:
時間撮記:
2016-3-11 下午04:23:59 (9 年 以前)
作者:
vboxsync
訊息:

NetLwf/Win(bugref:8283): five pre-allocated pools to accomodate various frame sizes.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetLwf-win.cpp

    r59993 r59998  
    1616#define LOG_GROUP LOG_GROUP_NET_FLT_DRV
    1717
     18/*
     19 * If VBOXNETLWF_SYNC_SEND is defined we won't allocate data buffers, but use
     20 * the original buffers coming from IntNet to build MDLs around them. This
     21 * also means that we need to wait for send operation to complete before
     22 * returning the buffers, which hinders performance way too much.
     23 */
    1824//#define VBOXNETLWF_SYNC_SEND
     25
     26/*
     27 * If VBOXNETLWF_FIXED_SIZE_POOLS is defined we pre-allocate data buffers of
     28 * fixed size in five pools. Each pool uses different size to accomodate packets
     29 * of various sizes. We allocate these buffers once and re-use them when send
     30 * operation is complete.
     31 * If VBOXNETLWF_FIXED_SIZE_POOLS is not defined we allocate data buffers before
     32 * each send operation and free then upon completion.
     33 */
     34#define VBOXNETLWF_FIXED_SIZE_POOLS
    1935
    2036/*
     
    172188VBOXNETLWFGLOBALS g_VBoxNetLwfGlobals;
    173189
     190#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     191static ULONG g_cbPool[] = { 576+56, 1556, 4096+56, 6192+56, 9056 };
     192#endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
     193
    174194typedef struct _VBOXNETLWF_MODULE {
    175195    RTLISTNODE node;
    176196
    177197    NDIS_HANDLE hFilter;
     198#ifndef VBOXNETLWF_FIXED_SIZE_POOLS
    178199    NDIS_HANDLE hPool;
     200#else /* VBOXNETLWF_FIXED_SIZE_POOLS */
     201    NDIS_HANDLE hPool[RT_ELEMENTS(g_cbPool)];
     202#endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
    179203    PVBOXNETLWFGLOBALS pGlobals;
    180204    /** Associated instance of NetFlt, one-to-one relationship */
     
    838862}
    839863
     864#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     865static void vboxNetLwfWinFreePools(PVBOXNETLWF_MODULE pModuleCtx, int cPools)
     866{
     867    for (int i = 0; i < cPools; ++i)
     868    {
     869        if (pModuleCtx->hPool[i])
     870        {
     871            NdisFreeNetBufferListPool(pModuleCtx->hPool[i]);
     872            Log4(("vboxNetLwfWinAttach: freeed NBL+NB pool 0x%p\n", pModuleCtx->hPool[i]));
     873        }
     874    }
     875}
     876#endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
     877
    840878static NDIS_STATUS vboxNetLwfWinAttach(IN NDIS_HANDLE hFilter, IN NDIS_HANDLE hDriverCtx,
    841879                                       IN PNDIS_FILTER_ATTACH_PARAMETERS pParameters)
     
    911949#endif /* !VBOXNETLWF_SYNC_SEND */
    912950
     951#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     952    for (int i = 0; i < RT_ELEMENTS(g_cbPool); ++i)
     953    {
     954        /* Allocate buffer pools */
     955        NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
     956        NdisZeroMemory(&PoolParams, sizeof(PoolParams));
     957        PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
     958        PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
     959        PoolParams.Header.Size = sizeof(PoolParams);
     960        PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
     961        PoolParams.fAllocateNetBuffer = TRUE;
     962        PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
     963        PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
     964        PoolParams.DataSize = g_cbPool[i];
     965        pModuleCtx->hPool[i] = NdisAllocateNetBufferListPool(hFilter, &PoolParams);
     966        if (!pModuleCtx->hPool[i])
     967        {
     968            LogError(("vboxNetLwfWinAttach: NdisAllocateNetBufferListPool failed\n"));
     969            vboxNetLwfWinFreePools(pModuleCtx, i);
     970            NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
     971            NdisFreeMemory(pModuleCtx, 0, 0);
     972            return NDIS_STATUS_RESOURCES;
     973        }
     974        Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool (data size=%u) 0x%p\n",
     975              PoolParams.DataSize, pModuleCtx->hPool[i]));
     976    }
     977#else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    913978    /* Allocate buffer pools */
    914979    NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
     
    921986    PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
    922987    PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
    923                
    924988    pModuleCtx->hPool = NdisAllocateNetBufferListPool(hFilter, &PoolParams);
    925989    if (!pModuleCtx->hPool)
     
    931995    }
    932996    Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool 0x%p\n", pModuleCtx->hPool));
     997#endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    933998
    934999    NDIS_FILTER_ATTRIBUTES Attributes;
     
    9421007    {
    9431008        LogError(("vboxNetLwfWinAttach: NdisFSetAttributes failed with 0x%x\n", Status));
     1009#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     1010        vboxNetLwfWinFreePools(pModuleCtx, RT_ELEMENTS(g_cbPool));
     1011#else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    9441012        NdisFreeNetBufferListPool(pModuleCtx->hPool);
    9451013        Log4(("vboxNetLwfWinAttach: freed NBL+NB pool 0x%p\n", pModuleCtx->hPool));
     1014#endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    9461015        NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
    9471016        NdisFreeMemory(pModuleCtx, 0, 0);
     
    9931062     * by vboxNetLwfWinPause().
    9941063     */
     1064#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     1065    vboxNetLwfWinFreePools(pModuleCtx, RT_ELEMENTS(g_cbPool));
     1066#else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    9951067    if (pModuleCtx->hPool)
    9961068    {
     
    9981070        Log4(("vboxNetLwfWinDetach: freed NBL+NB pool 0x%p\n", pModuleCtx->hPool));
    9991071    }
     1072#endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    10001073    NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
    10011074    NdisFreeMemory(hModuleCtx, 0, 0);
     
    12301303DECLINLINE(void) vboxNetLwfWinFreeMdlChain(PMDL pMdl)
    12311304{
     1305#ifndef VBOXNETLWF_FIXED_SIZE_POOLS
    12321306    PMDL pMdlNext;
    12331307    while (pMdl)
     
    12471321        pMdl = pMdlNext;
    12481322    }
     1323#endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
    12491324}
    12501325
     
    13041379    }
    13051380#else /* !VBOXNETLWF_SYNC_SEND */
     1381
     1382# ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     1383    int iPool = 0;
     1384    ULONG cbFrame = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal);
     1385    /* Let's find the appropriate pool first */
     1386    for (iPool = 0; iPool < RT_ELEMENTS(g_cbPool); ++iPool)
     1387        if (cbFrame <= g_cbPool[iPool])
     1388            break;
     1389    if (iPool >= RT_ELEMENTS(g_cbPool))
     1390    {
     1391        LogError(("vboxNetLwfWinSGtoNB: frame is too big (%u > %u), drop it.\n", cbFrame, g_cbPool[RT_ELEMENTS(g_cbPool)-1]));
     1392        LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
     1393        return NULL;
     1394    }
     1395    PNET_BUFFER_LIST pBufList = NdisAllocateNetBufferList(pModule->hPool[iPool],
     1396                                                          0 /** @todo ContextSize */,
     1397                                                          0 /** @todo ContextBackFill */);
     1398    if (!pBufList)
     1399    {
     1400        LogError(("vboxNetLwfWinSGtoNB: failed to allocate netbuffer (cb=%u) from pool %d\n", cbFrame, iPool));
     1401        LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
     1402        return NULL;
     1403    }
     1404    NET_BUFFER *pBuffer = NET_BUFFER_LIST_FIRST_NB(pBufList);
     1405    NDIS_STATUS Status = NdisRetreatNetBufferDataStart(pBuffer, pSG->cbTotal, 0 /** @todo DataBackfill */, NULL);
     1406    if (Status == NDIS_STATUS_SUCCESS)
     1407    {
     1408        uint8_t *pDst = (uint8_t*)NdisGetDataBuffer(pBuffer, pSG->cbTotal, NULL, 1, 0);
     1409        if (pDst)
     1410        {
     1411            for (int i = 0; i < pSG->cSegsUsed; i++)
     1412            {
     1413                NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb);
     1414                pDst += pSG->aSegs[i].cb;
     1415            }
     1416            Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
     1417            pBufList->SourceHandle = pModule->hFilter;
     1418        }
     1419        else
     1420        {
     1421            LogError(("vboxNetLwfWinSGtoNB: failed to obtain the buffer pointer (size=%u)\n", pSG->cbTotal));
     1422            NdisAdvanceNetBufferDataStart(pBuffer, pSG->cbTotal, false, NULL); /** @todo why bother? */
     1423            NdisFreeNetBufferList(pBufList);
     1424            pBufList = NULL;
     1425        }
     1426    }
     1427    else
     1428    {
     1429        LogError(("vboxNetLwfWinSGtoNB: NdisRetreatNetBufferDataStart failed with 0x%x (size=%u)\n", Status, pSG->cbTotal));
     1430        NdisFreeNetBufferList(pBufList);
     1431        pBufList = NULL;
     1432    }
     1433# else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    13061434    PNET_BUFFER_LIST pBufList = NULL;
    13071435    ULONG cbMdl = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal);
     
    13491477        LogError(("vboxNetLwfWinSGtoNB: failed to allocate data buffer (size=%u)\n", cbMdl));
    13501478    }
     1479# endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
     1480
    13511481#endif /* !VBOXNETLWF_SYNC_SEND */
    13521482    LogFlow(("<==vboxNetLwfWinSGtoNB: return %p\n", pBufList));
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette