[ofw] [PATCH] IPOIB_NDIS6_CM remove NBL/MDL alloc & dealloc from UD recv data path

Smith, Stan stan.smith at intel.com
Tue Nov 9 10:10:18 PST 2010


Hello,
  Enclosed you will find a technology preview patch implementing Fab's suggestions about removing NETWORK_BUFFER_LIST and MDL allocation and deallocation for every UD receive operation; now allocated/deallocated in recv_pool constructor & destructor routines.
The results is approximately a 3 Mbyte/sec transfer rate increase; less than I had envisioned although good nonetheless.  There are bigger fish to fry in the send/recv data paths.
The patch is done with #if UD_NBL_IN_DESC to highlight the changes and make comparison testing easier; I would envision the final patch without the #if.

Details:
  Add NBL and MDL pointers to ipoib_recv_desc_t.
  Allocate NBL(h_packet_pool element) & MDL for recv_pool in recv_ctor()
     (allocate NBL pool before recv_pool) in buf_mgr_init().
  Added recv_dtor()for RECV_INLINE as NBL and MDL need to be deallocated.
  Destroy recv_pool before NBL pool as recv_dtor() needs to free NBL before h_packet_pool destroyed.

Let me know what you think.

thanks,

stan.

--- A/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h    Tue Nov 09 09:47:18 2010
+++ B/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h    Mon Nov 08 13:33:52 2010
@@ -365,6 +365,10 @@
        ipoib_pkt_type_t        type;
        ib_recv_wr_t            wr;
        ib_local_ds_t           local_ds[2];
+#if UD_NBL_IN_DESC
+       NET_BUFFER_LIST         *p_NBL;
+       MDL                             *p_mdl;
+#endif
        NDIS_TCP_IP_CHECKSUM_PACKET_INFO        ndis_csum;
 #if IPOIB_INLINE_RECV
        recv_buf_t                      buf;

--- A/ulp/ipoib_NDIS6_CM/kernel/SOURCES Tue Nov 09 09:46:50 2010
+++ B/ulp/ipoib_NDIS6_CM/kernel/SOURCES Tue Nov 09 09:45:59 2010
@@ -29,7 +29,8 @@
 INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;

 C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS_WDM=1 \
-       -DDEPRECATE_DDK_FUNCTIONS -DNDIS61_MINIPORT=1 -DNEED_CL_OBJ -DBINARY_COMPATIBLE=0
+       -DDEPRECATE_DDK_FUNCTIONS -DNDIS61_MINIPORT=1 -DNEED_CL_OBJ \
+       -DBINARY_COMPATIBLE=0 -DUD_NBL_IN_DESC=1

 TARGETLIBS= \
        $(TARGETPATH)\*\complib.lib \


--- A/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp  Tue Nov 09 09:47:45 2010
+++ B/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp  Tue Nov 09 09:47:18 2010
@@ -192,7 +192,7 @@
        IN                              void*                                           context,
                OUT                     cl_pool_item_t** const          pp_pool_item );

-#if !IPOIB_INLINE_RECV
+#if !IPOIB_INLINE_RECV || UD_NBL_IN_DESC
 static void
 __recv_dtor(
        IN              const   cl_pool_item_t* const           p_pool_item,
@@ -1410,6 +1410,9 @@
        IN                              ipoib_port_t* const                     p_port )
 {
        cl_status_t             cl_status;
+#if UD_NBL_IN_DESC
+       ib_api_status_t ib_status;
+#endif
        ipoib_params_t  *p_params;
        NET_BUFFER_LIST_POOL_PARAMETERS pool_parameters;

@@ -1420,6 +1423,55 @@

        p_params = &p_port->p_adapter->params;

+#if    UD_NBL_IN_DESC
+
+       /* Allocate the NET BUFFER list pools for receive indication. */
+       NdisZeroMemory(&pool_parameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
+    pool_parameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
+    pool_parameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
+    pool_parameters.Header.Size = sizeof(pool_parameters);
+    pool_parameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
+    pool_parameters.ContextSize = 0;
+    pool_parameters.fAllocateNetBuffer = TRUE;
+    pool_parameters.PoolTag = 'CRPI';
+       pool_parameters.DataSize = 0;
+
+    p_port->buf_mgr.h_packet_pool = NdisAllocateNetBufferListPool(
+                                                                                               p_port->p_adapter->h_adapter,
+                                                                                               &pool_parameters );
+
+       if( !p_port->buf_mgr.h_packet_pool )
+       {
+               NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,
+                       EVENT_IPOIB_RECV_PKT_POOL, 1, NDIS_STATUS_RESOURCES  );
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+                       ("NdisAllocatePacketPool returned %08X\n", (UINT)NDIS_STATUS_RESOURCES) );
+               return IB_INSUFFICIENT_RESOURCES;
+       }
+
+       /* Allocate the receive descriptor pool */
+       cl_status = cl_qpool_init( &p_port->buf_mgr.recv_pool,
+                                                          p_params->rq_depth * p_params->recv_pool_ratio,
+                                                          0,
+                                                          0,
+                                                          sizeof(ipoib_recv_desc_t),
+                                                          __recv_ctor,
+                                                          __recv_dtor,
+                                                          p_port );
+
+       if( cl_status != CL_SUCCESS )
+       {
+               NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,
+                       EVENT_IPOIB_RECV_POOL, 1, cl_status );
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+                       ("cl_qpool_init for recvs returned %#x\n",
+                       cl_status) );
+               ib_status = IB_INSUFFICIENT_MEMORY;
+               goto pkt_pool_failed;
+       }
+
+#else  !UD_NBL_IN_DESC
+
        /* Allocate the receive descriptor pool */
        cl_status = cl_qpool_init( &p_port->buf_mgr.recv_pool,
                                                           p_params->rq_depth * p_params->recv_pool_ratio,
@@ -1449,7 +1501,7 @@
     pool_parameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
     pool_parameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
     pool_parameters.Header.Size = sizeof(pool_parameters);
-    pool_parameters.ProtocolId = 0;
+    pool_parameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
     pool_parameters.ContextSize = 0;
     pool_parameters.fAllocateNetBuffer = TRUE;
     pool_parameters.PoolTag = 'CRPI';
@@ -1467,6 +1519,7 @@
                        ("NdisAllocatePacketPool returned %08X\n", (UINT)NDIS_STATUS_RESOURCES) );
                return IB_INSUFFICIENT_RESOURCES;
        }
+#endif

        /* Allocate the NET buffer list pool for send formatting. */
     pool_parameters.PoolTag = 'XTPI';
@@ -1481,11 +1534,31 @@
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
                        ("NdisAllocatePacketPool returned %08X\n",
                        (UINT)NDIS_STATUS_RESOURCES) );
+#if UD_NBL_IN_DESC
+               ib_status = IB_INSUFFICIENT_RESOURCES;
+               goto pkt_pool_failed;
+#else
                return IB_INSUFFICIENT_RESOURCES;
+#endif
        }

        IPOIB_EXIT( IPOIB_DBG_INIT );
        return IB_SUCCESS;
+
+#if UD_NBL_IN_DESC
+pkt_pool_failed:
+       NdisFreeNetBufferListPool( p_port->buf_mgr.h_packet_pool );
+       p_port->buf_mgr.h_packet_pool = NULL;
+       cl_qpool_destroy( &p_port->buf_mgr.recv_pool );
+       if( p_port->buf_mgr.h_send_pkt_pool)
+       {
+               NdisFreeNetBufferListPool( p_port->buf_mgr.h_send_pkt_pool );
+               p_port->buf_mgr.h_send_pkt_pool = NULL;
+       }
+
+       IPOIB_EXIT( IPOIB_DBG_INIT );
+       return ib_status;
+#endif
 }


@@ -1506,11 +1579,19 @@
        /* Destroy the receive packet and buffer pools.
        if( p_port->buf_mgr.h_buffer_pool )
                NdisFreeBufferPool( p_port->buf_mgr.h_buffer_pool );*/
+#if UD_NBL_IN_DESC
+       /* Free the receive and send descriptors. */
+       cl_qpool_destroy( &p_port->buf_mgr.recv_pool );
+
+       if( p_port->buf_mgr.h_packet_pool )
+               NdisFreeNetBufferListPool ( p_port->buf_mgr.h_packet_pool );
+#else
        if( p_port->buf_mgr.h_packet_pool )
                NdisFreeNetBufferListPool ( p_port->buf_mgr.h_packet_pool );

        /* Free the receive and send descriptors. */
        cl_qpool_destroy( &p_port->buf_mgr.recv_pool );
+#endif

        /* Free the lookaside list of scratch buffers. */
        NdisDeleteNPagedLookasideList( &p_port->buf_mgr.send_buf_list );
@@ -1592,14 +1673,65 @@
        p_desc->wr.num_ds = 1;
 #endif /* IPOIB_INLINE_RECV */

+#if    UD_NBL_IN_DESC
+       /* setup NDIS NetworkBufferList and MemoryDescriptorList for this Recv desc */
+       p_desc->p_mdl = NdisAllocateMdl(p_port->p_adapter->h_adapter,
+#if IPOIB_INLINE_RECV
+                                                                       &p_desc->buf.eth.pkt,
+#else
+                                                                       p_desc->p_buf,
+#endif
+                                                                       sizeof(ipoib_pkt_t) + sizeof(ib_grh_t) );
+       if( !p_desc->p_mdl )
+       {
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+                       ("Failed to allocate MDL\n") );
+               goto err1;
+       }
+
+       p_desc->p_NBL = NdisAllocateNetBufferAndNetBufferList(
+                                               p_port->buf_mgr.h_packet_pool,
+                                               0,
+                                               0,
+                                               p_desc->p_mdl,
+                                               0,
+                                               0);
+
+       if( !p_desc->p_NBL )
+       {
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
+                       ("Failed to allocate NET_BUFFER_LIST\n") );
+               goto err2;
+       }
+
+       NET_BUFFER_LIST_NEXT_NBL(p_desc->p_NBL) = NULL;
+       IPOIB_PORT_FROM_NBL( p_desc->p_NBL ) = p_port;
+       IPOIB_RECV_FROM_NBL( p_desc->p_NBL ) = p_desc;
+       p_desc->p_NBL->SourceHandle = p_port->p_adapter->h_adapter;
+#endif
+
        *pp_pool_item = &p_desc->item;

        IPOIB_EXIT( IPOIB_DBG_ALLOC );
        return CL_SUCCESS;
-}

+#if UD_NBL_IN_DESC
+err2:
+       NdisFreeMdl( p_desc->p_mdl );
+       p_desc->p_mdl = NULL;

+err1:
 #if !IPOIB_INLINE_RECV
+       cl_free( p_desc->p_buf );
+       p_desc->p_buf = NULL;
+#endif
+
+       return CL_INSUFFICIENT_MEMORY;
+#endif
+}
+
+
+#if !IPOIB_INLINE_RECV || UD_NBL_IN_DESC
 static void
 __recv_dtor(
        IN              const   cl_pool_item_t* const           p_pool_item,
@@ -1607,16 +1739,27 @@
 {
        ipoib_recv_desc_t       *p_desc;

-       IPOIB_ENTER(  IPOIB_DBG_ALLOC );
-
        UNUSED_PARAM( context );

        p_desc = PARENT_STRUCT( p_pool_item, ipoib_recv_desc_t, item );

+#if UD_NBL_IN_DESC
+       if( p_desc->p_mdl )
+       {
+               NdisFreeMdl( p_desc->p_mdl );
+               p_desc->p_mdl = NULL;
+       }
+       if( p_desc->p_NBL)
+       {
+               NdisFreeNetBufferList(p_desc->p_NBL);
+               p_desc->p_NBL = NULL;
+       }
+#endif
+
+#if !IPOIB_INLINE_RECV
        if( p_desc->p_buf )
                cl_free( p_desc->p_buf );
-
-       IPOIB_EXIT( IPOIB_DBG_ALLOC );
+#endif
 }
 #endif

@@ -1657,12 +1800,29 @@
        IN                              ipoib_recv_desc_t* const        p_desc,
        IN                              NET_BUFFER_LIST* const          p_net_buffer_list OPTIONAL )
 {
-       NET_BUFFER              *p_buf = NULL;
-       MDL                             *p_mdl = NULL;
        IPOIB_ENTER(IPOIB_DBG_RECV );

        if( p_net_buffer_list )
        {
+               NET_BUFFER      *p_buf = NULL;
+               MDL                     *p_mdl = NULL;
+#if UD_NBL_IN_DESC
+               ASSERT( p_desc->p_NBL );
+               ASSERT( p_desc->p_mdl );
+               ASSERT( p_net_buffer_list == p_desc->p_NBL );
+
+               NET_BUFFER_LIST_NEXT_NBL(p_net_buffer_list) = NULL;
+
+               p_buf = NET_BUFFER_LIST_FIRST_NB( p_net_buffer_list );
+               p_mdl = NET_BUFFER_FIRST_MDL( p_buf );
+
+               ASSERT( p_mdl == p_desc->p_mdl );
+               ASSERT( NET_BUFFER_CURRENT_MDL( p_buf ) == p_mdl );
+
+               /* reset Avail buffer lengths to full Rx size */
+               NET_BUFFER_DATA_LENGTH( p_buf ) = sizeof(ipoib_pkt_t) + sizeof(ib_grh_t);
+               NdisAdjustMdlLength( p_mdl, sizeof(ipoib_pkt_t) + sizeof(ib_grh_t) );
+#else
                NET_BUFFER_LIST_NEXT_NBL(p_net_buffer_list) = NULL;
                p_buf = NET_BUFFER_LIST_FIRST_NB(p_net_buffer_list);
                CL_ASSERT( p_buf );
@@ -1670,6 +1830,7 @@
                CL_ASSERT( p_mdl );
                NdisFreeMdl(p_mdl);
                NdisFreeNetBufferList(p_net_buffer_list);
+#endif
        }

        /* Return the descriptor to its pools. */
@@ -1701,7 +1862,25 @@
        MDL                                             *p_mdl;

        IPOIB_ENTER(  IPOIB_DBG_RECV );
+#if UD_NBL_IN_DESC
+       PNET_BUFFER                     NetBuffer;
+       UNREFERENCED_PARAMETER(p_port);
+
+       IPOIB_ENTER( IPOIB_DBG_BUF );
+
+       ASSERT( p_desc->p_NBL );
+       ASSERT( p_desc->p_mdl );
+       p_net_buffer_list = p_desc->p_NBL;
+
+       NetBuffer = NET_BUFFER_LIST_FIRST_NB( p_net_buffer_list );
+       p_mdl = NET_BUFFER_FIRST_MDL( NetBuffer );
+
+       ASSERT( p_mdl == p_desc->p_mdl );
+       ASSERT( NET_BUFFER_CURRENT_MDL( NetBuffer ) == p_mdl );

+       NET_BUFFER_DATA_LENGTH( NetBuffer ) = p_desc->len;
+       NdisAdjustMdlLength( p_mdl, p_desc->len );
+#else  // !UD_NBL_IN_DESC
        p_mdl = NdisAllocateMdl(p_port->p_adapter->h_adapter,
                                                        &p_desc->buf.eth.pkt,
                                                        p_desc->len );
@@ -1732,6 +1911,7 @@
        IPOIB_PORT_FROM_NBL( p_net_buffer_list ) = p_port;
        IPOIB_RECV_FROM_NBL( p_net_buffer_list ) = p_desc;
        p_net_buffer_list->SourceHandle = p_port->p_adapter->h_adapter;
+#endif // !UD_NBL_IN_DESC

        IPOIB_EXIT(  IPOIB_DBG_RECV );
        return p_net_buffer_list;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: SOURCES.patch
Type: application/octet-stream
Size: 631 bytes
Desc: SOURCES.patch
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20101109/0ed9cb95/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ipoib_port.cpp.patch
Type: application/octet-stream
Size: 9465 bytes
Desc: ipoib_port.cpp.patch
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20101109/0ed9cb95/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ipoib_port.h.patch
Type: application/octet-stream
Size: 534 bytes
Desc: ipoib_port.h.patch
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20101109/0ed9cb95/attachment-0002.obj>


More information about the ofw mailing list