diff options
author | Jon Paul Maloy <jon.maloy@ericsson.com> | 2014-08-22 18:09:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-23 14:18:34 -0400 |
commit | dadebc00299a19dc4639ba7192db937e31b81eb2 (patch) | |
tree | e67049689659535bbe2d88f22f0a492d2a3064c3 /net/tipc | |
parent | 80e44c22255468337b891da2348cab68cb62766f (diff) |
tipc: eliminate port_connect()/port_disconnect() functions
tipc_port_connect()/tipc_port_disconnect() are remnants of the obsolete
native API. Their only task is to grab port_lock and call the functions
__tipc_port_connect()/__tipc_port_disconnect() respectively, which will
perform the actual state change.
Since socket/port exection now is single-threaded the use of port_lock
is not needed any more, so we can safely replace the two functions with
their lock-free counterparts.
In this commit, we remove the two functions. Furthermore, the contents
of __tipc_port_disconnect() is so trivial that we choose to eliminate
that function too, expanding its functionality into tipc_shutdown().
__tipc_port_connect() is simplified, moved to socket.c, and given the
more correct name tipc_sk_finish_conn(). Finally, we eliminate the
function auto_connect(), and expand its contents into filter_connect().
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/port.c | 84 | ||||
-rw-r--r-- | net/tipc/port.h | 10 | ||||
-rw-r--r-- | net/tipc/socket.c | 75 |
3 files changed, 37 insertions, 132 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index 3ad092b7fb7d..2f96719a3514 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -40,9 +40,6 @@ | |||
40 | #include "name_table.h" | 40 | #include "name_table.h" |
41 | #include "socket.h" | 41 | #include "socket.h" |
42 | 42 | ||
43 | /* Connection management: */ | ||
44 | #define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ | ||
45 | |||
46 | #define MAX_REJECT_SIZE 1024 | 43 | #define MAX_REJECT_SIZE 1024 |
47 | 44 | ||
48 | DEFINE_SPINLOCK(tipc_port_list_lock); | 45 | DEFINE_SPINLOCK(tipc_port_list_lock); |
@@ -304,84 +301,3 @@ int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, | |||
304 | p_ptr->published = 0; | 301 | p_ptr->published = 0; |
305 | return res; | 302 | return res; |
306 | } | 303 | } |
307 | |||
308 | int tipc_port_connect(u32 ref, struct tipc_portid const *peer) | ||
309 | { | ||
310 | struct tipc_port *p_ptr; | ||
311 | int res; | ||
312 | |||
313 | p_ptr = tipc_port_lock(ref); | ||
314 | if (!p_ptr) | ||
315 | return -EINVAL; | ||
316 | res = __tipc_port_connect(ref, p_ptr, peer); | ||
317 | tipc_port_unlock(p_ptr); | ||
318 | return res; | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | * __tipc_port_connect - connect to a remote peer | ||
323 | * | ||
324 | * Port must be locked. | ||
325 | */ | ||
326 | int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr, | ||
327 | struct tipc_portid const *peer) | ||
328 | { | ||
329 | struct tipc_msg *msg; | ||
330 | int res = -EINVAL; | ||
331 | |||
332 | if (p_ptr->published || p_ptr->connected) | ||
333 | goto exit; | ||
334 | if (!peer->ref) | ||
335 | goto exit; | ||
336 | |||
337 | msg = &p_ptr->phdr; | ||
338 | msg_set_destnode(msg, peer->node); | ||
339 | msg_set_destport(msg, peer->ref); | ||
340 | msg_set_type(msg, TIPC_CONN_MSG); | ||
341 | msg_set_lookup_scope(msg, 0); | ||
342 | msg_set_hdr_sz(msg, SHORT_H_SIZE); | ||
343 | |||
344 | p_ptr->probing_interval = PROBING_INTERVAL; | ||
345 | p_ptr->probing_state = TIPC_CONN_OK; | ||
346 | p_ptr->connected = 1; | ||
347 | k_start_timer(&p_ptr->timer, p_ptr->probing_interval); | ||
348 | res = tipc_node_add_conn(tipc_port_peernode(p_ptr), p_ptr->ref, | ||
349 | tipc_port_peerport(p_ptr)); | ||
350 | exit: | ||
351 | p_ptr->max_pkt = tipc_node_get_mtu(peer->node, ref); | ||
352 | return res; | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * __tipc_disconnect - disconnect port from peer | ||
357 | * | ||
358 | * Port must be locked. | ||
359 | */ | ||
360 | int __tipc_port_disconnect(struct tipc_port *tp_ptr) | ||
361 | { | ||
362 | if (tp_ptr->connected) { | ||
363 | tp_ptr->connected = 0; | ||
364 | /* let timer expire on it's own to avoid deadlock! */ | ||
365 | tipc_node_remove_conn(tipc_port_peernode(tp_ptr), tp_ptr->ref); | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | return -ENOTCONN; | ||
370 | } | ||
371 | |||
372 | /* | ||
373 | * tipc_port_disconnect(): Disconnect port form peer. | ||
374 | * This is a node local operation. | ||
375 | */ | ||
376 | int tipc_port_disconnect(u32 ref) | ||
377 | { | ||
378 | struct tipc_port *p_ptr; | ||
379 | int res; | ||
380 | |||
381 | p_ptr = tipc_port_lock(ref); | ||
382 | if (!p_ptr) | ||
383 | return -EINVAL; | ||
384 | res = __tipc_port_disconnect(p_ptr); | ||
385 | tipc_port_unlock(p_ptr); | ||
386 | return res; | ||
387 | } | ||
diff --git a/net/tipc/port.h b/net/tipc/port.h index f5762f940e33..b356cb8340d9 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h | |||
@@ -102,16 +102,6 @@ int tipc_publish(struct tipc_port *p_ptr, unsigned int scope, | |||
102 | int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, | 102 | int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, |
103 | struct tipc_name_seq const *name_seq); | 103 | struct tipc_name_seq const *name_seq); |
104 | 104 | ||
105 | int tipc_port_connect(u32 portref, struct tipc_portid const *port); | ||
106 | |||
107 | int tipc_port_disconnect(u32 portref); | ||
108 | |||
109 | /* | ||
110 | * The following routines require that the port be locked on entry | ||
111 | */ | ||
112 | int __tipc_port_disconnect(struct tipc_port *tp_ptr); | ||
113 | int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr, | ||
114 | struct tipc_portid const *peer); | ||
115 | int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg); | 105 | int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg); |
116 | 106 | ||
117 | struct sk_buff *tipc_port_get_ports(void); | 107 | struct sk_buff *tipc_port_get_ports(void); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f202d4790ce3..a65105818fe5 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #define SS_READY -2 /* socket is connectionless */ | 45 | #define SS_READY -2 /* socket is connectionless */ |
46 | 46 | ||
47 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 47 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ |
48 | #define CONN_PROBING_INTERVAL 3600000 /* [ms] => 1 h */ | ||
48 | #define TIPC_FWD_MSG 1 | 49 | #define TIPC_FWD_MSG 1 |
49 | 50 | ||
50 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); | 51 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); |
@@ -339,7 +340,9 @@ static int tipc_release(struct socket *sock) | |||
339 | if ((sock->state == SS_CONNECTING) || | 340 | if ((sock->state == SS_CONNECTING) || |
340 | (sock->state == SS_CONNECTED)) { | 341 | (sock->state == SS_CONNECTED)) { |
341 | sock->state = SS_DISCONNECTING; | 342 | sock->state = SS_DISCONNECTING; |
342 | tipc_port_disconnect(port->ref); | 343 | port->connected = 0; |
344 | tipc_node_remove_conn(tipc_port_peernode(port), | ||
345 | port->ref); | ||
343 | } | 346 | } |
344 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) | 347 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) |
345 | tipc_link_xmit(buf, dnode, 0); | 348 | tipc_link_xmit(buf, dnode, 0); |
@@ -988,29 +991,25 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, | |||
988 | return tipc_send_stream(iocb, sock, m, dsz); | 991 | return tipc_send_stream(iocb, sock, m, dsz); |
989 | } | 992 | } |
990 | 993 | ||
991 | /** | 994 | /* tipc_sk_finish_conn - complete the setup of a connection |
992 | * auto_connect - complete connection setup to a remote port | ||
993 | * @tsk: tipc socket structure | ||
994 | * @msg: peer's response message | ||
995 | * | ||
996 | * Returns 0 on success, errno otherwise | ||
997 | */ | 995 | */ |
998 | static int auto_connect(struct tipc_sock *tsk, struct tipc_msg *msg) | 996 | static void tipc_sk_finish_conn(struct tipc_port *port, u32 peer_port, |
997 | u32 peer_node) | ||
999 | { | 998 | { |
1000 | struct tipc_port *port = &tsk->port; | 999 | struct tipc_msg *msg = &port->phdr; |
1001 | struct socket *sock = tsk->sk.sk_socket; | ||
1002 | struct tipc_portid peer; | ||
1003 | |||
1004 | peer.ref = msg_origport(msg); | ||
1005 | peer.node = msg_orignode(msg); | ||
1006 | 1000 | ||
1007 | __tipc_port_connect(port->ref, port, &peer); | 1001 | msg_set_destnode(msg, peer_node); |
1002 | msg_set_destport(msg, peer_port); | ||
1003 | msg_set_type(msg, TIPC_CONN_MSG); | ||
1004 | msg_set_lookup_scope(msg, 0); | ||
1005 | msg_set_hdr_sz(msg, SHORT_H_SIZE); | ||
1008 | 1006 | ||
1009 | if (msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE) | 1007 | port->probing_interval = CONN_PROBING_INTERVAL; |
1010 | return -EINVAL; | 1008 | port->probing_state = TIPC_CONN_OK; |
1011 | msg_set_importance(&port->phdr, (u32)msg_importance(msg)); | 1009 | port->connected = 1; |
1012 | sock->state = SS_CONNECTED; | 1010 | k_start_timer(&port->timer, port->probing_interval); |
1013 | return 0; | 1011 | tipc_node_add_conn(peer_node, port->ref, peer_port); |
1012 | port->max_pkt = tipc_node_get_mtu(peer_node, port->ref); | ||
1014 | } | 1013 | } |
1015 | 1014 | ||
1016 | /** | 1015 | /** |
@@ -1405,7 +1404,6 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | |||
1405 | struct tipc_msg *msg = buf_msg(*buf); | 1404 | struct tipc_msg *msg = buf_msg(*buf); |
1406 | 1405 | ||
1407 | int retval = -TIPC_ERR_NO_PORT; | 1406 | int retval = -TIPC_ERR_NO_PORT; |
1408 | int res; | ||
1409 | 1407 | ||
1410 | if (msg_mcast(msg)) | 1408 | if (msg_mcast(msg)) |
1411 | return retval; | 1409 | return retval; |
@@ -1416,13 +1414,20 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | |||
1416 | if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) { | 1414 | if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) { |
1417 | if (unlikely(msg_errcode(msg))) { | 1415 | if (unlikely(msg_errcode(msg))) { |
1418 | sock->state = SS_DISCONNECTING; | 1416 | sock->state = SS_DISCONNECTING; |
1419 | __tipc_port_disconnect(port); | 1417 | port->connected = 0; |
1418 | /* let timer expire on it's own */ | ||
1419 | tipc_node_remove_conn(tipc_port_peernode(port), | ||
1420 | port->ref); | ||
1420 | } | 1421 | } |
1421 | retval = TIPC_OK; | 1422 | retval = TIPC_OK; |
1422 | } | 1423 | } |
1423 | break; | 1424 | break; |
1424 | case SS_CONNECTING: | 1425 | case SS_CONNECTING: |
1425 | /* Accept only ACK or NACK message */ | 1426 | /* Accept only ACK or NACK message */ |
1427 | |||
1428 | if (unlikely(!msg_connected(msg))) | ||
1429 | break; | ||
1430 | |||
1426 | if (unlikely(msg_errcode(msg))) { | 1431 | if (unlikely(msg_errcode(msg))) { |
1427 | sock->state = SS_DISCONNECTING; | 1432 | sock->state = SS_DISCONNECTING; |
1428 | sk->sk_err = ECONNREFUSED; | 1433 | sk->sk_err = ECONNREFUSED; |
@@ -1430,17 +1435,17 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) | |||
1430 | break; | 1435 | break; |
1431 | } | 1436 | } |
1432 | 1437 | ||
1433 | if (unlikely(!msg_connected(msg))) | 1438 | if (unlikely(msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE)) { |
1434 | break; | ||
1435 | |||
1436 | res = auto_connect(tsk, msg); | ||
1437 | if (res) { | ||
1438 | sock->state = SS_DISCONNECTING; | 1439 | sock->state = SS_DISCONNECTING; |
1439 | sk->sk_err = -res; | 1440 | sk->sk_err = EINVAL; |
1440 | retval = TIPC_OK; | 1441 | retval = TIPC_OK; |
1441 | break; | 1442 | break; |
1442 | } | 1443 | } |
1443 | 1444 | ||
1445 | tipc_sk_finish_conn(port, msg_origport(msg), msg_orignode(msg)); | ||
1446 | msg_set_importance(&port->phdr, msg_importance(msg)); | ||
1447 | sock->state = SS_CONNECTED; | ||
1448 | |||
1444 | /* If an incoming message is an 'ACK-', it should be | 1449 | /* If an incoming message is an 'ACK-', it should be |
1445 | * discarded here because it doesn't contain useful | 1450 | * discarded here because it doesn't contain useful |
1446 | * data. In addition, we should try to wake up | 1451 | * data. In addition, we should try to wake up |
@@ -1816,8 +1821,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1816 | struct sk_buff *buf; | 1821 | struct sk_buff *buf; |
1817 | struct tipc_port *new_port; | 1822 | struct tipc_port *new_port; |
1818 | struct tipc_msg *msg; | 1823 | struct tipc_msg *msg; |
1819 | struct tipc_portid peer; | ||
1820 | u32 new_ref; | ||
1821 | long timeo; | 1824 | long timeo; |
1822 | int res; | 1825 | int res; |
1823 | 1826 | ||
@@ -1840,7 +1843,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1840 | 1843 | ||
1841 | new_sk = new_sock->sk; | 1844 | new_sk = new_sock->sk; |
1842 | new_port = &tipc_sk(new_sk)->port; | 1845 | new_port = &tipc_sk(new_sk)->port; |
1843 | new_ref = new_port->ref; | ||
1844 | msg = buf_msg(buf); | 1846 | msg = buf_msg(buf); |
1845 | 1847 | ||
1846 | /* we lock on new_sk; but lockdep sees the lock on sk */ | 1848 | /* we lock on new_sk; but lockdep sees the lock on sk */ |
@@ -1853,9 +1855,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1853 | reject_rx_queue(new_sk); | 1855 | reject_rx_queue(new_sk); |
1854 | 1856 | ||
1855 | /* Connect new socket to it's peer */ | 1857 | /* Connect new socket to it's peer */ |
1856 | peer.ref = msg_origport(msg); | 1858 | tipc_sk_finish_conn(new_port, msg_origport(msg), msg_orignode(msg)); |
1857 | peer.node = msg_orignode(msg); | ||
1858 | tipc_port_connect(new_ref, &peer); | ||
1859 | new_sock->state = SS_CONNECTED; | 1859 | new_sock->state = SS_CONNECTED; |
1860 | 1860 | ||
1861 | tipc_port_set_importance(new_port, msg_importance(msg)); | 1861 | tipc_port_set_importance(new_port, msg_importance(msg)); |
@@ -1919,9 +1919,9 @@ restart: | |||
1919 | kfree_skb(buf); | 1919 | kfree_skb(buf); |
1920 | goto restart; | 1920 | goto restart; |
1921 | } | 1921 | } |
1922 | tipc_port_disconnect(port->ref); | ||
1923 | if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN)) | 1922 | if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN)) |
1924 | tipc_link_xmit(buf, dnode, port->ref); | 1923 | tipc_link_xmit(buf, dnode, port->ref); |
1924 | tipc_node_remove_conn(dnode, port->ref); | ||
1925 | } else { | 1925 | } else { |
1926 | dnode = tipc_port_peernode(port); | 1926 | dnode = tipc_port_peernode(port); |
1927 | buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, | 1927 | buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, |
@@ -1930,11 +1930,10 @@ restart: | |||
1930 | tipc_port_peerport(port), | 1930 | tipc_port_peerport(port), |
1931 | port->ref, TIPC_CONN_SHUTDOWN); | 1931 | port->ref, TIPC_CONN_SHUTDOWN); |
1932 | tipc_link_xmit(buf, dnode, port->ref); | 1932 | tipc_link_xmit(buf, dnode, port->ref); |
1933 | __tipc_port_disconnect(port); | ||
1934 | } | 1933 | } |
1935 | 1934 | port->connected = 0; | |
1936 | sock->state = SS_DISCONNECTING; | 1935 | sock->state = SS_DISCONNECTING; |
1937 | 1936 | tipc_node_remove_conn(dnode, port->ref); | |
1938 | /* fall through */ | 1937 | /* fall through */ |
1939 | 1938 | ||
1940 | case SS_DISCONNECTING: | 1939 | case SS_DISCONNECTING: |