aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/addrlabel.c14
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
109static void ip6addrlbl_free_rcu(struct rcu_head *h)
110{
111 ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
112}
113
109static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p) 114static 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)
114static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p) 119static 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
120static 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 }