diff options
-rw-r--r-- | net/ipv6/addrlabel.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 38674121ae5f..a3c5a72218fd 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -106,6 +106,11 @@ static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) | |||
106 | kfree(p); | 106 | kfree(p); |
107 | } | 107 | } |
108 | 108 | ||
109 | static void ip6addrlbl_free_rcu(struct rcu_head *h) | ||
110 | { | ||
111 | ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu)); | ||
112 | } | ||
113 | |||
109 | static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p) | 114 | static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p) |
110 | { | 115 | { |
111 | return atomic_inc_not_zero(&p->refcnt); | 116 | return atomic_inc_not_zero(&p->refcnt); |
@@ -114,12 +119,7 @@ static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p) | |||
114 | static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p) | 119 | static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p) |
115 | { | 120 | { |
116 | if (atomic_dec_and_test(&p->refcnt)) | 121 | if (atomic_dec_and_test(&p->refcnt)) |
117 | ip6addrlbl_free(p); | 122 | call_rcu(&p->rcu, ip6addrlbl_free_rcu); |
118 | } | ||
119 | |||
120 | static void ip6addrlbl_free_rcu(struct rcu_head *h) | ||
121 | { | ||
122 | ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu)); | ||
123 | } | 123 | } |
124 | 124 | ||
125 | /* Find label */ | 125 | /* Find label */ |
@@ -240,7 +240,6 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace) | |||
240 | } | 240 | } |
241 | hlist_replace_rcu(&p->list, &newp->list); | 241 | hlist_replace_rcu(&p->list, &newp->list); |
242 | ip6addrlbl_put(p); | 242 | ip6addrlbl_put(p); |
243 | call_rcu(&p->rcu, ip6addrlbl_free_rcu); | ||
244 | goto out; | 243 | goto out; |
245 | } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) || | 244 | } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) || |
246 | (p->prefixlen < newp->prefixlen)) { | 245 | (p->prefixlen < newp->prefixlen)) { |
@@ -300,7 +299,6 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, | |||
300 | ipv6_addr_equal(&p->prefix, prefix)) { | 299 | ipv6_addr_equal(&p->prefix, prefix)) { |
301 | hlist_del_rcu(&p->list); | 300 | hlist_del_rcu(&p->list); |
302 | ip6addrlbl_put(p); | 301 | ip6addrlbl_put(p); |
303 | call_rcu(&p->rcu, ip6addrlbl_free_rcu); | ||
304 | ret = 0; | 302 | ret = 0; |
305 | break; | 303 | break; |
306 | } | 304 | } |