aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-07-08 23:52:12 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-08 23:52:12 -0400
commitcc3baecb21d2e6ff61e81a0b864c8fd624a7f258 (patch)
tree1e358e60f96a1a4b373a61c1ee84204c0702fe01 /include
parent99a50bb11cad44cd1d478256d2388e7afce982ac (diff)
parentd440a1ce5d2cf9d90390f6c0d8badc4c0a4f8b6b (diff)
Merge tag 'rxrpc-rewrite-20160706' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
David Howells says: ==================== rxrpc: Improve conn/call lookup and fix call number generation [ver #3] I've fixed a couple of patch descriptions and excised the patch that duplicated the connections list for reconsideration at a later date. For reference, the excised patch is sitting on the rxrpc-experimental branch of my git tree, based on top of the rxrpc-rewrite branch. Diffing it against yesterday's tag shows no differences. Would you prefer the patch set to be emailed afresh instead of a git-pull request? David --- Here's the next part of the AF_RXRPC rewrite. The two main purposes of this set are to fix the call number handling and to make use of RCU when looking up the connection or call to pass a received packet to. Important changes in this set include: (1) Avoidance of placing stack data into SG lists in rxkad so that kernel stacks can become vmalloc'd (Herbert Xu). (2) Calls cease pinning the connection they used as soon as possible, which allows the connection to be discarded sooner and allows the call channel on that connection to be reused earlier. (3) Make each call channel on a connection have a separate and independent call number space rather than having a shared number space for the connection. Call numbers should increment monotonically per channel on the client, and the server should ignore a call with a lower call number for that channel than the latest it has seen. The RESPONSE packet sets the minimum values of each call ID counter on a connection. (4) Look up calls by indexing the channel array on a connection rather than by keeping calls in an rbtree on that connection. Also look up calls using the channel array rather than using a hashtable. The call hashtable can then be removed. (5) Call terminal statuses are cached in the channel array for the last call. It is assumed that if we the server have seen call N, then the client no longer cares about call N-1 on the same channel. This will allow retransmission of the terminal status in future without the need to keep the rxrpc_call struct around. (6) Peer lookups are moved out of common connection handling code and into service connection handling code as client connections (a) must point to a peer before they can be used and (b) are looked up by a machine-unique connection ID directly, so we only need to look up the peer first if we're going to deal with a service call. (7) The reference count on a connection is held elevated by 1 whilst it is alive (ie. idle unused connections have a refcount of 1). The reaper will attempt to change the refcount from 1->0 and skip if this cannot be done, whilst look ups only increment the refcount if it's non-zero. This makes the implementation of RCU lookups easier as we don't have to get a ref on the connection or a lock on the connection list to prevent a connection being reaped whilst we're contemplating queueing a packet that initiates a new service call upon it. If we need to get a connection, but there's a dead connection in the tree, we use rb_replace_node() to replace the dead one with a new one. (8) Use a seqlock to validate the walk over the service connection rbtree attached to a peer when it's being walked in RCU mode. (9) Make the incoming call/connection packet handling code use RCU mode and locks and make it only take a reference if the call/connection gets queued on a workqueue. The intention is that the next set will introduce the connection lifetime management and capacity limits to prevent clients from overloading the server. There are some fixes too: (1) Verifying that a packet coming in to a client connection came from the expected source. (2) Fix handling of connection failure in client call creation where we don't reinitialise the list linkage block and a second attempt to unlink the failed connection oopses and also we don't set the state correctly, which causes an assertion failure. (3) New service calls were being added to the socket's accept queue under the wrong lock. Changes: (V2) In rxrpc_find_service_conn_rcu() initialised the sequence number to 0. Fixed the RCU handling in conn_service.c by introducing and using rb_replace_node_rcu() as an RCU-safe alternative in rxrpc_publish_service_conn(). Modified and used rcu_dereference_raw() to avoid RCU sparse warnings in rxrpc_find_service_conn_rcu(). Added in some missing RCU dereference wrappers. It seems to be necessary to turn on CONFIG_PROVE_RCU_REPEATEDLY as well as CONFIG_SPARSE_RCU_POINTER to get the static __rcu annotation checking to happen. Fixed some other sparse warnings, including a missing ntohs() in jumbo packet processing. (V3) Fixed some commit descriptions. Excised the patch that duplicated the connection list to separate out the procfs list for reconsideration at a later date. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/rbtree.h2
-rw-r--r--include/linux/rbtree_augmented.h13
-rw-r--r--include/linux/rcupdate.h8
3 files changed, 21 insertions, 2 deletions
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index b6900099ea81..e585018498d5 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -76,6 +76,8 @@ extern struct rb_node *rb_next_postorder(const struct rb_node *);
76/* Fast replacement of a single node without remove/rebalance/add/rebalance */ 76/* Fast replacement of a single node without remove/rebalance/add/rebalance */
77extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, 77extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
78 struct rb_root *root); 78 struct rb_root *root);
79extern void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new,
80 struct rb_root *root);
79 81
80static inline void rb_link_node(struct rb_node *node, struct rb_node *parent, 82static inline void rb_link_node(struct rb_node *node, struct rb_node *parent,
81 struct rb_node **rb_link) 83 struct rb_node **rb_link)
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
index 14d7b831b63a..d076183e49be 100644
--- a/include/linux/rbtree_augmented.h
+++ b/include/linux/rbtree_augmented.h
@@ -130,6 +130,19 @@ __rb_change_child(struct rb_node *old, struct rb_node *new,
130 WRITE_ONCE(root->rb_node, new); 130 WRITE_ONCE(root->rb_node, new);
131} 131}
132 132
133static inline void
134__rb_change_child_rcu(struct rb_node *old, struct rb_node *new,
135 struct rb_node *parent, struct rb_root *root)
136{
137 if (parent) {
138 if (parent->rb_left == old)
139 rcu_assign_pointer(parent->rb_left, new);
140 else
141 rcu_assign_pointer(parent->rb_right, new);
142 } else
143 rcu_assign_pointer(root->rb_node, new);
144}
145
133extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, 146extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
134 void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); 147 void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
135 148
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 5f1533e3d032..85830e6c797b 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -611,6 +611,12 @@ static inline void rcu_preempt_sleep_check(void)
611 rcu_dereference_sparse(p, space); \ 611 rcu_dereference_sparse(p, space); \
612 ((typeof(*p) __force __kernel *)(p)); \ 612 ((typeof(*p) __force __kernel *)(p)); \
613}) 613})
614#define rcu_dereference_raw(p) \
615({ \
616 /* Dependency order vs. p above. */ \
617 typeof(p) ________p1 = lockless_dereference(p); \
618 ((typeof(*p) __force __kernel *)(________p1)); \
619})
614 620
615/** 621/**
616 * RCU_INITIALIZER() - statically initialize an RCU-protected global variable 622 * RCU_INITIALIZER() - statically initialize an RCU-protected global variable
@@ -729,8 +735,6 @@ static inline void rcu_preempt_sleep_check(void)
729 __rcu_dereference_check((p), (c) || rcu_read_lock_sched_held(), \ 735 __rcu_dereference_check((p), (c) || rcu_read_lock_sched_held(), \
730 __rcu) 736 __rcu)
731 737
732#define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/
733
734/* 738/*
735 * The tracing infrastructure traces RCU (we want that), but unfortunately 739 * The tracing infrastructure traces RCU (we want that), but unfortunately
736 * some of the RCU checks causes tracing to lock up the system. 740 * some of the RCU checks causes tracing to lock up the system.