[ofw] [patch][IPoIB_NDIS6_CM] Deadlock fix

Alex Naslednikov xalex at mellanox.co.il
Wed Feb 2 01:58:56 PST 2011


Fix a deadlock between the send lock and the port lock
Currently the code that completes the send packets is not called under  lock.
Signed off by: Tzachi Dar (tzachi at mellanox.co.il)
Index: ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp
===================================================================
--- ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp             (revision 3088)
+++ ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp          (working copy)
@@ -4169,12 +4169,14 @@
                ipoib_adapter_t                               *p_adapter;
                KLOCK_QUEUE_HANDLE              hdl;
                ipoib_state_t                     prev_state;
+             cl_qlist_t              complete_list;

                UNREFERENCED_PARAMETER( pause_parameters );
                IPOIB_ENTER( IPOIB_DBG_INIT );

                CL_ASSERT( adapter_context );
                p_adapter = (ipoib_adapter_t*)adapter_context;
+             cl_qlist_init(&complete_list);

                KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
                prev_state = p_adapter->ipoib_state;
@@ -4187,8 +4189,9 @@
                if( p_adapter->p_port )
                {
                                cl_spinlock_acquire( &p_adapter->p_port->send_lock );
-                              ipoib_port_resume( p_adapter->p_port,FALSE );
+                             ipoib_port_resume( p_adapter->p_port,FALSE, &complete_list );
                                cl_spinlock_release( &p_adapter->p_port->send_lock );
+                             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());
                }
                if ( prev_state == IPOIB_RUNNING ) { //i.e there was no active reset
                                IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,
Index: ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp
===================================================================
--- ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp                (revision 3088)
+++ ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp             (working copy)
@@ -397,9 +397,7 @@
 static inline void
 __send_complete_net_buffer(
                IN           ipoib_send_NB_SG        *s_buf,
-              IN           NDIS_STATUS                    status,
-              IN           ULONG                                                 compl_flags,
-              IN           boolean_t                                           bLock    );
+             IN           ULONG                                                 compl_flags);

 static inline NDIS_STATUS
 __send_mgr_queue(
@@ -992,12 +990,14 @@
                IN                                                           cl_obj_t* const                                                 p_obj )
 {
                ipoib_port_t      *p_port;
+             cl_qlist_t              complete_list;

                IPOIB_ENTER( IPOIB_DBG_INIT );

                CL_ASSERT( p_obj );

                p_port = PARENT_STRUCT( p_obj, ipoib_port_t, obj );
+             cl_qlist_init(&complete_list);

                ipoib_port_down( p_port );

@@ -1012,8 +1012,9 @@
                }

                cl_spinlock_acquire(&p_port->send_lock);
-              ipoib_port_resume( p_port, FALSE );
+             ipoib_port_resume( p_port, FALSE, &complete_list );
                cl_spinlock_release(&p_port->send_lock);
+             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());

                dmp_ipoib_port_refs( p_port, "port_destroying()" );

@@ -3878,6 +3879,8 @@
                cl_qlist_init( &p_port->send_mgr.pending_list );
                cl_qpool_construct(&p_port->send_mgr.sg_pool);
                cl_qpool_construct( &p_port->send_mgr.send_pool );
+             cl_spinlock_construct(&p_port->send_mgr.send_pool_lock);
+
                p_port->p_desc = NULL;
 }

@@ -3934,6 +3937,8 @@
                                cl_qpool_destroy(&p_port->send_mgr.sg_pool);
                                return IB_INSUFFICIENT_MEMORY;
                }
+
+             cl_spinlock_init(&p_port->send_mgr.send_pool_lock);

                //This send descriptor can't be allocated on the stack because of boundary
                // violation !!!
@@ -3949,20 +3954,58 @@
                                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
                                                ("Allocation of port[%d] send descriptor failed\n", p_port->port_num) );
                                cl_qpool_destroy(&p_port->send_mgr.send_pool);
+
+                             cl_spinlock_destroy(&p_port->send_mgr.send_pool_lock);
                                cl_qpool_destroy(&p_port->send_mgr.sg_pool);
                                return IB_INSUFFICIENT_MEMORY;
                }
                return IB_SUCCESS;
 }

+static void
+__send_complete_add_to_list(
+             IN                                                           cl_qlist_t                                                                              *p_complete_list,
+             IN                                                           ipoib_send_NB_SG                                                                        *s_buf,
+             IN           NDIS_STATUS                    status)
+{

+    NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = status;
+    cl_qlist_insert_tail(p_complete_list, &s_buf->p_complete_list_item);
+}
+
+// Complete the entire list
+void
+send_complete_list_complete(
+             IN                                                           cl_qlist_t                                                                              *p_complete_list,
+             IN                                                           ULONG                                                                                 compl_flags)
+{
+             cl_list_item_t                    *p_item;
+             ipoib_send_NB_SG        *s_buf;
+
+             KIRQL oldIrql = DISPATCH_LEVEL;
+             if ( (compl_flags & NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL) == 0 )
+             {
+                NDIS_RAISE_IRQL_TO_DISPATCH(&oldIrql);
+             }
+             ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+             for( p_item = cl_qlist_remove_head( p_complete_list );
+                             p_item != cl_qlist_end( p_complete_list );
+                             p_item = cl_qlist_remove_head( p_complete_list ) )
+             {
+                             s_buf = CONTAINING_RECORD(p_item, ipoib_send_NB_SG, p_complete_list_item);
+                             __send_complete_net_buffer(s_buf, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
+             }
+             NDIS_LOWER_IRQL(oldIrql, DISPATCH_LEVEL);
+
+}
 static void
 __pending_list_destroy(
-              IN                                                           ipoib_port_t* const                                        p_port )
+             IN                                                           ipoib_port_t* const                                        p_port,
+             IN                                                           cl_qlist_t                                                                              *p_complete_list)
 {
                cl_list_item_t                    *p_item;
                ipoib_send_NB_SG        *s_buf;
-              ULONG                                                 send_complete_flags = NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL;

                /* Complete any pending packets. */
                for( p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list );
@@ -3973,9 +4016,7 @@
                                ASSERT(s_buf->p_port == p_port);
                                ASSERT(s_buf->p_nbl);

-                              //TODO
-                              //__send_complete_net_buffer(s_buf, NDIS_STATUS_RESET_IN_PROGRESS,send_complete_flags,TRUE);
-                              __send_complete_net_buffer(s_buf, NDIS_STATUS_FAILURE,send_complete_flags,TRUE);
+                             __send_complete_add_to_list(p_complete_list  ,s_buf, NDIS_STATUS_FAILURE);
                }
 }

@@ -3983,16 +4024,21 @@
 __send_mgr_destroy(
                IN                                                           ipoib_port_t* const                                        p_port )
 {
+             cl_qlist_t              complete_list;
+
                IPOIB_ENTER( IPOIB_DBG_SEND );
                //Destroy pending list and put all the send buffers back to pool
                //The list should be already destroyed at this point
                ASSERT(p_port->send_mgr.pending_list.count == 0);
+             cl_qlist_init(&complete_list);
                cl_spinlock_acquire( &p_port->send_lock );
-              __pending_list_destroy(p_port);
+             __pending_list_destroy(p_port, &complete_list);
                cl_spinlock_release( &p_port->send_lock );
+             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());

                // Now, destroy the send pool
                cl_qpool_destroy(&p_port->send_mgr.send_pool);
+             cl_spinlock_destroy(&p_port->send_mgr.send_pool_lock);
                cl_qpool_destroy(&p_port->send_mgr.sg_pool);

                //Now, free port send descriptor
@@ -4579,10 +4625,12 @@

 bool
 ipoib_process_sg_list_real(
-    IN  PDEVICE_OBJECT          pDO,
-    IN  PVOID                   pIrp,
-    IN  PSCATTER_GATHER_LIST    p_sgl,
-    IN  PVOID                   context )
+             IN           PDEVICE_OBJECT                                             pDO,
+             IN           PVOID                                                                   pIrp,
+             IN           PSCATTER_GATHER_LIST              p_sgl,
+             IN           PVOID                                                                   context,
+             IN           cl_qlist_t                                                              *p_complete_list
+             )
 {
                NDIS_STATUS                                                    status;
                ipoib_port_t                                      *p_port;
@@ -4657,7 +4705,8 @@
                                /* fail  net buffer */
                                IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
                                                                                ("Failed to get Eth hdr - send inside process SG list\n"));
-                              __send_complete_net_buffer(s_buf, status, complete_flags, TRUE);
+                             __send_complete_add_to_list(p_complete_list  ,s_buf, status);
+

                                cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );
                                ret = true;
@@ -4724,11 +4773,8 @@
                                                IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
                                                                                ("Bad status: packet has not been sent\n"));
                                                cl_perf_start( ProcessFailedSends );
+                                             __send_complete_add_to_list(p_complete_list  ,s_buf, NDIS_STATUS_SUCCESS);

-                                              __send_complete_net_buffer(                s_buf,
-                                                                                                                                                              NDIS_STATUS_SUCCESS,
-                                                                                                                                                              complete_flags,
-                                                                                                                                                              TRUE );
                                                ret = true;
                                                goto send_end;
                                }
@@ -4819,12 +4865,8 @@
                                                 * sends to fail.
                                                 */
                                                 //TODO - check previous comment !
-                                              cl_perf_start( ProcessFailedSends );
-                                              __send_complete_net_buffer( s_buf,
-                                                                                                                                                              NDIS_STATUS_SUCCESS,
-                                                                                                                                                              complete_flags,
-                                                                                                                                                              TRUE );
-                                              cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );
+                                             __send_complete_add_to_list(p_complete_list  ,s_buf,NDIS_STATUS_SUCCESS );
+
                                                ret = true;
                                                goto send_end;
                                }
@@ -4841,7 +4883,7 @@
                if( status != NDIS_STATUS_SUCCESS )
                {
                                cl_perf_start( ProcessFailedSends );
-                              __send_complete_net_buffer(s_buf, NDIS_STATUS_FAILURE, complete_flags, TRUE);
+                             __send_complete_add_to_list(p_complete_list  ,s_buf, NDIS_STATUS_FAILURE);
                                cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );
                                ret = true;
                                goto send_end;
@@ -4885,7 +4927,7 @@
                                                                (p_desc->send_qp == p_port->ib_mgr.h_qp ? "UD":"RC"),
                                                                p_port->p_adapter->p_ifc->get_err_str( ib_status )) );
                                cl_perf_start( ProcessFailedSends );
-                              __send_complete_net_buffer(s_buf, NDIS_STATUS_FAILURE, complete_flags, TRUE);
+                             __send_complete_add_to_list(p_complete_list  ,s_buf, NDIS_STATUS_FAILURE);
                                cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );
                                if( p_desc->send_qp == p_port->ib_mgr.h_qp )
                                {
@@ -4929,6 +4971,8 @@
 {
                ipoib_send_NB_SG *  s_buf = (ipoib_send_NB_SG *)context;
                ipoib_port_t*                    p_port = s_buf->p_port;
+             cl_qlist_t              complete_list;
+             cl_qlist_init(&complete_list);

                cl_spinlock_acquire( &p_port->send_lock );

@@ -4942,7 +4986,7 @@
 #endif
                }

-              ipoib_process_sg_list_real( pDO, pIrp, p_sgl, context );
+             ipoib_process_sg_list_real( pDO, pIrp, p_sgl, context, &complete_list );

                if (g_ipoib_send_SG > 1) {
 #if 0
@@ -4953,6 +4997,7 @@
 #endif
                }
                cl_spinlock_release( &p_port->send_lock );
+             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());
 }


@@ -6620,15 +6665,17 @@
                {
                                p_next_netbuf = NET_BUFFER_NEXT_NB(p_netbuf);

+                             cl_spinlock_acquire(&p_port->send_mgr.send_pool_lock);
                                ipoib_send_NB_SG * s_buf = (ipoib_send_NB_SG*) (PVOID)
                                                                                                                                                (cl_qpool_get(&p_port->send_mgr.send_pool));
+                             cl_spinlock_release(&p_port->send_mgr.send_pool_lock);
                                if (s_buf == NULL)
                                {
                                                ASSERT(FALSE);
                                                NET_BUFFER_LIST_STATUS(p_net_buffer_list) = NDIS_STATUS_RESOURCES;
                                                NdisMSendNetBufferListsCompleteX( p_port->p_adapter,
                                                                                                                                                                                  p_net_buffer_list,
-                                                                                                                                                                                send_complete_flags );
+                                                                                                                                                                               send_complete_flags );
                                                break;
                                }

@@ -6660,6 +6707,8 @@

                                ++g_ipoib_send_SW_in_loop;

+                             ++g_ipoib_send_SW_in_loop;
+
                                status = NdisMAllocateNetBufferSGList(
                                                                                                                p_port->p_adapter->NdisMiniportDmaHandle,
                                                                                                                p_netbuf,
@@ -6668,7 +6717,6 @@
                                                                                                                (PUCHAR )s_buf->p_sg_buf + sizeof(cl_pool_item_t),
                                                                                                                p_port->p_adapter->sg_list_size);

-                              cl_spinlock_acquire( &p_port->send_lock );

                                if( status != NDIS_STATUS_SUCCESS )
                                {
@@ -6682,9 +6730,11 @@
                                                NET_BUFFER_LIST_STATUS(p_net_buffer_list) = status;
                                                NdisMSendNetBufferListsCompleteX( p_port->p_adapter,
                                                                                                                                                                                  p_net_buffer_list,
-                                                                                                                                                                                send_complete_flags );
+                                                                                                                                                                               send_complete_flags );
+                                             cl_spinlock_acquire( &p_port->send_lock );
                                                break;
                                }
+                             cl_spinlock_acquire( &p_port->send_lock );
                }

                cl_spinlock_release( &p_port->send_lock );
@@ -6694,17 +6744,17 @@
                XIPOIB_EXIT( IPOIB_DBG_SEND );
 }

+
 static inline void
 __send_complete_net_buffer(
                IN           ipoib_send_NB_SG        *s_buf,
-              IN           NDIS_STATUS                    status,
-              IN           ULONG                                                 compl_flags,
-              IN           boolean_t                                           bLock )
+             IN           ULONG                                                 compl_flags )
 {
                PERF_DECLARE( FreeSendBuf );
                PERF_DECLARE( SendComp );

                CL_ASSERT( s_buf );
+

                IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_BUF,
                                ("Processing send completion for NBL %p s_buf %p\n",
@@ -6729,10 +6779,7 @@
                }
 #endif

-              NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = status;
-
-              switch (status)
-              {
+             switch (NET_BUFFER_LIST_STATUS(s_buf->p_nbl)) {
                                case NDIS_STATUS_SUCCESS:
                                                ++g_ipoib_send_ack;
                                                break;
@@ -6754,7 +6801,6 @@
                /* Complete the NBL */
                if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0)
                {
-                              NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = status;
                                PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO pLsoInfo =
                                                (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)
                                                                (PULONG)&NET_BUFFER_LIST_INFO(s_buf->p_nbl, TcpLargeSendNetBufferListInfo);
@@ -6777,16 +6823,7 @@
                        pLsoInfo->LsoV2TransmitComplete.Type = NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE;
                    }

-                              if (bLock)
-                              {
-                                              cl_spinlock_release( &s_buf->p_port->send_lock );
-                                              NdisMSendNetBufferListsCompleteX( s_buf->p_port->p_adapter,
-                                                              s_buf->p_nbl, compl_flags );
-                                              cl_spinlock_acquire( &s_buf->p_port->send_lock );
-                              } else {
-                                              NdisMSendNetBufferListsCompleteX( s_buf->p_port->p_adapter,
-                                                              s_buf->p_nbl, compl_flags );
-                              }
+                             NdisMSendNetBufferListsCompleteX( s_buf->p_port->p_adapter,         s_buf->p_nbl, compl_flags );
                }

                if( s_buf->p_send_buf )
@@ -6813,7 +6850,9 @@
                }
 #endif
                //Put back into the pool list structure allocated for the NB
+             cl_spinlock_acquire(&s_buf->p_port->send_mgr.send_pool_lock);
                cl_qpool_put(&s_buf->p_port->send_mgr.send_pool, (cl_pool_item_t* )s_buf);
+             cl_spinlock_release(&s_buf->p_port->send_mgr.send_pool_lock);

                cl_perf_stop( &s_buf->p_port->p_adapter->perf, SendComp );
 }
@@ -6834,7 +6873,8 @@
 void
 ipoib_port_resume(
                IN                                                           ipoib_port_t* const                                        p_port,
-              IN boolean_t                                                                                                                     b_pending )
+             IN boolean_t                                                                                                                     b_pending,
+             IN           cl_qlist_t                                                                                                                              *p_complete_list)
 {
                cl_list_item_t                    *p_item;
                ipoib_send_NB_SG        *s_buf = NULL;
@@ -6875,8 +6915,7 @@
                                {
                                                // Port is in error state, flush the list
                                                ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_DROPPED, 0 );
-                                              __send_complete_net_buffer( s_buf, NDIS_STATUS_FAILURE,
-                                                                                                              NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL, TRUE);
+                                             __send_complete_add_to_list(p_complete_list  ,s_buf, NDIS_STATUS_FAILURE);
                                } else {
                                                /* Check the send queue and pend the request if not empty. */
                                                if( p_port->send_mgr.depth == p_port->p_adapter->params.sq_depth )
@@ -6887,11 +6926,11 @@
                                                                break;
                                                }

-                                              continue_sending = ipoib_process_sg_list_real(
-                                                                                                                                                                              NULL,
-                                                                                                                                                                              NULL,
-                                                                                                                                                                              (PSCATTER_GATHER_LIST) s_buf->p_sgl,
-                                                                                                                                                                              s_buf );
+                                             bool continue_sending = ipoib_process_sg_list_real(     NULL,
+                                                                                                                                                                                                                                                             NULL,
+                                                                                                                                                                                                                                                             (PSCATTER_GATHER_LIST) s_buf->p_sgl,
+                                                                                                                                                                                                                                                             s_buf,
+                                                                                                                                                                                                                                                             p_complete_list);

                                                //cl_qlist_check_validity(&p_port->send_mgr.pending_list);

@@ -6931,6 +6970,7 @@
                ip_stat_sel_t                     type;
                NET_BUFFER                                      *p_netbuffer = NULL;
                ipoib_send_NB_SG        *s_buf;
+             cl_qlist_t                                              complete_list;

                PERF_DECLARE( SendCompBundle );
                PERF_DECLARE( SendCb );
@@ -6941,6 +6981,7 @@

                IPOIB_ENTER( IPOIB_DBG_SEND );

+             cl_qlist_init(&complete_list);
                ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);

                cl_perf_clr( SendCompBundle );
@@ -7031,12 +7072,8 @@

                                                                break;
                                                }
+                                             __send_complete_add_to_list(&complete_list  ,s_buf, status);

-                                              __send_complete_net_buffer( s_buf,
-                                                                                                                                                              status,
-                                                                                                                                                              NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL,
-                                                                                                                                                              TRUE );
-
                                                cl_atomic_dec( &p_port->send_mgr.depth );

                                                p_wc = p_wc->p_next;
@@ -7048,7 +7085,7 @@

                /* Resume any sends awaiting resources. */
                cl_perf_start( PortResume );
-              ipoib_port_resume( p_port, TRUE );
+             ipoib_port_resume( p_port, TRUE, &complete_list );
                cl_perf_stop( &p_port->p_adapter->perf, PortResume );

                /* Rearm the CQ. */
@@ -7063,6 +7100,7 @@
                cl_perf_update_ctr( &p_port->p_adapter->perf, SendCompBundle );
                //cl_qlist_check_validity(&p_port->send_mgr.pending_list);
                cl_spinlock_release( &p_port->send_lock );
+             send_complete_list_complete(&complete_list, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
                IPOIB_EXIT( IPOIB_DBG_SEND );
 }

@@ -8360,8 +8398,11 @@
 {
                ib_api_status_t                                status;
                ib_qp_mod_t                                    qp_mod;
+             cl_qlist_t              complete_list;

                IPOIB_ENTER( IPOIB_DBG_INIT );
+
+             cl_qlist_init(&complete_list);

                /*
                 * Mark our state.  This causes all callbacks to abort.
@@ -8382,7 +8423,7 @@

                p_port->state = IB_QPS_ERROR;

-              __pending_list_destroy(p_port);
+             __pending_list_destroy(p_port, &complete_list);

                NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter, EVENT_IPOIB_PORT_DOWN, 0 );

@@ -8395,6 +8436,7 @@
                cl_obj_unlock( &p_port->obj );
                cl_spinlock_release( &p_port->send_lock );
                cl_spinlock_release( &p_port->recv_lock );
+             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());

                KeWaitForSingleObject( &p_port->sa_event,
                                                                                                   Executive,
@@ -8887,10 +8929,12 @@
                ipoib_port_t                      *p_port;
                cl_fmap_item_t                               *p_item;
                ipoib_endpt_t                   *p_endpt;
+             cl_qlist_t              complete_list;

                IPOIB_ENTER( IPOIB_DBG_MCAST );

                p_port = (ipoib_port_t*)p_mcast_rec->mcast_context;
+             cl_qlist_init(&complete_list);

                cl_obj_lock( &p_port->obj );
                while( p_port->endpt_rdr )
@@ -8913,11 +8957,11 @@
                                                ("Invalid state - Aborting.\n") );
                                IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
                                                ("Invalid state - Aborting.\n") );
-
                                cl_spinlock_acquire(&p_port->send_lock);
                                //ipoib_port_resume(p_port , FALSE);
-                              __pending_list_destroy( p_port );
+                             __pending_list_destroy( p_port, &complete_list );
                                cl_spinlock_release(&p_port->send_lock);
+                             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());
                                return;
                }

@@ -8988,8 +9032,9 @@
                cl_spinlock_acquire( &p_port->send_lock );
                IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,
                                ("Calling ipoib_port_resume from mcast_cb, xmit pending sends\n"));
-              ipoib_port_resume(p_port , FALSE);
+             ipoib_port_resume(p_port , FALSE, &complete_list);
                cl_spinlock_release( &p_port->send_lock );
+             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());

                ipoib_port_deref( p_port, ref_join_mcast );

@@ -9300,10 +9345,10 @@
                cl_list_item_t                    *p_item, *p_next;
                ipoib_send_NB_SG        *s_buf;
                PVOID                                   nbl_id;
-              cl_qlist_t                              cancel_list;
+             cl_qlist_t                              complete_list;
                IPOIB_ENTER( IPOIB_DBG_SEND );

-              cl_qlist_init( &cancel_list );
+             cl_qlist_init( &complete_list );

                ASSERT(FALSE); //TODO ???????????????? Do we reach here ????????????

@@ -9321,27 +9366,12 @@
                                if( nbl_id == cancel_id )
                                {
                                                cl_qlist_remove_item( &p_port->send_mgr.pending_list, p_item );
-                                              NET_BUFFER_LIST_STATUS( s_buf->p_nbl) = NDIS_STATUS_REQUEST_ABORTED ;
-                                              cl_qlist_insert_tail( &cancel_list, (cl_list_item_t *) s_buf );
+                                             __send_complete_add_to_list(&complete_list                ,s_buf, NDIS_STATUS_REQUEST_ABORTED);
                                }
                }
                cl_spinlock_release( &p_port->send_lock );

-              if( cl_qlist_count( &cancel_list ) )
-              {
-                              while( ( p_item = cl_qlist_remove_head( &cancel_list ))
-                                                                                                                              != cl_qlist_end( &cancel_list ))
-                              {
-                                              s_buf = (ipoib_send_NB_SG*) (PVOID) p_item;
-                                              IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl);
-
-
-                                              //TODO don't use DISPATCH LEVEL
-                                              __send_complete_net_buffer( s_buf, NDIS_STATUS_SEND_ABORTED,
-                                                                                                                              NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL, TRUE);
-                              }
-
-              }
+             send_complete_list_complete(&complete_list, IRQL_TO_COMPLETE_FLAG());
                IPOIB_EXIT( IPOIB_DBG_SEND );
 }

Index: ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h
===================================================================
--- ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h     (revision 3080)
+++ ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h  (working copy)
@@ -620,6 +620,7 @@
                atomic32_t                                         depth;
                cl_qlist_t                                              pending_list;
                cl_qpool_t                                          send_pool;
+             cl_spinlock_t                      send_pool_lock;
                cl_qpool_t                                          sg_pool;

 }             ipoib_send_mgr_t;
@@ -842,6 +843,7 @@
                PSCATTER_GATHER_LIST              p_sgl;
                UINT                                                                      tcp_payload;
                PVOID                                                                   p_sg_buf;
+             cl_list_item_t                                    p_complete_list_item;
 } ipoib_send_NB_SG;
 /*
 * FIELDS
@@ -925,7 +927,8 @@
 void
 ipoib_port_resume(
                IN                                                           ipoib_port_t* const                                        p_port,
-              IN boolean_t                                                                                                                     b_pending );
+             IN boolean_t                                                                                                                     b_pending,
+             IN           cl_qlist_t                                                                                                                              *p_complete_list);

 NTSTATUS
 ipoib_mac_to_gid(
@@ -1088,7 +1091,16 @@
                }
 }

+VOID
+send_complete_list_complete(
+             IN                                                           cl_qlist_t                                                                              *p_complete_list,
+             IN                                                           ULONG                                                                                 compl_flags);

+#define IRQL_TO_COMPLETE_FLAG() KeGetCurrentIrql() == DISPATCH_LEVEL ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0
+
+
+
+
 // This function is only used to monitor send failures
 extern ULONG g_NBL_complete;
 extern ULONG g_NBL;
Alexander (XaleX) Naslednikov
SW Networking Team
Mellanox Technologies

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20110202/bb5285e5/attachment.html>


More information about the ofw mailing list