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