aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/port.h
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2013-12-26 21:18:28 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-29 22:24:07 -0500
commit84602761ca4495dd409be936dfa93ed20c946684 (patch)
tree5936e501cc24cc66cf298a8e6713cbb04b4427b0 /net/tipc/port.h
parent8eb9bff0edefcce50116ec50397a60dd626022d6 (diff)
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>
Diffstat (limited to 'net/tipc/port.h')
-rw-r--r--net/tipc/port.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 912253597343..34f12bd4074e 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -116,7 +116,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err);
116 116
117void tipc_acknowledge(u32 port_ref, u32 ack); 117void tipc_acknowledge(u32 port_ref, u32 ack);
118 118
119int tipc_deleteport(u32 portref); 119int tipc_deleteport(struct tipc_port *p_ptr);
120 120
121int tipc_portimportance(u32 portref, unsigned int *importance); 121int tipc_portimportance(u32 portref, unsigned int *importance);
122int tipc_set_portimportance(u32 portref, unsigned int importance); 122int tipc_set_portimportance(u32 portref, unsigned int importance);
@@ -127,9 +127,9 @@ int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
127int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); 127int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
128int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); 128int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
129 129
130int tipc_publish(u32 portref, unsigned int scope, 130int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
131 struct tipc_name_seq const *name_seq); 131 struct tipc_name_seq const *name_seq);
132int tipc_withdraw(u32 portref, unsigned int scope, 132int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
133 struct tipc_name_seq const *name_seq); 133 struct tipc_name_seq const *name_seq);
134 134
135int tipc_connect(u32 portref, struct tipc_portid const *port); 135int tipc_connect(u32 portref, struct tipc_portid const *port);