<!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 orders the spinlocks to 
avoid deadlock.<BR>Send lock can't be invoked after port object was 
locked.<BR>It creates classic dedlock:<BR>Thread 1: wait(A); wait(B)<BR>Thread 
2: wait(B); wait(A)</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>@@ -3243,14 +3294,8 
@@<BR> {<BR>  cl_list_item_t  *p_item;<BR>  ipoib_send_NB_SG 
 *s_buf;<BR>- ULONG    send_complete_flags = 
0;<BR>+ ULONG    send_complete_flags = 
NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL;<BR> <BR>- if 
(KeGetCurrentIrql() == 
DISPATCH_LEVEL)<BR>- {<BR>-  NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, 
NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);<BR>- } 
<BR>-<BR>- cl_spinlock_acquire( &p_port->send_lock 
);<BR>  /* Complete any pending packets. */<BR>  for( p_item 
= cl_qlist_remove_head( &p_port->send_mgr.pending_list 
);<BR>   p_item != cl_qlist_end( 
&p_port->send_mgr.pending_list );<BR>@@ -3260,13 +3305,10 
@@<BR>   ASSERT(s_buf->p_port == 
p_port);<BR>   ASSERT(s_buf->p_nbl);<BR> <BR>-  <BR>+  //TODO<BR>   //__send_complete_net_buffer(s_buf, 
NDIS_STATUS_RESET_IN_PROGRESS,send_complete_flags,TRUE);<BR>   __send_complete_net_buffer(s_buf, 
NDIS_STATUS_FAILURE,send_complete_flags,TRUE);<BR>  }<BR>-<BR>-<BR>- cl_spinlock_release( 
&p_port->send_lock );<BR>   <BR> }<BR> <BR>@@ -3278,7 
+3320,9 @@<BR>  //Destroy pending list and put all the send buffers 
back to pool<BR>  //The list should be already destroyed at this 
point<BR>  ASSERT(p_port->send_mgr.pending_list.count == 
0);<BR>+ cl_spinlock_acquire( &p_port->send_lock 
);<BR>  __pending_list_destroy(p_port);<BR>+ cl_spinlock_release( 
&p_port->send_lock );<BR> <BR>  // Now, destroy the send 
pool<BR>  cl_qpool_destroy(&p_port->send_mgr.send_pool);<BR>@@ 
-5299,7 +5343,6 @@<BR>   //TODO Tzachid: make an assert here to 
validate your IRQL<BR>   ASSERT (KeGetCurrentIrql() == 
DISPATCH_LEVEL);<BR>   old_irql = 
DISPATCH_LEVEL;<BR>-  NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, 
NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);<BR>  } else 
{<BR>   NDIS_RAISE_IRQL_TO_DISPATCH(&old_irql);<BR>   //ASSERT 
(KeGetCurrentIrql() == PASSIVE_LEVEL); // Happens<BR>@@ -7158,6 +7201,7 
@@<BR>   * object lock since that is the order taken when 
reposting.<BR>   */<BR>  cl_spinlock_acquire( 
&p_port->recv_lock );<BR>+ cl_spinlock_acquire( 
&p_port->send_lock );<BR>  cl_obj_lock( &p_port->obj 
);<BR>  p_port->state = IB_QPS_ERROR;<BR> <BR>@@ -7172,6 
+7216,7 @@<BR>   p_port->ib_mgr.h_query = 
NULL;<BR>  }<BR>  cl_obj_unlock( &p_port->obj 
);<BR>+ cl_spinlock_release( &p_port->send_lock 
);<BR>  cl_spinlock_release( &p_port->recv_lock 
);<BR> <BR>  KeWaitForSingleObject(<BR></FONT></DIV></BODY></HTML>