From 9fdf19d2e56275f7d9133ea1520a74d82ad1642e Mon Sep 17 00:00:00 2001 From: Stan Smith Date: Fri, 19 Feb 2010 18:13:20 +0000 Subject: [PATCH] [IPoIB_ndis6_cm] migrate IPoIB shutter code into the trunk - match 2.2 release. shutter code stops IPoIB from receiving packets during device shutdown. git-svn-id: svn://openib.tc.cornell.edu/gen1@2710 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- .../mlx4/kernel/inc => inc/kernel}/shutter.h | 0 .../ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp | 7 + .../ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h | 6 + .../ipoib_NDIS6_CM/kernel/ipoib_driver.cpp | 39 ++++- .../ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp | 148 ++++++++++++------ 5 files changed, 145 insertions(+), 55 deletions(-) rename trunk/{hw/mlx4/kernel/inc => inc/kernel}/shutter.h (100%) diff --git a/trunk/hw/mlx4/kernel/inc/shutter.h b/trunk/inc/kernel/shutter.h similarity index 100% rename from trunk/hw/mlx4/kernel/inc/shutter.h rename to trunk/inc/kernel/shutter.h diff --git a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp index c18dfee7..76973969 100644 --- a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp +++ b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp @@ -390,6 +390,13 @@ adapter_init( p_adapter->p_ifc->get_err_str( status )) ); return status; } + + + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, + ("Shutter Init, state = %d\n", p_adapter->ipoib_state) ); + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV, + ("Shutter Init, state = %d\n", p_adapter->ipoib_state) ); + shutter_init( &p_adapter->recv_shutter ); IPOIB_EXIT( IPOIB_DBG_INIT ); return status; diff --git a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h index c0718e9a..de28d977 100644 --- a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h +++ b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h @@ -47,6 +47,8 @@ #include #include "ip_stats.h" #include "ipoib_stat.h" +#include "shutter.h" + /* @@ -70,6 +72,7 @@ typedef enum typedef enum _ipoib_state { + IPOIB_INIT = -1, IPOIB_PAUSED, IPOIB_PAUSING, IPOIB_RUNNING @@ -238,6 +241,9 @@ typedef struct _ipoib_adapter ULONG n_send_NBL; // number of send NBLs, gotten from NDIS ULONG n_send_NBL_done; // number of send NBLs, completed + // + shutter_t recv_shutter; + } ipoib_adapter_t; /* * FIELDS diff --git a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp index fff1d6cc..cbe6cd9d 100644 --- a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp +++ b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp @@ -1862,7 +1862,7 @@ if(cl_get_time_stamp_sec() < 30) { ("ipoib_create_adapter returned status %d.\n", ib_status ) ); return NDIS_STATUS_FAILURE; } - p_adapter->ipoib_state = IPOIB_PAUSED; + p_adapter->ipoib_state = IPOIB_INIT; status = SetAttributes(p_adapter, h_adapter); if (status != NDIS_STATUS_SUCCESS) { @@ -3108,13 +3108,12 @@ ipoib_send_net_buffer_list( CL_ASSERT( adapter_context ); p_adapter = (ipoib_adapter_t*)adapter_context; - p_port = p_adapter->p_port; cl_obj_lock( &p_adapter->obj ); if( p_adapter->ipoib_state == IPOIB_PAUSING || p_adapter->ipoib_state == IPOIB_PAUSED) { - status = NDIS_STATUS_PAUSED; //NDIS_STATUS_PAUSED; + status = NDIS_STATUS_PAUSED; IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Got send during PAUSE, complete with error \n") ); cl_obj_unlock( &p_adapter->obj ); @@ -3236,9 +3235,21 @@ ipoib_shutdown_ex( IN NDIS_HANDLE adapter_context, IN NDIS_SHUTDOWN_ACTION shutdown_action) { - IPOIB_ENTER( IPOIB_DBG_INIT ); - UNUSED_PARAM( adapter_context ); + IPOIB_ENTER( IPOIB_DBG_INIT ) ; UNUSED_PARAM( shutdown_action ); + + ipoib_adapter_t *p_adapter = (ipoib_adapter_t *) adapter_context; + + if (shutdown_action == NdisShutdownPowerOff ) { + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + // We need to wait only if this is not a blue screen any way + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, + ("Shutter shut, state = %d\n", p_adapter->ipoib_state)); + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV, + ("Shutter shut, state = %d\n", p_adapter->ipoib_state)); + shutter_shut ( &p_adapter->recv_shutter ); + } + IPOIB_EXIT( IPOIB_DBG_INIT ); } @@ -3938,13 +3949,15 @@ ipoib_pause( KeReleaseInStackQueuedSpinLock( &hdl ); if (p_adapter->p_port) { - //TODO improve this flow ! - //TODO Be sure we stopped all sends and receives cl_spinlock_acquire( &p_adapter->p_port->send_lock ); ipoib_port_resume(p_adapter->p_port,FALSE); cl_spinlock_release( &p_adapter->p_port->send_lock ); } - + + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV, + ("Shutter shut, state = %d\n", p_adapter->ipoib_state)); + shutter_shut ( &p_adapter->recv_shutter ); + KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl ); p_adapter->ipoib_state = IPOIB_PAUSED; KeReleaseInStackQueuedSpinLock( &hdl ); @@ -3975,6 +3988,16 @@ ipoib_restart( // // Check to see if we need to change any attributes } + + if ( (p_adapter->ipoib_state == IPOIB_PAUSED) || (p_adapter->ipoib_state == IPOIB_INIT) ) { + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV, + ("Shutter Alive, ipoib_state = %d\n", p_adapter->ipoib_state)); + shutter_alive( &p_adapter->recv_shutter ); + } + else { + IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_RECV, + ("*****Shutter Was not \"Alived\", state = %d*****\n", p_adapter->ipoib_state)); + } KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl ); p_adapter->ipoib_state = IPOIB_RUNNING; diff --git a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp index df8d9bf2..a5c5aaca 100644 --- a/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp +++ b/trunk/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp @@ -824,7 +824,21 @@ __port_init( IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_OBJ, ("ref type %d ref_cnt %d\n", ref_init, p_port->obj.ref_cnt) ); #endif - + // The port is started as paused and NDIS calls latter to ipoib_restart. We + // shut the recv_shuter for now and alive it on ipoib_restart. We did + // it in this way since MpInitializeInternal also calls in reset and than + // we need to set the rec ref count to 1 //TODO !!!!!!!!!!1 + // + + if ( p_adapter->ipoib_state == IPOIB_INIT) { + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV, + ("Shutter shut, state = %d\n", p_adapter->ipoib_state)); + shutter_shut ( &p_adapter->recv_shutter ); + } + else { + IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_RECV, + ("*****Shutter wasn't shut, state = %d*****\n", p_adapter->ipoib_state)); + } IPOIB_EXIT( IPOIB_DBG_INIT ); return IB_SUCCESS; } @@ -1843,44 +1857,27 @@ __recv_mgr_repost( return p_port->p_adapter->params.rq_low_watermark - p_port->recv_mgr.depth; } -void -ipoib_return_net_buffer_list( - IN NDIS_HANDLE adapter_context, - IN NET_BUFFER_LIST *p_net_buffer_lists, - IN ULONG return_flags) +inline ULONG __free_received_NBL ( + IN ipoib_port_t *p_port, + IN NET_BUFFER_LIST *p_net_buffer_lists + ) { - ipoib_port_t *p_port; - ipoib_recv_desc_t *p_desc; - NET_BUFFER_LIST *cur_net_buffer_list,*next_net_buffer_list; - int32_t shortage; - - PERF_DECLARE( ReturnPacket ); - PERF_DECLARE( ReturnPutRecv ); - PERF_DECLARE( ReturnRepostRecv ); - PERF_DECLARE( ReturnPreparePkt ); - PERF_DECLARE( ReturnNdisIndicate ); - IPOIB_ENTER( IPOIB_DBG_RECV ); - - UNUSED_PARAM( return_flags ); - - p_port = ((ipoib_adapter_t*)adapter_context)->p_port; - CL_ASSERT( p_net_buffer_lists ); + ipoib_recv_desc_t *p_desc; + NET_BUFFER_LIST *cur_net_buffer_list, *next_net_buffer_list; + LONG NBL_cnt = 0; - cl_perf_start( ReturnPacket ); - cl_spinlock_acquire( &p_port->recv_lock ); + for (cur_net_buffer_list = p_net_buffer_lists; cur_net_buffer_list != NULL; cur_net_buffer_list = next_net_buffer_list) { + ++NBL_cnt; next_net_buffer_list = NET_BUFFER_LIST_NEXT_NBL(cur_net_buffer_list); /* Get the port and descriptor from the NET_BUFFER_LIST. */ CL_ASSERT(p_port == IPOIB_PORT_FROM_NBL( cur_net_buffer_list )); p_desc = IPOIB_RECV_FROM_NBL( cur_net_buffer_list ); - - - //TODO: NDIS60, rewrite this block #if 0 //TODO CM flow if( p_desc->type == PKT_TYPE_CM_UCAST ) @@ -1916,8 +1913,43 @@ ipoib_return_net_buffer_list( __buf_mgr_put_recv( p_port, p_desc, cur_net_buffer_list ); cl_perf_stop( &p_port->p_adapter->perf, ReturnPutRecv ); } + return NBL_cnt; +} +void +ipoib_return_net_buffer_list( + IN NDIS_HANDLE adapter_context, + IN NET_BUFFER_LIST *p_net_buffer_lists, + IN ULONG return_flags) +{ + ipoib_port_t *p_port; + int32_t shortage; + LONG NBL_cnt = 0; + + PERF_DECLARE( ReturnPacket ); + PERF_DECLARE( ReturnPutRecv ); + PERF_DECLARE( ReturnRepostRecv ); + PERF_DECLARE( ReturnPreparePkt ); + PERF_DECLARE( ReturnNdisIndicate ); + + IPOIB_ENTER( IPOIB_DBG_RECV ); + + UNUSED_PARAM( return_flags ); + + p_port = ((ipoib_adapter_t*)adapter_context)->p_port; + CL_ASSERT( p_net_buffer_lists ); + if ( !p_port ) { + ASSERT(p_port); + IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, + ("return_NBL callback called when port pointer was already cleared\n") ); + return; + } + + cl_perf_start( ReturnPacket ); + cl_spinlock_acquire( &p_port->recv_lock ); + NBL_cnt = __free_received_NBL( p_port, p_net_buffer_lists ); + shutter_sub( &p_port->p_adapter->recv_shutter, -NBL_cnt ); /* Repost buffers to HW */ cl_perf_start( ReturnRepostRecv ); @@ -1958,6 +1990,7 @@ __recv_cb( cl_qlist_t done_list, bad_list; size_t i; ULONG recv_complete_flags = 0; + BOOLEAN res; PERF_DECLARE( RecvCompBundle ); PERF_DECLARE( RecvCb ); @@ -2069,12 +2102,39 @@ __recv_cb( cl_perf_start( RecvNdisIndicate ); - NdisMIndicateReceiveNetBufferLists( - p_port->p_adapter->h_adapter, - p_port->recv_mgr.recv_NBL_array[0], - NDIS_DEFAULT_PORT_NUMBER, - NBL_cnt, - recv_complete_flags); + if (shortage <= 0) { + + res = shutter_add( &p_port->p_adapter->recv_shutter, NBL_cnt ); + if (res) { + NdisMIndicateReceiveNetBufferLists( + p_port->p_adapter->h_adapter, + p_port->recv_mgr.recv_NBL_array[0], + NDIS_DEFAULT_PORT_NUMBER, + NBL_cnt, + recv_complete_flags); + } + else { + __free_received_NBL (p_port, p_port->recv_mgr.recv_NBL_array[0]); + } + + } else { + + // If shortage >0, we already set the status to NDIS_RECEIVE_FLAGS_RESOURCES + // That is, IPoIB driver regain ownership of the NET_BUFFER_LIST structures immediately + res = shutter_add( &p_port->p_adapter->recv_shutter, 1 ); + if (res) { + NdisMIndicateReceiveNetBufferLists( + p_port->p_adapter->h_adapter, + p_port->recv_mgr.recv_NBL_array[0], + NDIS_DEFAULT_PORT_NUMBER, + NBL_cnt, + recv_complete_flags); + shutter_sub( &p_port->p_adapter->recv_shutter, -1 ); + } + + } + + cl_perf_stop( &p_port->p_adapter->perf, RecvNdisIndicate ); @@ -3243,14 +3303,8 @@ __pending_list_destroy( { cl_list_item_t *p_item; ipoib_send_NB_SG *s_buf; - ULONG send_complete_flags = 0; - - if (KeGetCurrentIrql() == DISPATCH_LEVEL) - { - NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL); - } + ULONG send_complete_flags = NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL; - cl_spinlock_acquire( &p_port->send_lock ); /* Complete any pending packets. */ for( p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list ); p_item != cl_qlist_end( &p_port->send_mgr.pending_list ); @@ -3260,13 +3314,10 @@ __pending_list_destroy( 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); } - - - cl_spinlock_release( &p_port->send_lock ); } @@ -3278,7 +3329,9 @@ __send_mgr_destroy( //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_spinlock_acquire( &p_port->send_lock ); __pending_list_destroy(p_port); + cl_spinlock_release( &p_port->send_lock ); // Now, destroy the send pool cl_qpool_destroy(&p_port->send_mgr.send_pool); @@ -5298,7 +5351,6 @@ ipoib_port_send( //TODO Tzachid: make an assert here to validate your IRQL ASSERT (KeGetCurrentIrql() == DISPATCH_LEVEL); old_irql = DISPATCH_LEVEL; - NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL); } else { NDIS_RAISE_IRQL_TO_DISPATCH(&old_irql); //ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); // Happens @@ -7157,6 +7209,7 @@ ipoib_port_down( * object lock since that is the order taken when reposting. */ cl_spinlock_acquire( &p_port->recv_lock ); + cl_spinlock_acquire( &p_port->send_lock ); cl_obj_lock( &p_port->obj ); p_port->state = IB_QPS_ERROR; @@ -7171,6 +7224,7 @@ ipoib_port_down( p_port->ib_mgr.h_query = NULL; } cl_obj_unlock( &p_port->obj ); + cl_spinlock_release( &p_port->send_lock ); cl_spinlock_release( &p_port->recv_lock ); KeWaitForSingleObject( @@ -7669,10 +7723,10 @@ __mcast_cb( IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST ,("Invalid state - Aborting.\n") ); IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT ,("Invalid state - Aborting.\n") ); - //cl_spinlock_acquire(&p_port->send_lock); + cl_spinlock_acquire(&p_port->send_lock); //ipoib_port_resume(p_port , FALSE); __pending_list_destroy( p_port ); - //cl_spinlock_release(&p_port->send_lock); + cl_spinlock_release(&p_port->send_lock); return; } -- 2.41.0