diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-24 17:33:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-25 16:09:45 -0400 |
commit | 6f0bcf152582e7403155627a38e07bf3ef7f3cf5 (patch) | |
tree | 0dafb9ea61fa01bb8850ee2bcce97b98c23a7c8f /net | |
parent | 3cc77ec74e1583b50b8405114cdbd6b8ebb8c474 (diff) |
tunnels: add _rcu annotations
(struct ip6_tnl)->next is rcu protected :
(struct ip_tunnel)->next is rcu protected :
(struct xfrm6_tunnel)->next is rcu protected :
add __rcu annotation and proper rcu primitives.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/gre.c | 5 | ||||
-rw-r--r-- | net/ipv6/tunnel6.c | 24 |
2 files changed, 18 insertions, 11 deletions
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index caea6885fdbd..c6933f2ea310 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <net/gre.h> | 22 | #include <net/gre.h> |
23 | 23 | ||
24 | 24 | ||
25 | static const struct gre_protocol *gre_proto[GREPROTO_MAX] __read_mostly; | 25 | static const struct gre_protocol __rcu *gre_proto[GREPROTO_MAX] __read_mostly; |
26 | static DEFINE_SPINLOCK(gre_proto_lock); | 26 | static DEFINE_SPINLOCK(gre_proto_lock); |
27 | 27 | ||
28 | int gre_add_protocol(const struct gre_protocol *proto, u8 version) | 28 | int gre_add_protocol(const struct gre_protocol *proto, u8 version) |
@@ -51,7 +51,8 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version) | |||
51 | goto err_out; | 51 | goto err_out; |
52 | 52 | ||
53 | spin_lock(&gre_proto_lock); | 53 | spin_lock(&gre_proto_lock); |
54 | if (gre_proto[version] != proto) | 54 | if (rcu_dereference_protected(gre_proto[version], |
55 | lockdep_is_held(&gre_proto_lock)) != proto) | ||
55 | goto err_out_unlock; | 56 | goto err_out_unlock; |
56 | rcu_assign_pointer(gre_proto[version], NULL); | 57 | rcu_assign_pointer(gre_proto[version], NULL); |
57 | spin_unlock(&gre_proto_lock); | 58 | spin_unlock(&gre_proto_lock); |
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index d9864725d0c6..4f3cec12aa85 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c | |||
@@ -30,23 +30,26 @@ | |||
30 | #include <net/protocol.h> | 30 | #include <net/protocol.h> |
31 | #include <net/xfrm.h> | 31 | #include <net/xfrm.h> |
32 | 32 | ||
33 | static struct xfrm6_tunnel *tunnel6_handlers __read_mostly; | 33 | static struct xfrm6_tunnel __rcu *tunnel6_handlers __read_mostly; |
34 | static struct xfrm6_tunnel *tunnel46_handlers __read_mostly; | 34 | static struct xfrm6_tunnel __rcu *tunnel46_handlers __read_mostly; |
35 | static DEFINE_MUTEX(tunnel6_mutex); | 35 | static DEFINE_MUTEX(tunnel6_mutex); |
36 | 36 | ||
37 | int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) | 37 | int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) |
38 | { | 38 | { |
39 | struct xfrm6_tunnel **pprev; | 39 | struct xfrm6_tunnel __rcu **pprev; |
40 | struct xfrm6_tunnel *t; | ||
40 | int ret = -EEXIST; | 41 | int ret = -EEXIST; |
41 | int priority = handler->priority; | 42 | int priority = handler->priority; |
42 | 43 | ||
43 | mutex_lock(&tunnel6_mutex); | 44 | mutex_lock(&tunnel6_mutex); |
44 | 45 | ||
45 | for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers; | 46 | for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers; |
46 | *pprev; pprev = &(*pprev)->next) { | 47 | (t = rcu_dereference_protected(*pprev, |
47 | if ((*pprev)->priority > priority) | 48 | lockdep_is_held(&tunnel6_mutex))) != NULL; |
49 | pprev = &t->next) { | ||
50 | if (t->priority > priority) | ||
48 | break; | 51 | break; |
49 | if ((*pprev)->priority == priority) | 52 | if (t->priority == priority) |
50 | goto err; | 53 | goto err; |
51 | } | 54 | } |
52 | 55 | ||
@@ -65,14 +68,17 @@ EXPORT_SYMBOL(xfrm6_tunnel_register); | |||
65 | 68 | ||
66 | int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) | 69 | int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) |
67 | { | 70 | { |
68 | struct xfrm6_tunnel **pprev; | 71 | struct xfrm6_tunnel __rcu **pprev; |
72 | struct xfrm6_tunnel *t; | ||
69 | int ret = -ENOENT; | 73 | int ret = -ENOENT; |
70 | 74 | ||
71 | mutex_lock(&tunnel6_mutex); | 75 | mutex_lock(&tunnel6_mutex); |
72 | 76 | ||
73 | for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers; | 77 | for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers; |
74 | *pprev; pprev = &(*pprev)->next) { | 78 | (t = rcu_dereference_protected(*pprev, |
75 | if (*pprev == handler) { | 79 | lockdep_is_held(&tunnel6_mutex))) != NULL; |
80 | pprev = &t->next) { | ||
81 | if (t == handler) { | ||
76 | *pprev = handler->next; | 82 | *pprev = handler->next; |
77 | ret = 0; | 83 | ret = 0; |
78 | break; | 84 | break; |