aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/port.c
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2008-04-15 03:22:02 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-15 03:22:02 -0400
commit0c3141e910eaaa0b617e2f26c69b266d1cd1f035 (patch)
tree53b9f635b8dc2bf82d49e2d29f6e07677fa4811e /net/tipc/port.c
parentb89741a0cc162511b4341c07e17e1bd4c8b4621d (diff)
[TIPC]: Overhaul of socket locking logic
This patch modifies TIPC's socket code to follow the same approach used by other protocols. This change eliminates the need for a mutex in the TIPC-specific portion of the socket protocol data structure -- in its place, the standard Linux socket backlog queue and associated locking routines are utilized. These changes fix a long-standing receive queue bug on SMP systems, and also enable individual read and write threads to utilize a socket without unnecessarily interfering with each other. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/port.c')
-rw-r--r--net/tipc/port.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c
index e2646a96935d..2f5806410c64 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -1240,6 +1240,28 @@ exit:
1240 return res; 1240 return res;
1241} 1241}
1242 1242
1243/**
1244 * tipc_disconnect_port - disconnect port from peer
1245 *
1246 * Port must be locked.
1247 */
1248
1249int tipc_disconnect_port(struct tipc_port *tp_ptr)
1250{
1251 int res;
1252
1253 if (tp_ptr->connected) {
1254 tp_ptr->connected = 0;
1255 /* let timer expire on it's own to avoid deadlock! */
1256 tipc_nodesub_unsubscribe(
1257 &((struct port *)tp_ptr)->subscription);
1258 res = TIPC_OK;
1259 } else {
1260 res = -ENOTCONN;
1261 }
1262 return res;
1263}
1264
1243/* 1265/*
1244 * tipc_disconnect(): Disconnect port form peer. 1266 * tipc_disconnect(): Disconnect port form peer.
1245 * This is a node local operation. 1267 * This is a node local operation.
@@ -1248,17 +1270,12 @@ exit:
1248int tipc_disconnect(u32 ref) 1270int tipc_disconnect(u32 ref)
1249{ 1271{
1250 struct port *p_ptr; 1272 struct port *p_ptr;
1251 int res = -ENOTCONN; 1273 int res;
1252 1274
1253 p_ptr = tipc_port_lock(ref); 1275 p_ptr = tipc_port_lock(ref);
1254 if (!p_ptr) 1276 if (!p_ptr)
1255 return -EINVAL; 1277 return -EINVAL;
1256 if (p_ptr->publ.connected) { 1278 res = tipc_disconnect_port((struct tipc_port *)p_ptr);
1257 p_ptr->publ.connected = 0;
1258 /* let timer expire on it's own to avoid deadlock! */
1259 tipc_nodesub_unsubscribe(&p_ptr->subscription);
1260 res = TIPC_OK;
1261 }
1262 tipc_port_unlock(p_ptr); 1279 tipc_port_unlock(p_ptr);
1263 return res; 1280 return res;
1264} 1281}