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