linux-stable/net/tipc
Ying Xue c61dd61dec tipc: remove 'links' list from tipc_bearer struct
In our ongoing effort to simplify the TIPC locking structure,
we see a need to remove the linked list for tipc_links
in the bearer. This can be explained as follows.

Currently, we have three different ways to access a link,
via three different lists/tables:

1: Via a node hash table:
   Used by the time-critical outgoing/incoming data paths.
   (e.g. link_send_sections_fast() and tipc_recv_msg() ):

grab net_lock(read)
   find node from node hash table
   grab node_lock
       select link
       grab bearer_lock
          send_msg()
       release bearer_lock
   release node lock
release net_lock

2: Via a global linked list for nodes:
   Used by configuration commands (link_cmd_set_value())

grab net_lock(read)
   find node and link from global node list (using link name)
   grab node_lock
       update link
   release node lock
release net_lock

(Same locking order as above. No problem.)

3: Via the bearer's linked link list:
   Used by notifications from interface (e.g. tipc_disable_bearer() )

grab net_lock(write)
   grab bearer_lock
      get link ptr from bearer's link list
      get node from link
      grab node_lock
         delete link
      release node lock
   release bearer_lock
release net_lock

(Different order from above, but works because we grab the
outer net_lock in write mode first, excluding all other access.)

The first major goal in our simplification effort is to get rid
of the "big" net_lock, replacing it with rcu-locks when accessing
the node list and node hash array. This will come in a later patch
series.

But to get there we first need to rewrite access methods ##2 and 3,
since removal of net_lock would introduce three major problems:

a) In access method #2, we access the link before taking the
   protecting node_lock. This will not work once net_lock is gone,
   so we will have to change the access order. We will deal with
   this in a later commit in this series, "tipc: add node lock
   protection to link found by link_find_link()".

b) When the outer protection from net_lock is gone, taking
   bearer_lock and node_lock in opposite order of method 1) and 2)
   will become an obvious deadlock hazard. This is fixed in the
   commit ("tipc: remove bearer_lock from tipc_bearer struct")
   later in this series.

c) Similar to what is described in problem a), access method #3
   starts with using a link pointer that is unprotected by node_lock,
   in order to via that pointer find the correct node struct and
   lock it. Before we remove net_lock, this access order must be
   altered. This is what we do with this commit.

We can avoid introducing problem problem c) by even here using the
global node list to find the node, before accessing its links. When
we loop though the node list we use the own bearer identity as search
criteria, thus easily finding the links that are associated to the
resetting/disabling bearer. It should be noted that although this
method is somewhat slower than the current list traversal, it is in
no way time critical. This is only about resetting or deleting links,
something that must be considered relatively infrequent events.

As a bonus, we can get rid of the mutual pointers between links and
bearers. After this commit, pointer dependency go in one direction
only: from the link to the bearer.

This commit pre-empts introduction of problem c) as described above.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-02-13 17:57:05 -05:00
..
addr.c tipc: compress out gratuitous extra carriage returns 2012-04-30 15:53:56 -04:00
addr.h tipc: explicitly include core.h in addr.h 2014-02-13 17:49:13 -05:00
bcast.c tipc: stricter behavior of message reassembly function 2014-02-13 17:57:05 -05:00
bcast.h tipc: cosmetic realignment of function arguments 2013-06-17 15:53:01 -07:00
bearer.c tipc: remove 'links' list from tipc_bearer struct 2014-02-13 17:57:05 -05:00
bearer.h tipc: remove 'links' list from tipc_bearer struct 2014-02-13 17:57:05 -05:00
config.c tipc: convert config_lock from spinlock to mutex 2013-06-17 15:53:01 -07:00
config.h tipc: Optimize re-initialization of configuration service 2012-04-26 17:19:07 -04:00
core.c tipc: remove 'links' list from tipc_bearer struct 2014-02-13 17:57:05 -05:00
core.h tipc: Use <linux/uaccess.h> instead of <asm/uaccess.h> 2013-12-16 12:48:35 -05:00
discover.c tipc: introduce new spinlock to protect struct link_req 2014-01-07 18:44:25 -05:00
discover.h tipc: rename struct link* to struct tipc_link* 2011-12-29 21:53:30 -05:00
eth_media.c tipc: eliminate code duplication in media layer 2013-12-11 00:17:43 -05:00
handler.c tipc: protect handler_enabled variable with qitem_lock spin lock 2013-12-10 22:35:49 -05:00
ib_media.c tipc: eliminate code duplication in media layer 2013-12-11 00:17:43 -05:00
Kconfig tipc: add InfiniBand media type 2013-04-17 14:18:33 -04:00
link.c tipc: remove 'links' list from tipc_bearer struct 2014-02-13 17:57:05 -05:00
link.h tipc: remove 'links' list from tipc_bearer struct 2014-02-13 17:57:05 -05:00
log.c tipc: remove print_buf and deprecated log buffer code 2012-07-13 19:34:43 -04:00
Makefile tipc: introduce new TIPC server infrastructure 2013-06-17 15:53:00 -07:00
msg.c tipc: remove iovec length parameter from all sending functions 2013-10-18 13:20:42 -04:00
msg.h tipc: message reassembly using fragment chain 2013-11-07 18:30:11 -05:00
name_distr.c tipc: eliminate an unnecessary cast of node variable 2012-11-22 14:33:28 -05:00
name_distr.h
name_table.c tipc: remove unnecessary variables and conditions 2013-12-16 12:48:35 -05:00
name_table.h tipc: cosmetic realignment of function arguments 2013-06-17 15:53:01 -07:00
net.c tipc: change tipc_net_start routine return value type 2012-08-20 02:26:30 -07:00
net.h tipc: change tipc_net_start routine return value type 2012-08-20 02:26:30 -07:00
netlink.c genetlink: only pass array to genl_register_family_with_ops() 2013-11-19 16:39:05 -05:00
node.c tipc: rename functions related to link failover and improve comments 2014-01-07 18:44:25 -05:00
node.h tipc: remove 'has_redundant_link' flag from STATE link protocol messages 2014-01-07 18:44:25 -05:00
node_subscr.c tipc: cosmetic realignment of function arguments 2013-06-17 15:53:01 -07:00
node_subscr.h tipc: compress out gratuitous extra carriage returns 2012-04-30 15:53:56 -04:00
port.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-01-06 17:37:45 -05:00
port.h tipc: fix deadlock during socket release 2013-12-29 22:24:07 -05:00
ref.c tipc: use standard printk shortcut macros (pr_err etc.) 2012-07-13 19:24:44 -04:00
ref.h tipc: cleanup function namespace 2010-10-16 11:13:24 -07:00
server.c tipc: spelling fixes 2014-01-14 18:18:22 -08:00
server.h tipc: introduce new TIPC server infrastructure 2013-06-17 15:53:00 -07:00
socket.c net: add build-time checks for msg->msg_name size 2014-01-18 23:04:16 -08:00
subscr.c tipc: spelling fixes 2014-01-14 18:18:22 -08:00
subscr.h tipc: cosmetic realignment of function arguments 2013-06-17 15:53:01 -07:00
sysctl.c tipc: change socket buffer overflow control to respect sk_rcvbuf 2013-06-17 15:53:00 -07:00