diff options
author | Allan Stephens <allan.stephens@windriver.com> | 2008-04-15 03:22:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-15 03:22:02 -0400 |
commit | 0c3141e910eaaa0b617e2f26c69b266d1cd1f035 (patch) | |
tree | 53b9f635b8dc2bf82d49e2d29f6e07677fa4811e /net/tipc/port.c | |
parent | b89741a0cc162511b4341c07e17e1bd4c8b4621d (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.c | 31 |
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 | |||
1249 | int 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: | |||
1248 | int tipc_disconnect(u32 ref) | 1270 | int 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 | } |