<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=us-ascii" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.6001.18702"></HEAD>
<BODY>
<DIV><FONT color=#0000ff size=2 face=Arial>This patches introduces SHUTTER Data 
Structure to avoid stop <BR>receiving packets during IPoIB shutdown.<BR>The 
problem was discovered by WHQL NDIS 6.5 MPE test</FONT></DIV>
<DIV> </DIV>
<DIV><FONT color=#0000ff size=2 face=Arial>Signed-off by: Alexander Naslednikov 
(xalex at mellanox.com), <BR>      Tzachi Dar (tzachid 
at mellanox.com)<BR>Index: 
ipoib_adapter.cpp<BR>===================================================================<BR>--- 
ipoib_adapter.cpp (revision 5452)<BR>+++ ipoib_adapter.cpp (working 
copy)<BR>@@ -393,6 +393,8 @@<BR>   return 
status;<BR>  }<BR> <BR>+ shutter_init(&p_adapter->recv_shutter);<BR>+<BR>  IPOIB_EXIT( 
IPOIB_DBG_INIT );<BR>  return status;<BR> }<BR>Index: 
ipoib_adapter.h<BR>===================================================================<BR>--- 
ipoib_adapter.h (revision 5452)<BR>+++ ipoib_adapter.h (working 
copy)<BR>@@ -47,8 +47,10 @@<BR> #include 
<ip_packet.h><BR> #include "ip_stats.h"<BR> #include 
"ipoib_stat.h"<BR>+#include 
"shutter.h"<BR> <BR> <BR>+<BR> /*<BR>  * 
Definitions<BR>  */<BR>@@ -238,6 +240,9 
@@<BR>  ULONG     n_send_NBL;   // 
number of send NBLs, gotten from 
NDIS<BR>  ULONG     n_send_NBL_done; // 
number of send NBLs, 
completed<BR> <BR>+ //<BR>+ shutter_t               
recv_shutter;<BR>+<BR> } ipoib_adapter_t;<BR> /*<BR> * 
FIELDS<BR>Index: 
ipoib_driver.cpp<BR>===================================================================<BR>--- 
ipoib_driver.cpp (revision 5452)<BR>+++ ipoib_driver.cpp (working 
copy)<BR>@@ -3111,7 +3111,6 @@<BR> <BR>  CL_ASSERT( 
adapter_context );<BR>  p_adapter = 
(ipoib_adapter_t*)adapter_context;<BR>- p_port = 
p_adapter->p_port;<BR> <BR>  cl_obj_lock( 
&p_adapter->obj );<BR>  if( p_adapter->ipoib_state == 
IPOIB_PAUSING ||<BR>@@ -3239,9 +3238,17 @@<BR>  IN NDIS_HANDLE  
adapter_context,<BR>  IN NDIS_SHUTDOWN_ACTION  
shutdown_action)<BR> {<BR>- IPOIB_ENTER( IPOIB_DBG_INIT 
);<BR>- UNUSED_PARAM( adapter_context );<BR>+ IPOIB_ENTER( 
IPOIB_DBG_INIT ) ;<BR>  UNUSED_PARAM( shutdown_action 
);<BR>+ <BR>+ ipoib_adapter_t *p_adapter = (ipoib_adapter_t *) 
adapter_context;<BR>+ <BR>+ if (shutdown_action == 
NdisShutdownPowerOff ) {<BR>+  ASSERT(KeGetCurrentIrql() == 
PASSIVE_LEVEL);<BR>+  // We need to wait only if this is not a blue 
screen any way<BR>+  shutter_shut ( &p_adapter->recv_shutter 
);<BR>+ }<BR>+<BR>  IPOIB_EXIT( IPOIB_DBG_INIT 
);<BR> }<BR> <BR>@@ -3940,9 +3947,9 
@@<BR>  p_adapter->ipoib_state = 
IPOIB_PAUSING;<BR>  KeReleaseInStackQueuedSpinLock( &hdl 
);<BR>  <BR>+ shutter_shut ( &p_adapter->recv_shutter 
);<BR>+ <BR>  if (p_adapter->p_port) {<BR>-  //TODO 
improve this flow !<BR>-  //TODO Be sure we stopped all sends and 
receives<BR>   cl_spinlock_acquire( 
&p_adapter->p_port->send_lock 
);<BR>   ipoib_port_resume(p_adapter->p_port,FALSE);<BR>   cl_spinlock_release( 
&p_adapter->p_port->send_lock );<BR>@@ -3978,6 +3985,10 
@@<BR>         
//<BR>         // Check to see if we 
need to change any attributes<BR>     
}<BR>+ <BR>+ if (p_adapter->ipoib_state == IPOIB_PAUSED) 
{<BR>+  shutter_alive( &p_adapter->recv_shutter 
);<BR>+ }<BR> <BR>  KeAcquireInStackQueuedSpinLock( 
&g_ipoib.lock, &hdl );<BR>  p_adapter->ipoib_state = 
IPOIB_RUNNING;<BR>Index: 
ipoib_port.cpp<BR>===================================================================<BR>--- 
ipoib_port.cpp (revision 5452)<BR>+++ ipoib_port.cpp (working 
copy)<BR>@@ -824,7 +824,12 @@<BR>  IPOIB_PRINT( TRACE_LEVEL_ERROR, 
IPOIB_DBG_OBJ,<BR>   ("ref type %d ref_cnt %d\n", ref_init, 
p_port->obj.ref_cnt) );<BR> #endif<BR>-<BR>+    // The 
port is started as paused and NDIS calls latter to ipoib_restart. 
We<BR>+    // shut the recv_shuter for now and alive it on 
ipoib_restart. We did<BR>+    // it in this way since 
MpInitializeInternal also calls in reset and than<BR>+    // we 
need to set the rec ref count to 1 //TODO !!!!!!!!!!1<BR>+    
//<BR>+ shutter_shut 
(&p_adapter->recv_shutter);<BR>  IPOIB_EXIT( IPOIB_DBG_INIT 
);<BR>  return IB_SUCCESS;<BR> }<BR>@@ -1843,45 +1848,28 
@@<BR>  return p_port->p_adapter->params.rq_low_watermark - 
p_port->recv_mgr.depth;<BR> }<BR> <BR>-void<BR>-ipoib_return_net_buffer_list(<BR>- IN    NDIS_HANDLE     adapter_context,<BR>- IN    NET_BUFFER_LIST    *p_net_buffer_lists,<BR>- IN    ULONG      return_flags)<BR>+inline 
ULONG __free_received_NBL (<BR>+ IN 
ipoib_port_t  *p_port,<BR>+ IN NET_BUFFER_LIST 
 *p_net_buffer_lists<BR>+ ) 
<BR> {<BR>- ipoib_port_t  *p_port;<BR>+<BR>  ipoib_recv_desc_t *p_desc;<BR>- NET_BUFFER_LIST  *cur_net_buffer_list,*next_net_buffer_list;<BR>- int32_t    shortage;<BR>+ NET_BUFFER_LIST  *cur_net_buffer_list, 
*next_net_buffer_list;<BR>+ LONG    NBL_cnt = 
0;<BR>+<BR>  <BR>- PERF_DECLARE( ReturnPacket 
);<BR>- PERF_DECLARE( ReturnPutRecv );<BR>- PERF_DECLARE( 
ReturnRepostRecv );<BR>- PERF_DECLARE( ReturnPreparePkt 
);<BR>- PERF_DECLARE( ReturnNdisIndicate );<BR>-<BR>- IPOIB_ENTER( 
IPOIB_DBG_RECV );<BR>-<BR>- UNUSED_PARAM( return_flags 
);<BR>-<BR>- p_port = 
((ipoib_adapter_t*)adapter_context)->p_port;<BR>- CL_ASSERT( 
p_net_buffer_lists );<BR>-<BR>- cl_perf_start( ReturnPacket 
);<BR>- cl_spinlock_acquire( &p_port->recv_lock 
);<BR>  for (cur_net_buffer_list = 
p_net_buffer_lists;<BR>    cur_net_buffer_list != 
NULL;<BR>    cur_net_buffer_list = 
next_net_buffer_list)<BR>  {<BR>+  ++NBL_cnt;<BR>   next_net_buffer_list 

NET_BUFFER_LIST_NEXT_NBL(cur_net_buffer_list);<BR> <BR>   /* 
Get the port and descriptor from the NET_BUFFER_LIST. 
*/<BR>   CL_ASSERT(p_port == IPOIB_PORT_FROM_NBL( 
cur_net_buffer_list ));<BR>   p_desc = IPOIB_RECV_FROM_NBL( 
cur_net_buffer_list );<BR>-<BR>   <BR>-  //TODO: 
NDIS60, rewrite this block<BR>-  <BR> #if 0 //TODO CM 
flow<BR>   if( p_desc->type == PKT_TYPE_CM_UCAST 
)<BR>   {<BR>@@ -1916,9 +1904,44 
@@<BR>   __buf_mgr_put_recv( p_port, p_desc, cur_net_buffer_list 
);<BR>   cl_perf_stop( &p_port->p_adapter->perf, 
ReturnPutRecv );<BR>  }<BR>+ return 
NBL_cnt;<BR>+}<BR> <BR>+void<BR>+ipoib_return_net_buffer_list(<BR>+ IN    NDIS_HANDLE     adapter_context,<BR>+ IN    NET_BUFFER_LIST    *p_net_buffer_lists,<BR>+ IN    ULONG      return_flags)<BR>+{<BR>+ ipoib_port_t  *p_port;<BR>+ int32_t    shortage;<BR>+ LONG    NBL_cnt 
= 0;<BR>+ <BR>+ PERF_DECLARE( ReturnPacket );<BR>+ PERF_DECLARE( 
ReturnPutRecv );<BR>+ PERF_DECLARE( ReturnRepostRecv 
);<BR>+ PERF_DECLARE( ReturnPreparePkt );<BR>+ PERF_DECLARE( 
ReturnNdisIndicate );<BR> <BR>+ IPOIB_ENTER( IPOIB_DBG_RECV 
);<BR> <BR>+ UNUSED_PARAM( return_flags );<BR>+ <BR>+ p_port 
= ((ipoib_adapter_t*)adapter_context)->p_port;<BR>+ CL_ASSERT( 
p_net_buffer_lists );<BR>+ if ( !p_port ) 
{<BR>+  ASSERT(p_port);<BR>+  IPOIB_PRINT_EXIT( 
TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("return_NBL callback 
called when port pointer was already cleared\n") 
);<BR>+  return;<BR>+ }<BR>+<BR>+ cl_perf_start( 
ReturnPacket );<BR>+ cl_spinlock_acquire( &p_port->recv_lock 
);<BR>+ NBL_cnt = __free_received_NBL( p_port, p_net_buffer_lists 
);<BR>+<BR>+ shutter_sub( &p_port->p_adapter->recv_shutter, 
-NBL_cnt );<BR>+<BR>  /* Repost buffers to HW 
*/<BR>  cl_perf_start( ReturnRepostRecv );<BR>  shortage = 
__recv_mgr_repost( p_port );<BR>@@ -1958,6 +1981,7 
@@<BR>  cl_qlist_t   done_list, 
bad_list;<BR>  size_t    i;<BR>  ULONG    recv_complete_flags 

0;<BR>+ BOOLEAN    res;<BR> <BR>  PERF_DECLARE( 
RecvCompBundle );<BR>  PERF_DECLARE( RecvCb );<BR>@@ -2069,13 +2093,40 
@@<BR> <BR>   cl_perf_start( RecvNdisIndicate 
);<BR>   <BR>-  NdisMIndicateReceiveNetBufferLists(<BR>-   p_port->p_adapter->h_adapter,<BR>-   p_port->recv_mgr.recv_NBL_array[0],<BR>-   NDIS_DEFAULT_PORT_NUMBER,<BR>-   NBL_cnt,<BR>-   recv_complete_flags);<BR>+  if 
(shortage <= 0) {<BR> <BR>+   res = shutter_add( 
&p_port->p_adapter->recv_shutter, NBL_cnt );<BR>+   if 
(res) 
{<BR>+    NdisMIndicateReceiveNetBufferLists(<BR>+     p_port->p_adapter->h_adapter,<BR>+     p_port->recv_mgr.recv_NBL_array[0],<BR>+     NDIS_DEFAULT_PORT_NUMBER,<BR>+     NBL_cnt,<BR>+     recv_complete_flags);<BR>+   }<BR>+   else 
{<BR>+    __free_received_NBL (p_port, 
p_port->recv_mgr.recv_NBL_array[0]);<BR>+   }<BR>+    <BR>+  } 
else {<BR>+  <BR>+   // If shortage >0, we already 
set the status to NDIS_RECEIVE_FLAGS_RESOURCES<BR>+   // That is, 
IPoIB driver regain ownership of the NET_BUFFER_LIST structures 
immediately<BR>+   res = shutter_add( 
&p_port->p_adapter->recv_shutter, 1 );<BR>+   if (res) 
{<BR>+    NdisMIndicateReceiveNetBufferLists(<BR>+     p_port->p_adapter->h_adapter,<BR>+     p_port->recv_mgr.recv_NBL_array[0],<BR>+     NDIS_DEFAULT_PORT_NUMBER,<BR>+     NBL_cnt,<BR>+     recv_complete_flags);<BR>+    shutter_sub( 
&p_port->p_adapter->recv_shutter, -1 
);<BR>+   }<BR>+   <BR>+  }<BR>+  <BR>+ <BR>+<BR>   cl_perf_stop( 
&p_port->p_adapter->perf, RecvNdisIndicate 
);<BR> <BR>   /*</FONT></DIV></BODY></HTML>