diff options
-rw-r--r-- | net/ipv6/addrconf_core.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index d873ceea86e6..ca09bf49ac68 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c | |||
@@ -133,6 +133,14 @@ static void snmp6_free_dev(struct inet6_dev *idev) | |||
133 | free_percpu(idev->stats.ipv6); | 133 | free_percpu(idev->stats.ipv6); |
134 | } | 134 | } |
135 | 135 | ||
136 | static void in6_dev_finish_destroy_rcu(struct rcu_head *head) | ||
137 | { | ||
138 | struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu); | ||
139 | |||
140 | snmp6_free_dev(idev); | ||
141 | kfree(idev); | ||
142 | } | ||
143 | |||
136 | /* Nobody refers to this device, we may destroy it. */ | 144 | /* Nobody refers to this device, we may destroy it. */ |
137 | 145 | ||
138 | void in6_dev_finish_destroy(struct inet6_dev *idev) | 146 | void in6_dev_finish_destroy(struct inet6_dev *idev) |
@@ -151,7 +159,6 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) | |||
151 | pr_warn("Freeing alive inet6 device %p\n", idev); | 159 | pr_warn("Freeing alive inet6 device %p\n", idev); |
152 | return; | 160 | return; |
153 | } | 161 | } |
154 | snmp6_free_dev(idev); | 162 | call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu); |
155 | kfree_rcu(idev, rcu); | ||
156 | } | 163 | } |
157 | EXPORT_SYMBOL(in6_dev_finish_destroy); | 164 | EXPORT_SYMBOL(in6_dev_finish_destroy); |