aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index fbf8270619255..80828078733dd 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -13,6 +13,7 @@
*
*/
+#include <asm/bug.h>
#include <linux/config.h>
#include <linux/slab.h>
#include <linux/kmod.h>
@@ -300,20 +301,20 @@ static void xfrm_policy_gc_task(void *data)
static void xfrm_policy_kill(struct xfrm_policy *policy)
{
+ int dead;
+
write_lock_bh(&policy->lock);
- if (policy->dead) {
- write_unlock_bh(&policy->lock);
+ dead = policy->dead;
+ policy->dead = 1;
+ write_unlock_bh(&policy->lock);
+
+ if (unlikely(dead)) {
+ WARN_ON(1);
return;
}
- policy->dead = 1;
spin_lock(&xfrm_policy_gc_lock);
list_add(&policy->list, &xfrm_policy_gc_list);
- /*
- * Unlock the policy (out of order unlocking), to make sure
- * the GC context does not free it with an active lock:
- */
- write_unlock_bh(&policy->lock);
spin_unlock(&xfrm_policy_gc_lock);
schedule_work(&xfrm_policy_gc_work);