diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 39 |
1 files changed, 5 insertions, 34 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 06ccc71c871f..7430ac26ec49 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -46,9 +46,6 @@ static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO]; | |||
46 | 46 | ||
47 | static struct kmem_cache *xfrm_dst_cache __read_mostly; | 47 | static struct kmem_cache *xfrm_dst_cache __read_mostly; |
48 | 48 | ||
49 | static HLIST_HEAD(xfrm_policy_gc_list); | ||
50 | static DEFINE_SPINLOCK(xfrm_policy_gc_lock); | ||
51 | |||
52 | static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); | 49 | static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); |
53 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); | 50 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); |
54 | static void xfrm_init_pmtu(struct dst_entry *dst); | 51 | static void xfrm_init_pmtu(struct dst_entry *dst); |
@@ -288,32 +285,6 @@ void xfrm_policy_destroy(struct xfrm_policy *policy) | |||
288 | } | 285 | } |
289 | EXPORT_SYMBOL(xfrm_policy_destroy); | 286 | EXPORT_SYMBOL(xfrm_policy_destroy); |
290 | 287 | ||
291 | static void xfrm_policy_gc_kill(struct xfrm_policy *policy) | ||
292 | { | ||
293 | atomic_inc(&policy->genid); | ||
294 | |||
295 | if (del_timer(&policy->timer)) | ||
296 | atomic_dec(&policy->refcnt); | ||
297 | |||
298 | xfrm_pol_put(policy); | ||
299 | } | ||
300 | |||
301 | static void xfrm_policy_gc_task(struct work_struct *work) | ||
302 | { | ||
303 | struct xfrm_policy *policy; | ||
304 | struct hlist_node *entry, *tmp; | ||
305 | struct hlist_head gc_list; | ||
306 | |||
307 | spin_lock_bh(&xfrm_policy_gc_lock); | ||
308 | gc_list.first = xfrm_policy_gc_list.first; | ||
309 | INIT_HLIST_HEAD(&xfrm_policy_gc_list); | ||
310 | spin_unlock_bh(&xfrm_policy_gc_lock); | ||
311 | |||
312 | hlist_for_each_entry_safe(policy, entry, tmp, &gc_list, bydst) | ||
313 | xfrm_policy_gc_kill(policy); | ||
314 | } | ||
315 | static DECLARE_WORK(xfrm_policy_gc_work, xfrm_policy_gc_task); | ||
316 | |||
317 | /* Rule must be locked. Release descentant resources, announce | 288 | /* Rule must be locked. Release descentant resources, announce |
318 | * entry dead. The rule must be unlinked from lists to the moment. | 289 | * entry dead. The rule must be unlinked from lists to the moment. |
319 | */ | 290 | */ |
@@ -322,11 +293,12 @@ static void xfrm_policy_kill(struct xfrm_policy *policy) | |||
322 | { | 293 | { |
323 | policy->walk.dead = 1; | 294 | policy->walk.dead = 1; |
324 | 295 | ||
325 | spin_lock_bh(&xfrm_policy_gc_lock); | 296 | atomic_inc(&policy->genid); |
326 | hlist_add_head(&policy->bydst, &xfrm_policy_gc_list); | ||
327 | spin_unlock_bh(&xfrm_policy_gc_lock); | ||
328 | 297 | ||
329 | schedule_work(&xfrm_policy_gc_work); | 298 | if (del_timer(&policy->timer)) |
299 | xfrm_pol_put(policy); | ||
300 | |||
301 | xfrm_pol_put(policy); | ||
330 | } | 302 | } |
331 | 303 | ||
332 | static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024; | 304 | static unsigned int xfrm_policy_hashmax __read_mostly = 1 * 1024 * 1024; |
@@ -2599,7 +2571,6 @@ static void xfrm_policy_fini(struct net *net) | |||
2599 | audit_info.sessionid = -1; | 2571 | audit_info.sessionid = -1; |
2600 | audit_info.secid = 0; | 2572 | audit_info.secid = 0; |
2601 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); | 2573 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); |
2602 | flush_work(&xfrm_policy_gc_work); | ||
2603 | 2574 | ||
2604 | WARN_ON(!list_empty(&net->xfrm.policy_all)); | 2575 | WARN_ON(!list_empty(&net->xfrm.policy_all)); |
2605 | 2576 | ||