From 07f6c4bc048a7a8939c68a668bf77474890794c5 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 7 Jan 2015 13:41:58 +0800 Subject: tipc: convert tipc reference table to use generic rhashtable As tipc reference table is statically allocated, its memory size requested on stack initialization stage is quite big even if the maximum port number is just restricted to 8191 currently, however, the number already becomes insufficient in practice. But if the maximum ports is allowed to its theory value - 2^32, its consumed memory size will reach a ridiculously unacceptable value. Apart from this, heavy tipc users spend a considerable amount of time in tipc_sk_get() due to the read-lock on ref_table_lock. If tipc reference table is converted with generic rhashtable, above mentioned both disadvantages would be resolved respectively: making use of the new resizable hash table can avoid locking on the lookup; smaller memory size is required at initial stage, for example, 256 hash bucket slots are requested at the beginning phase instead of allocating the entire 8191 slots in old mode. The hash table will grow if entries exceeds 75% of table size up to a total table size of 1M, and it will automatically shrink if usage falls below 30%, but the minimum table size is allowed down to 256. Also converts ref_table_lock to a separate mutex to protect hash table mutations on write side. Lastly defers the release of the socket reference using call_rcu() to allow using an RCU read-side protected call to rhashtable_lookup(). Signed-off-by: Ying Xue Acked-by: Jon Maloy Acked-by: Erik Hugne Cc: Thomas Graf Acked-by: Thomas Graf Signed-off-by: David S. Miller --- net/tipc/socket.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index d34089387006..c7d46d069d89 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -46,8 +46,8 @@ int tipc_sk_rcv(struct sk_buff *buf); struct sk_buff *tipc_sk_socks_show(void); void tipc_sk_mcast_rcv(struct sk_buff *buf); void tipc_sk_reinit(void); -int tipc_sk_ref_table_init(u32 requested_size, u32 start); -void tipc_sk_ref_table_stop(void); +int tipc_sk_rht_init(void); +void tipc_sk_rht_destroy(void); int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb); -- cgit v1.2.2 From 859fc7c0cedca0f84dac471fa31e9512259e1ecd Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Fri, 9 Jan 2015 15:27:01 +0800 Subject: tipc: cleanup core.c and core.h files Only the works of initializing and shutting down tipc module are done in core.h and core.c files, so all stuffs which are not closely associated with the two tasks should be moved to appropriate places. Signed-off-by: Ying Xue Tested-by: Tero Aho Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index c7d46d069d89..46bc370d82c7 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -42,6 +42,13 @@ #define TIPC_FLOWCTRL_WIN (TIPC_CONNACK_INTV * 2) #define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \ SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) + +int tipc_socket_init(void); +void tipc_socket_stop(void); +int tipc_sock_create_local(int type, struct socket **res); +void tipc_sock_release_local(struct socket *sock); +int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, + int flags); int tipc_sk_rcv(struct sk_buff *buf); struct sk_buff *tipc_sk_socks_show(void); void tipc_sk_mcast_rcv(struct sk_buff *buf); -- cgit v1.2.2 From f2f9800d4955a96d92896841d8ba9b04201deaa1 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Fri, 9 Jan 2015 15:27:05 +0800 Subject: tipc: make tipc node table aware of net namespace Global variables associated with node table are below: - node table list (node_htable) - node hash table list (tipc_node_list) - node table lock (node_list_lock) - node number counter (tipc_num_nodes) - node link number counter (tipc_num_links) To make node table support namespace, above global variables must be moved to tipc_net structure in order to keep secret for different namespaces. As a consequence, these variables are allocated and initialized when namespace is created, and deallocated when namespace is destroyed. After the change, functions associated with these variables have to utilize a namespace pointer to access them. So adding namespace pointer as a parameter of these functions is the major change made in the commit. Signed-off-by: Ying Xue Tested-by: Tero Aho Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index 46bc370d82c7..eb15c3107920 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -49,9 +49,9 @@ int tipc_sock_create_local(int type, struct socket **res); void tipc_sock_release_local(struct socket *sock); int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, int flags); -int tipc_sk_rcv(struct sk_buff *buf); +int tipc_sk_rcv(struct net *net, struct sk_buff *buf); struct sk_buff *tipc_sk_socks_show(void); -void tipc_sk_mcast_rcv(struct sk_buff *buf); +void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf); void tipc_sk_reinit(void); int tipc_sk_rht_init(void); void tipc_sk_rht_destroy(void); -- cgit v1.2.2 From e05b31f4bf8994d49322e9afb004ad479a129db0 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Fri, 9 Jan 2015 15:27:08 +0800 Subject: tipc: make tipc socket support net namespace Now tipc socket table is statically allocated as a global variable. Through it, we can look up one socket instance with port ID, insert a new socket instance to the table, and delete a socket from the table. But when tipc supports net namespace, each namespace must own its specific socket table. So the global variable of socket table must be redefined in tipc_net structure. As a concequence, a new socket table will be allocated when a new namespace is created, and a socket table will be deallocated when namespace is destroyed. Signed-off-by: Ying Xue Tested-by: Tero Aho Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index eb15c3107920..c15c4e121fe3 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -50,11 +50,11 @@ void tipc_sock_release_local(struct socket *sock); int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, int flags); int tipc_sk_rcv(struct net *net, struct sk_buff *buf); -struct sk_buff *tipc_sk_socks_show(void); +struct sk_buff *tipc_sk_socks_show(struct net *net); void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf); -void tipc_sk_reinit(void); -int tipc_sk_rht_init(void); -void tipc_sk_rht_destroy(void); +void tipc_sk_reinit(struct net *net); +int tipc_sk_rht_init(struct net *net); +void tipc_sk_rht_destroy(struct net *net); int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb); -- cgit v1.2.2 From a62fbccecd62bacb4416fc427239f5b43b25d05e Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Fri, 9 Jan 2015 15:27:11 +0800 Subject: tipc: make subscriber server support net namespace TIPC establishes one subscriber server which allows users to subscribe their interesting name service status. After tipc supports namespace, one dedicated tipc stack instance is created for each namespace, and each instance can be deemed as one independent TIPC node. As a result, subscriber server must be built for each namespace. Signed-off-by: Ying Xue Tested-by: Tero Aho Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index c15c4e121fe3..f56c3fded51f 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -45,7 +45,7 @@ int tipc_socket_init(void); void tipc_socket_stop(void); -int tipc_sock_create_local(int type, struct socket **res); +int tipc_sock_create_local(struct net *net, int type, struct socket **res); void tipc_sock_release_local(struct socket *sock); int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, int flags); -- cgit v1.2.2 From c637c1035534867b85b78b453c38c495b58e2c5a Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Thu, 5 Feb 2015 08:36:41 -0500 Subject: tipc: resolve race problem at unicast message reception TIPC handles message cardinality and sequencing at the link layer, before passing messages upwards to the destination sockets. During the upcall from link to socket no locks are held. It is therefore possible, and we see it happen occasionally, that messages arriving in different threads and delivered in sequence still bypass each other before they reach the destination socket. This must not happen, since it violates the sequentiality guarantee. We solve this by adding a new input buffer queue to the link structure. Arriving messages are added safely to the tail of that queue by the link, while the head of the queue is consumed, also safely, by the receiving socket. Sequentiality is secured per socket by only allowing buffers to be dequeued inside the socket lock. Since there may be multiple simultaneous readers of the queue, we use a 'filter' parameter to reduce the risk that they peek the same buffer from the queue, hence also reducing the risk of contention on the receiving socket locks. This solves the sequentiality problem, and seems to cause no measurable performance degradation. A nice side effect of this change is that lock handling in the functions tipc_rcv() and tipc_bcast_rcv() now becomes uniform, something that will enable future simplifications of those functions. Reviewed-by: Ying Xue Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index f56c3fded51f..e3dbdc0e1be7 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -49,7 +49,7 @@ int tipc_sock_create_local(struct net *net, int type, struct socket **res); void tipc_sock_release_local(struct socket *sock); int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, int flags); -int tipc_sk_rcv(struct net *net, struct sk_buff *buf); +int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); struct sk_buff *tipc_sk_socks_show(struct net *net); void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf); void tipc_sk_reinit(struct net *net); -- cgit v1.2.2 From 3c724acdd5049907555a831f814bfd5927c3350c Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Thu, 5 Feb 2015 08:36:43 -0500 Subject: tipc: simplify socket multicast reception The structure 'tipc_port_list' is used to collect port numbers representing multicast destination socket on a receiving node. The list is not based on a standard linked list, and is in reality optimized for the uncommon case that there are more than one multicast destinations per node. This makes the list handling unecessarily complex, and as a consequence, even the socket multicast reception becomes more complex. In this commit, we replace 'tipc_port_list' with a new 'struct tipc_plist', which is based on a standard list. We give the new list stack (push/pop) semantics, someting that simplifies the implementation of the function tipc_sk_mcast_rcv(). Reviewed-by: Ying Xue Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index e3dbdc0e1be7..95b015909ac1 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -1,6 +1,6 @@ /* net/tipc/socket.h: Include file for TIPC socket code * - * Copyright (c) 2014, Ericsson AB + * Copyright (c) 2014-2015, Ericsson AB * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.2 From cb1b728096f54e7408d60fb571944bed00c5b771 Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Thu, 5 Feb 2015 08:36:44 -0500 Subject: tipc: eliminate race condition at multicast reception In a previous commit in this series we resolved a race problem during unicast message reception. Here, we resolve the same problem at multicast reception. We apply the same technique: an input queue serializing the delivery of arriving buffers. The main difference is that here we do it in two steps. First, the broadcast link feeds arriving buffers into the tail of an arrival queue, which head is consumed at the socket level, and where destination lookup is performed. Second, if the lookup is successful, the resulting buffer clones are fed into a second queue, the input queue. This queue is consumed at reception in the socket just like in the unicast case. Both queues are protected by the same lock, -the one of the input queue. Reviewed-by: Ying Xue Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index 95b015909ac1..8be0da7df8fc 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -42,7 +42,6 @@ #define TIPC_FLOWCTRL_WIN (TIPC_CONNACK_INTV * 2) #define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \ SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) - int tipc_socket_init(void); void tipc_socket_stop(void); int tipc_sock_create_local(struct net *net, int type, struct socket **res); @@ -51,7 +50,8 @@ int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, int flags); int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); struct sk_buff *tipc_sk_socks_show(struct net *net); -void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf); +void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, + struct sk_buff_head *inputq); void tipc_sk_reinit(struct net *net); int tipc_sk_rht_init(struct net *net); void tipc_sk_rht_destroy(struct net *net); -- cgit v1.2.2 From 487d2a3a1326d339ce273ffbcd03247f2b7b052e Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 9 Feb 2015 09:50:11 +0100 Subject: tipc: convert legacy nl socket dump to nl compat Convert socket (port) listing to compat dumpit call. If a socket (port) has publications a second dumpit call is issued to collect them and format then into the legacy buffer before continuing to process the sockets (ports). Command converted in this patch: TIPC_CMD_SHOW_PORTS Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/socket.h | 1 - 1 file changed, 1 deletion(-) (limited to 'net/tipc/socket.h') diff --git a/net/tipc/socket.h b/net/tipc/socket.h index 8be0da7df8fc..238f1b7bd9bd 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -49,7 +49,6 @@ void tipc_sock_release_local(struct socket *sock); int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, int flags); int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); -struct sk_buff *tipc_sk_socks_show(struct net *net); void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, struct sk_buff_head *inputq); void tipc_sk_reinit(struct net *net); -- cgit v1.2.2