<!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>