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 | |
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>
-rw-r--r-- | include/net/netns/xfrm.h | 3 | ||||
-rw-r--r-- | include/net/xfrm.h | 1 | ||||
-rw-r--r-- | net/key/af_key.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 4 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 16 |
5 files changed, 13 insertions, 13 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 80555351fe5e..2a383c8ba1af 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __NETNS_XFRM_H | 2 | #define __NETNS_XFRM_H |
3 | 3 | ||
4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
5 | #include <linux/wait.h> | ||
5 | #include <linux/workqueue.h> | 6 | #include <linux/workqueue.h> |
6 | 7 | ||
7 | struct netns_xfrm { | 8 | struct netns_xfrm { |
@@ -22,6 +23,8 @@ struct netns_xfrm { | |||
22 | struct work_struct state_hash_work; | 23 | struct work_struct state_hash_work; |
23 | struct hlist_head state_gc_list; | 24 | struct hlist_head state_gc_list; |
24 | struct work_struct state_gc_work; | 25 | struct work_struct state_gc_work; |
26 | |||
27 | wait_queue_head_t km_waitq; | ||
25 | }; | 28 | }; |
26 | 29 | ||
27 | #endif | 30 | #endif |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 9da89039832c..0d4353c11093 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -1459,7 +1459,6 @@ extern int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | |||
1459 | struct xfrm_kmaddress *k); | 1459 | struct xfrm_kmaddress *k); |
1460 | #endif | 1460 | #endif |
1461 | 1461 | ||
1462 | extern wait_queue_head_t km_waitq; | ||
1463 | extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); | 1462 | extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); |
1464 | extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); | 1463 | extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); |
1465 | extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); | 1464 | extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); |
diff --git a/net/key/af_key.c b/net/key/af_key.c index bde8aad4cc93..f202ba6c8dcb 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -1411,7 +1411,7 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg * | |||
1411 | spin_lock_bh(&x->lock); | 1411 | spin_lock_bh(&x->lock); |
1412 | if (x->km.state == XFRM_STATE_ACQ) { | 1412 | if (x->km.state == XFRM_STATE_ACQ) { |
1413 | x->km.state = XFRM_STATE_ERROR; | 1413 | x->km.state = XFRM_STATE_ERROR; |
1414 | wake_up(&km_waitq); | 1414 | wake_up(&init_net.xfrm.km_waitq); |
1415 | } | 1415 | } |
1416 | spin_unlock_bh(&x->lock); | 1416 | spin_unlock_bh(&x->lock); |
1417 | xfrm_state_put(x); | 1417 | xfrm_state_put(x); |
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: |