diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:21:01 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:21:01 -0500 |
commit | 50a30657fd7ee77a94a6bf0ad86eba7c37c3032e (patch) | |
tree | 7eb9165881b9082588eb2c373e9ed2ebc013321e /net/xfrm | |
parent | c78371441c0d957f54c9f8a35b3ee5a378d14808 (diff) |
netns xfrm: per-netns km_waitq
Disallow spurious wakeups in __xfrm_lookup().
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 4 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 16 |
2 files changed, 9 insertions, 11 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8e7671b9e76e..cf2bf3aa7ab4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1691,11 +1691,11 @@ restart: | |||
1691 | if (err == -EAGAIN && (flags & XFRM_LOOKUP_WAIT)) { | 1691 | if (err == -EAGAIN && (flags & XFRM_LOOKUP_WAIT)) { |
1692 | DECLARE_WAITQUEUE(wait, current); | 1692 | DECLARE_WAITQUEUE(wait, current); |
1693 | 1693 | ||
1694 | add_wait_queue(&km_waitq, &wait); | 1694 | add_wait_queue(&init_net.xfrm.km_waitq, &wait); |
1695 | set_current_state(TASK_INTERRUPTIBLE); | 1695 | set_current_state(TASK_INTERRUPTIBLE); |
1696 | schedule(); | 1696 | schedule(); |
1697 | set_current_state(TASK_RUNNING); | 1697 | set_current_state(TASK_RUNNING); |
1698 | remove_wait_queue(&km_waitq, &wait); | 1698 | remove_wait_queue(&init_net.xfrm.km_waitq, &wait); |
1699 | 1699 | ||
1700 | nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family); | 1700 | nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family); |
1701 | 1701 | ||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 69c0b06bf756..24bd89e76236 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -170,9 +170,6 @@ out_unlock: | |||
170 | mutex_unlock(&hash_resize_mutex); | 170 | mutex_unlock(&hash_resize_mutex); |
171 | } | 171 | } |
172 | 172 | ||
173 | DECLARE_WAIT_QUEUE_HEAD(km_waitq); | ||
174 | EXPORT_SYMBOL(km_waitq); | ||
175 | |||
176 | static DEFINE_RWLOCK(xfrm_state_afinfo_lock); | 173 | static DEFINE_RWLOCK(xfrm_state_afinfo_lock); |
177 | static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO]; | 174 | static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO]; |
178 | 175 | ||
@@ -399,7 +396,7 @@ static void xfrm_state_gc_task(struct work_struct *work) | |||
399 | hlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist) | 396 | hlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist) |
400 | xfrm_state_gc_destroy(x); | 397 | xfrm_state_gc_destroy(x); |
401 | 398 | ||
402 | wake_up(&km_waitq); | 399 | wake_up(&net->xfrm.km_waitq); |
403 | } | 400 | } |
404 | 401 | ||
405 | static inline unsigned long make_jiffies(long secs) | 402 | static inline unsigned long make_jiffies(long secs) |
@@ -470,7 +467,7 @@ resched: | |||
470 | expired: | 467 | expired: |
471 | if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) { | 468 | if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) { |
472 | x->km.state = XFRM_STATE_EXPIRED; | 469 | x->km.state = XFRM_STATE_EXPIRED; |
473 | wake_up(&km_waitq); | 470 | wake_up(&init_net.xfrm.km_waitq); |
474 | next = 2; | 471 | next = 2; |
475 | goto resched; | 472 | goto resched; |
476 | } | 473 | } |
@@ -638,7 +635,7 @@ restart: | |||
638 | 635 | ||
639 | out: | 636 | out: |
640 | spin_unlock_bh(&xfrm_state_lock); | 637 | spin_unlock_bh(&xfrm_state_lock); |
641 | wake_up(&km_waitq); | 638 | wake_up(&init_net.xfrm.km_waitq); |
642 | return err; | 639 | return err; |
643 | } | 640 | } |
644 | EXPORT_SYMBOL(xfrm_state_flush); | 641 | EXPORT_SYMBOL(xfrm_state_flush); |
@@ -929,7 +926,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) | |||
929 | if (x->replay_maxage) | 926 | if (x->replay_maxage) |
930 | mod_timer(&x->rtimer, jiffies + x->replay_maxage); | 927 | mod_timer(&x->rtimer, jiffies + x->replay_maxage); |
931 | 928 | ||
932 | wake_up(&km_waitq); | 929 | wake_up(&init_net.xfrm.km_waitq); |
933 | 930 | ||
934 | init_net.xfrm.state_num++; | 931 | init_net.xfrm.state_num++; |
935 | 932 | ||
@@ -1743,7 +1740,7 @@ void km_state_expired(struct xfrm_state *x, int hard, u32 pid) | |||
1743 | km_state_notify(x, &c); | 1740 | km_state_notify(x, &c); |
1744 | 1741 | ||
1745 | if (hard) | 1742 | if (hard) |
1746 | wake_up(&km_waitq); | 1743 | wake_up(&init_net.xfrm.km_waitq); |
1747 | } | 1744 | } |
1748 | 1745 | ||
1749 | EXPORT_SYMBOL(km_state_expired); | 1746 | EXPORT_SYMBOL(km_state_expired); |
@@ -1794,7 +1791,7 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) | |||
1794 | km_policy_notify(pol, dir, &c); | 1791 | km_policy_notify(pol, dir, &c); |
1795 | 1792 | ||
1796 | if (hard) | 1793 | if (hard) |
1797 | wake_up(&km_waitq); | 1794 | wake_up(&init_net.xfrm.km_waitq); |
1798 | } | 1795 | } |
1799 | EXPORT_SYMBOL(km_policy_expired); | 1796 | EXPORT_SYMBOL(km_policy_expired); |
1800 | 1797 | ||
@@ -2089,6 +2086,7 @@ int __net_init xfrm_state_init(struct net *net) | |||
2089 | INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); | 2086 | INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); |
2090 | INIT_HLIST_HEAD(&net->xfrm.state_gc_list); | 2087 | INIT_HLIST_HEAD(&net->xfrm.state_gc_list); |
2091 | INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task); | 2088 | INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task); |
2089 | init_waitqueue_head(&net->xfrm.km_waitq); | ||
2092 | return 0; | 2090 | return 0; |
2093 | 2091 | ||
2094 | out_byspi: | 2092 | out_byspi: |