<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.2873" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=544355221-07052006>Hi 
Fab,</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=544355221-07052006>Attached is a patch 
that solves the posting of received packets when in the QP is in RST 
state.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=544355221-07052006>According to my 
checks it solves the problem, and it doesn't add any locking or Interlocked 
operations.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=544355221-07052006>(As always feel free 
to do cosmetic changes to the patch)</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006>Thanks</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006>Tzachi</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=544355221-07052006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=544355221-07052006>Index: 
ipoib_port.c<BR>===================================================================<BR>--- 
ipoib_port.c (revision 333)<BR>+++ ipoib_port.c (working copy)<BR>@@ 
-58,7 +58,6 @@<BR> #define MAX_SEND_WC  8<BR> #define 
MAX_RECV_WC  16<BR> <BR>-<BR> ib_gid_t bcast_mgid_template 
= {<BR>  0xff,        /* 
multicast field 
*/<BR>  0x12,        /* scope 
(to be filled in) */<BR>@@ -676,7 +675,8 @@<BR>  p_port = 
PARENT_STRUCT( p_obj, ipoib_port_t, obj );<BR> <BR>  /* Wait for 
all sends and receives to get flushed. */<BR>- while( 
p_port->send_mgr.depth || p_port->recv_mgr.depth )<BR>+ shutter_shut 
(&p_port->recv_mgr.shutter);<BR>+ while( p_port->send_mgr.depth 
)<BR>   cl_thread_suspend( 0 );<BR> <BR>  /* 
Destroy the send and receive managers before closing the CA. */<BR>@@ -1285,6 
+1285,7 @@<BR>    ("cl_malloc for PNDIS_PACKET array 
failed.\n") );<BR>   return 
IB_INSUFFICIENT_MEMORY;<BR>  }<BR>+ shutter_init(&p_port->recv_mgr.shutter);<BR> <BR>  IPOIB_EXIT( 
IPOIB_DBG_INIT );<BR>  return IB_SUCCESS;<BR>@@ -1298,7 +1299,6 
@@<BR>  IPOIB_ENTER( IPOIB_DBG_INIT 
);<BR> <BR>  CL_ASSERT( cl_is_qlist_empty( 
&p_port->recv_mgr.done_list ) );<BR>- CL_ASSERT( 
!p_port->recv_mgr.depth );<BR> <BR>  if( 
p_port->recv_mgr.recv_pkt_array )<BR>   cl_free( 
p_port->recv_mgr.recv_pkt_array );<BR>@@ -1316,6 +1316,7 
@@<BR>  ipoib_recv_desc_t *p_head = NULL, *p_tail = NULL, 
*p_next;<BR>  ib_api_status_t  status;<BR>  ib_recv_wr_t  *p_failed;<BR>+ boolean_t   AllowToPost 
= TRUE;<BR>  PERF_DECLARE( GetRecv );<BR>  PERF_DECLARE( 
PostRecv );<BR> <BR>@@ -1336,10 +1337,19 @@<BR> <BR>  while( 
num_wrs-- )<BR>  {<BR>-  if( p_port->recv_mgr.depth == 
p_port->p_adapter->params.rq_depth )<BR>+  long depth = 
shutter_use(&p_port->recv_mgr.shutter);<BR>+  if (depth < 0) 
{<BR>+   IPOIB_TRACE( IPOIB_DBG_INFO | 
IPOIB_DBG_RECV,<BR>+    ("Already in shutdown\n") 
);<BR>+   AllowToPost = FALSE;<BR>+   // We will 
soon catch the state and fix 
it.<BR>+   break;<BR>+  }<BR>+  if( depth == 
p_port->p_adapter->params.rq_depth 
)<BR>   {<BR>    IPOIB_TRACE( IPOIB_DBG_INFO 
| IPOIB_DBG_RECV,<BR>     ("Receive queue already 
full\n") );<BR>+   shutter_loose(&p_port->recv_mgr.shutter 
, 1 );<BR>    break;<BR>   }<BR> <BR>@@ 
-1351,6 +1361,7 
@@<BR>   {<BR>    IPOIB_TRACE( IPOIB_DBG_INFO 
| IPOIB_DBG_RECV,<BR>     ("Out of receive 
descriptors!\n") 
);<BR>+   shutter_loose(&p_port->recv_mgr.shutter , 1 
);<BR>    break;<BR>   }<BR> <BR>@@ 
-1366,7 +1377,6 @@<BR> <BR>   p_head = 
p_next;<BR> <BR>-  cl_atomic_inc( &p_port->recv_mgr.depth 
);<BR>  }<BR> <BR>  if( !p_head )<BR>@@ -1376,11 
+1386,19 @@<BR>   return 
IB_SUCCESS;<BR>  }<BR> <BR>- cl_perf_start( PostRecv 
);<BR>- status = 
p_port->p_adapter->p_ifc->post_recv(<BR>-  p_port->ib_mgr.h_qp, 
&p_head->wr, &p_failed );<BR>- cl_perf_stop( 
&p_port->p_adapter->perf, PostRecv );<BR>-<BR>+ if (AllowToPost 
== FALSE) <BR>+ {<BR>+  // Shutdown has happened, need to close 
all objects and leave<BR>+  status = 
IB_CANCELED;<BR>+  p_failed = &p_head->wr;<BR>+ } 
<BR>+ else <BR>+ {<BR>+  cl_perf_start( PostRecv 
);<BR>+  status = 
p_port->p_adapter->p_ifc->post_recv(<BR>+   p_port->ib_mgr.h_qp, 
&p_head->wr, &p_failed );<BR>+  cl_perf_stop( 
&p_port->p_adapter->perf, PostRecv 
);<BR>+ }<BR>  /*<BR>   * If we failed, fix up the work 
completion list and return those<BR>   * buffers to the pool<BR>@@ 
-1397,7 +1415,7 @@<BR>    p_failed = 
p_failed->p_next;<BR> <BR>    __buf_mgr_put_recv( 
p_port, p_head, NULL );<BR>-   cl_atomic_dec( 
&p_port->recv_mgr.depth 
);<BR>+   shutter_loose(&p_port->recv_mgr.shutter , 1 
);<BR>   }<BR>  }<BR> <BR>@@ -1558,7 +1576,7 
@@<BR>  cl_atomic_dec( &p_port->endpt_rdr 
);<BR> <BR>  /* Update our posted depth. 
*/<BR>- cl_atomic_sub( &p_port->recv_mgr.depth, recv_cnt 
);<BR>+ shutter_loose(&p_port->recv_mgr.shutter , recv_cnt 
);<BR> <BR>  cl_perf_start( BuildPktArray );<BR>  /* 
Notify NDIS of any and all possible receive buffers. */<BR>@@ -4419,8 +4437,7 
@@<BR>  IPOIB_ENTER( IPOIB_DBG_INIT );<BR> <BR>  /* 
Wait for all receives to get flushed. */<BR>- while( 
p_port->recv_mgr.depth )<BR>-  cl_thread_suspend( 0 
);<BR>+ shutter_shut(&p_port->recv_mgr.shutter); <BR> <BR>  p_port->state 
= IB_QPS_RTS;<BR> <BR>@@ -5082,6 +5099,7 
@@<BR>  }<BR> <BR>  /* Prepost receives. 
*/<BR>+ shutter_init(&p_port->recv_mgr.shutter);<BR>  cl_spinlock_acquire( 
&p_port->recv_lock );<BR>  __recv_mgr_repost( p_port, 
p_port->p_adapter->params.rq_depth );<BR>  cl_spinlock_release( 
&p_port->recv_lock );<BR>Index: 
ipoib_port.h<BR>===================================================================<BR>--- 
ipoib_port.h (revision 333)<BR>+++ ipoib_port.h (working copy)<BR>@@ 
-42,8 +42,10 @@<BR> #include "ip_packet.h"<BR> #include 
"ipoib_endpoint.h"<BR> #include "ipoib_xfr_mgr.h"<BR>+#include 
"ipoib_shutter.h"<BR> <BR> <BR>+<BR> /*<BR>  * Define to 
place receive buffer inline in receive descriptor.<BR>  */<BR>@@ -406,7 
+408,7 @@<BR> <BR> typedef struct 
_ipoib_recv_mgr<BR> {<BR>- atomic32_t  depth;<BR>+ shutter_t  shutter;<BR> <BR>  NDIS_PACKET  **recv_pkt_array;<BR> <BR>Index: 
ipoib_shutter.h<BR>===================================================================<BR>--- 
ipoib_shutter.h (revision 0)<BR>+++ ipoib_shutter.h (revision 0)<BR>@@ 
-0,0 +1,102 @@<BR>+/*<BR>+ * Copyright (c) 2005 SilverStorm Technologies.  
All rights reserved.<BR>+ *<BR>+ * This software is available to you under the 
OpenIB.org BSD license<BR>+ * below:<BR>+ *<BR>+ *     
Redistribution and use in source and binary forms, with or<BR>+ 
*     without modification, are permitted provided that the 
following<BR>+ *     conditions are met:<BR>+ *<BR>+ 
*      - Redistributions of source code must retain the 
above<BR>+ *        copyright notice, this 
list of conditions and the following<BR>+ 
*        disclaimer.<BR>+ *<BR>+ 
*      - Redistributions in binary form must reproduce 
the above<BR>+ *        copyright notice, 
this list of conditions and the following<BR>+ 
*        disclaimer in the documentation 
and/or other materials<BR>+ *        provided 
with the distribution.<BR>+ *<BR>+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT 
WARRANTY OF ANY KIND,<BR>+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
THE WARRANTIES OF<BR>+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 
AND<BR>+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
HOLDERS<BR>+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 
AN<BR>+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN<BR>+ 
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<BR>+ * 
SOFTWARE.<BR>+ *<BR>+ * $Id: ipoib_shutter.h 10 2005-05-24 00:33:03Z ftillier 
$<BR>+ */<BR>+<BR>+<BR>+<BR>+#ifndef _IPOIB_SHUTTER_H_<BR>+#define 
_IPOIB_SHUTTER_H_<BR>+<BR>+<BR>+<BR>+<BR>+/*<BR>+ * Define the max numbers of 
operations that can be simultaniously done<BR>+ */<BR>+#define 
MAX_OPERATIONS 0x10000000<BR>+<BR>+typedef struct _shutter_t 
{<BR>+ long opertaions;<BR>+<BR>+} shutter_t;<BR>+<BR>+static inline 
void shutter_init(shutter_t* p_shutter)<BR>+{<BR>+ p_shutter->opertaions 
= 0;<BR>+}<BR>+<BR>+static inline int shutter_use(shutter_t * 
p_shutter)<BR>+{<BR>+ long res;<BR>+ res = 
InterlockedExchangeAdd(&p_shutter->opertaions, 1); <BR>+ ASSERT(res 
< MAX_OPERATIONS);<BR>+ if (res >= 0 ) {<BR>+  // 
Everything went OK, we can do the operation<BR>+  return 
res;<BR>+ }<BR>+ // The object was already 
shutdown<BR>+ InterlockedExchangeAdd(&p_shutter->opertaions, -1); 
<BR>+ return -1;<BR>+}<BR>+<BR>+static inline void shutter_loose(shutter_t 
* p_shutter, long 
count)<BR>+{<BR>+ InterlockedExchangeAdd(&p_shutter->opertaions, 
-count); <BR>+}<BR>+<BR>+static inline void shutter_shut(shutter_t * 
p_shutter)<BR>+{<BR>+ // Mark the counter as locked<BR>+ long 
res;<BR>+ LARGE_INTEGER interval;<BR>+ res = 
InterlockedExchangeAdd(&p_shutter->opertaions, 
-MAX_OPERATIONS);<BR>+ if (res == 0) <BR>+ {<BR>+  // The 
object had no user, quit<BR>+  return;<BR>+ }<BR>+ if (res 
<= -MAX_OPERATIONS)<BR>+ {<BR>+  // This probably means that 
we have another bug, but I want to give this<BR>+  // a chance 
(someone has already started to shut) 
?????????<BR>+  InterlockedExchangeAdd(&p_shutter->opertaions, 
MAX_OPERATIONS);<BR>+ }<BR>+ // We now wait for the object to reach to 
-MAX_OPERATIONS<BR>+ interval.QuadPart = 0;<BR>+ for(;;) 
{<BR>+  res = InterlockedExchangeAdd(&p_shutter->opertaions, 
0);<BR>+  if (res == -MAX_OPERATIONS) 
{<BR>+   return;<BR>+  }<BR>+  KeDelayExecutionThread( 
KernelMode, FALSE, &interval );<BR>+ }<BR>+}<BR>+<BR>+#endif 
_IPOIB_SHUTTER_H_<BR></SPAN></FONT></DIV></BODY></HTML>