summaryrefslogtreecommitdiff
path: root/net/tipc/port.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-08-22 22:09:08 (GMT)
committerDavid S. Miller <davem@davemloft.net>2014-08-23 18:18:33 (GMT)
commit02be61a981fb5ca5f1526323336198ee92cadf95 (patch)
tree2cd5f3dc25025a071ab2806b2e10981851b21bc5 /net/tipc/port.c
parent50100a5e39461b2a61d6040e73c384766c29975d (diff)
downloadlinux-02be61a981fb5ca5f1526323336198ee92cadf95.tar.xz
tipc: use message to abort connections when losing contact to node
In the current implementation, each 'struct tipc_node' instance keeps a linked list of those ports/sockets that are connected to the node represented by that struct. The purpose of this is to let the node object know which sockets to alert when it loses contact with its peer node, i.e., which sockets need to have their connections aborted. This entails an unwanted direct reference from the node structure back to the port/socket structure, and a need to grab port_lock when we have to make an upcall to the port. We want to get rid of this unecessary BH entry point into the socket, and also eliminate its use of port_lock. In this commit, we instead let the node struct keep list of "connected socket" structs, which each represents a connected socket, but is allocated independently by the node at the moment of connection. If the node loses contact with its peer node, the list is traversed, and a "connection abort" message is created for each entry in the list. The message is sent to it respective connected socket using the ordinary data path, and the receiving socket aborts its connections upon reception of the message. This enables us to get rid of the direct reference from 'struct node' to ´struct port', and another unwanted BH access point to the latter. 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/port.c')
-rw-r--r--net/tipc/port.c29
1 files changed, 4 insertions, 25 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c
index b58a777..edbd83d 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -48,7 +48,6 @@
DEFINE_SPINLOCK(tipc_port_list_lock);
static LIST_HEAD(ports);
-static void port_handle_node_down(unsigned long ref);
static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err);
static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err);
static void port_timeout(unsigned long ref);
@@ -126,10 +125,10 @@ void tipc_port_destroy(struct tipc_port *p_ptr)
k_cancel_timer(&p_ptr->timer);
if (p_ptr->connected) {
buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
- tipc_nodesub_unsubscribe(&p_ptr->subscription);
msg = buf_msg(buf);
peer = msg_destnode(msg);
tipc_link_xmit(buf, peer, msg_link_selector(msg));
+ tipc_node_remove_conn(peer, p_ptr->ref);
}
spin_lock_bh(&tipc_port_list_lock);
list_del(&p_ptr->port_list);
@@ -188,22 +187,6 @@ static void port_timeout(unsigned long ref)
tipc_link_xmit(buf, msg_destnode(msg), msg_link_selector(msg));
}
-
-static void port_handle_node_down(unsigned long ref)
-{
- struct tipc_port *p_ptr = tipc_port_lock(ref);
- struct sk_buff *buf = NULL;
- struct tipc_msg *msg = NULL;
-
- if (!p_ptr)
- return;
- buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_NODE);
- tipc_port_unlock(p_ptr);
- msg = buf_msg(buf);
- tipc_link_xmit(buf, msg_destnode(msg), msg_link_selector(msg));
-}
-
-
static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
{
struct sk_buff *buf = port_build_peer_abort_msg(p_ptr, err);
@@ -217,7 +200,6 @@ static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 er
return buf;
}
-
static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
{
struct sk_buff *buf;
@@ -447,11 +429,8 @@ int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
p_ptr->probing_state = TIPC_CONN_OK;
p_ptr->connected = 1;
k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
-
- tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
- (void *)(unsigned long)ref,
- (net_ev_handler)port_handle_node_down);
- res = 0;
+ res = tipc_node_add_conn(tipc_port_peernode(p_ptr), p_ptr->ref,
+ tipc_port_peerport(p_ptr));
exit:
p_ptr->max_pkt = tipc_node_get_mtu(peer->node, ref);
return res;
@@ -467,7 +446,7 @@ int __tipc_port_disconnect(struct tipc_port *tp_ptr)
if (tp_ptr->connected) {
tp_ptr->connected = 0;
/* let timer expire on it's own to avoid deadlock! */
- tipc_nodesub_unsubscribe(&tp_ptr->subscription);
+ tipc_node_remove_conn(tipc_port_peernode(tp_ptr), tp_ptr->ref);
return 0;
}