Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tunnels: add __rcu annotations

Add __rcu annotations to :
(struct ip_tunnel)->prl
(struct ip_tunnel_prl_entry)->next
(struct xfrm_tunnel)->next
struct xfrm_tunnel *tunnel4_handlers
struct xfrm_tunnel *tunnel64_handlers

And use appropriate rcu primitives to reduce sparse warnings if
CONFIG_SPARSE_RCU_POINTER=y

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
b33eab08 e0ad61ec

+22 -13
+2 -2
include/net/ipip.h
··· 34 34 #ifdef CONFIG_IPV6_SIT_6RD 35 35 struct ip_tunnel_6rd_parm ip6rd; 36 36 #endif 37 - struct ip_tunnel_prl_entry *prl; /* potential router list */ 37 + struct ip_tunnel_prl_entry __rcu *prl; /* potential router list */ 38 38 unsigned int prl_count; /* # of entries in PRL */ 39 39 }; 40 40 41 41 struct ip_tunnel_prl_entry { 42 - struct ip_tunnel_prl_entry *next; 42 + struct ip_tunnel_prl_entry __rcu *next; 43 43 __be32 addr; 44 44 u16 flags; 45 45 struct rcu_head rcu_head;
+1 -1
include/net/xfrm.h
··· 1264 1264 int (*handler)(struct sk_buff *skb); 1265 1265 int (*err_handler)(struct sk_buff *skb, u32 info); 1266 1266 1267 - struct xfrm_tunnel *next; 1267 + struct xfrm_tunnel __rcu *next; 1268 1268 int priority; 1269 1269 }; 1270 1270
+19 -10
net/ipv4/tunnel4.c
··· 14 14 #include <net/protocol.h> 15 15 #include <net/xfrm.h> 16 16 17 - static struct xfrm_tunnel *tunnel4_handlers __read_mostly; 18 - static struct xfrm_tunnel *tunnel64_handlers __read_mostly; 17 + static struct xfrm_tunnel __rcu *tunnel4_handlers __read_mostly; 18 + static struct xfrm_tunnel __rcu *tunnel64_handlers __read_mostly; 19 19 static DEFINE_MUTEX(tunnel4_mutex); 20 20 21 - static inline struct xfrm_tunnel **fam_handlers(unsigned short family) 21 + static inline struct xfrm_tunnel __rcu **fam_handlers(unsigned short family) 22 22 { 23 23 return (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; 24 24 } 25 25 26 26 int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) 27 27 { 28 - struct xfrm_tunnel **pprev; 28 + struct xfrm_tunnel __rcu **pprev; 29 + struct xfrm_tunnel *t; 30 + 29 31 int ret = -EEXIST; 30 32 int priority = handler->priority; 31 33 32 34 mutex_lock(&tunnel4_mutex); 33 35 34 - for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) { 35 - if ((*pprev)->priority > priority) 36 + for (pprev = fam_handlers(family); 37 + (t = rcu_dereference_protected(*pprev, 38 + lockdep_is_held(&tunnel4_mutex))) != NULL; 39 + pprev = &t->next) { 40 + if (t->priority > priority) 36 41 break; 37 - if ((*pprev)->priority == priority) 42 + if (t->priority == priority) 38 43 goto err; 39 44 } 40 45 ··· 57 52 58 53 int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family) 59 54 { 60 - struct xfrm_tunnel **pprev; 55 + struct xfrm_tunnel __rcu **pprev; 56 + struct xfrm_tunnel *t; 61 57 int ret = -ENOENT; 62 58 63 59 mutex_lock(&tunnel4_mutex); 64 60 65 - for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) { 66 - if (*pprev == handler) { 61 + for (pprev = fam_handlers(family); 62 + (t = rcu_dereference_protected(*pprev, 63 + lockdep_is_held(&tunnel4_mutex))) != NULL; 64 + pprev = &t->next) { 65 + if (t == handler) { 67 66 *pprev = handler->next; 68 67 ret = 0; 69 68 break;