tipc: fix deadlock during socket release
authorYing Xue <ying.xue@windriver.com>
Fri, 27 Dec 2013 02:18:28 +0000 (10:18 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 30 Dec 2013 03:24:07 +0000 (22:24 -0500)
commit84602761ca4495dd409be936dfa93ed20c946684
tree5936e501cc24cc66cf298a8e6713cbb04b4427b0
parent8eb9bff0edefcce50116ec50397a60dd626022d6
tipc: fix deadlock during socket release

A deadlock might occur if name table is withdrawn in socket release
routine, and while packets are still being received from bearer.

       CPU0                       CPU1
T0:   recv_msg()               release()
T1:   tipc_recv_msg()          tipc_withdraw()
T2:   [grab node lock]         [grab port lock]
T3:   tipc_link_wakeup_ports() tipc_nametbl_withdraw()
T4:   [grab port lock]*        named_cluster_distribute()
T5:   wakeupdispatch()         tipc_link_send()
T6:                            [grab node lock]*

The opposite order of holding port lock and node lock on above two
different paths may result in a deadlock. If socket lock instead of
port lock is used to protect port instance in tipc_withdraw(), the
reverse order of holding port lock and node lock will be eliminated,
as a result, the deadlock is killed as well.

Reported-by: Lars Everbrand <lars.everbrand@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/tipc/port.c
net/tipc/port.h
net/tipc/socket.c