diff options
author | David S. Miller <davem@davemloft.net> | 2016-04-23 18:26:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-23 18:51:33 -0400 |
commit | 1602f49b58abcb0d34a5f0a29d68e7c1769547aa (patch) | |
tree | 4848fb0ffbc581ff465fd9c9e5a5b10b06f09b68 /include/linux/rculist.h | |
parent | 22d37b6b0058365a80378ee6198d21e7f6c86327 (diff) | |
parent | 5f44abd041c5f3be76d57579ab254d78e601315b (diff) | |
download | lwn-1602f49b58abcb0d34a5f0a29d68e7c1769547aa.tar.gz lwn-1602f49b58abcb0d34a5f0a29d68e7c1769547aa.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts were two cases of simple overlapping changes,
nothing serious.
In the UDP case, we need to add a hlist_add_tail_rcu()
to linux/rculist.h, because we've moved UDP socket handling
away from using nulls lists.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/rculist.h')
-rw-r--r-- | include/linux/rculist.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 17d4f849c65e..8beb98dcf14f 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -488,6 +488,42 @@ static inline void hlist_add_head_rcu(struct hlist_node *n, } /** + * hlist_add_tail_rcu + * @n: the element to add to the hash list. + * @h: the list to add to. + * + * Description: + * Adds the specified element to the specified hlist, + * while permitting racing traversals. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as hlist_add_head_rcu() + * or hlist_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * hlist_for_each_entry_rcu(), used to prevent memory-consistency + * problems on Alpha CPUs. Regardless of the type of CPU, the + * list-traversal primitive must be guarded by rcu_read_lock(). + */ +static inline void hlist_add_tail_rcu(struct hlist_node *n, + struct hlist_head *h) +{ + struct hlist_node *i, *last = NULL; + + for (i = hlist_first_rcu(h); i; i = hlist_next_rcu(i)) + last = i; + + if (last) { + n->next = last->next; + n->pprev = &last->next; + rcu_assign_pointer(hlist_next_rcu(last), n); + } else { + hlist_add_head_rcu(n, h); + } +} + +/** * hlist_add_before_rcu * @n: the new element to add to the hash list. * @next: the existing element to add the new element before. |