aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
authorFan Du <fan.du@windriver.com>2013-11-07 04:47:50 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2013-12-06 00:45:06 -0500
commit283bc9f35bbbcb0e9ab4e6d2427da7f9f710d52d (patch)
tree8b580340bdc0d1f25f4a76dfc39c48760f3f307a /net/key
parent8d549c4f5d92d80fc6f888fd314e10972ae0ec37 (diff)
xfrm: Namespacify xfrm state/policy locks
By semantics, xfrm layer is fully name space aware, so will the locks, e.g. xfrm_state/pocliy_lock. Ensure exclusive access into state/policy link list for different name space with one global lock is not right in terms of semantics aspect at first place, as they are indeed mutually independent with each other, but also more seriously causes scalability problem. One practical scenario is on a Open Network Stack, more than hundreds of lxc tenants acts as routers within one host, a global xfrm_state/policy_lock becomes the bottleneck. But onces those locks are decoupled in a per-namespace fashion, locks contend is just with in specific name space scope, without causing additional SPD/SAD access delay for other name space. Also this patch improve scalability while as without changing original xfrm behavior. Signed-off-by: Fan Du <fan.du@windriver.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 3fa811c46913..9a039acf37e8 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1785,7 +1785,9 @@ static int pfkey_dump_sa(struct pfkey_sock *pfk)
1785 1785
1786static void pfkey_dump_sa_done(struct pfkey_sock *pfk) 1786static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
1787{ 1787{
1788 xfrm_state_walk_done(&pfk->dump.u.state); 1788 struct net *net = sock_net(&pfk->sk);
1789
1790 xfrm_state_walk_done(&pfk->dump.u.state, net);
1789} 1791}
1790 1792
1791static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) 1793static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
@@ -1861,7 +1863,7 @@ static u32 gen_reqid(struct net *net)
1861 reqid = IPSEC_MANUAL_REQID_MAX+1; 1863 reqid = IPSEC_MANUAL_REQID_MAX+1;
1862 xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN); 1864 xfrm_policy_walk_init(&walk, XFRM_POLICY_TYPE_MAIN);
1863 rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid); 1865 rc = xfrm_policy_walk(net, &walk, check_reqid, (void*)&reqid);
1864 xfrm_policy_walk_done(&walk); 1866 xfrm_policy_walk_done(&walk, net);
1865 if (rc != -EEXIST) 1867 if (rc != -EEXIST)
1866 return reqid; 1868 return reqid;
1867 } while (reqid != start); 1869 } while (reqid != start);
@@ -2660,7 +2662,9 @@ static int pfkey_dump_sp(struct pfkey_sock *pfk)
2660 2662
2661static void pfkey_dump_sp_done(struct pfkey_sock *pfk) 2663static void pfkey_dump_sp_done(struct pfkey_sock *pfk)
2662{ 2664{
2663 xfrm_policy_walk_done(&pfk->dump.u.policy); 2665 struct net *net = sock_net((struct sock *)pfk);
2666
2667 xfrm_policy_walk_done(&pfk->dump.u.policy, net);
2664} 2668}
2665 2669
2666static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) 2670static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
@@ -3570,6 +3574,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
3570 struct sk_buff *skb = NULL; 3574 struct sk_buff *skb = NULL;
3571 struct sadb_msg *hdr = NULL; 3575 struct sadb_msg *hdr = NULL;
3572 int err; 3576 int err;
3577 struct net *net = sock_net(sk);
3573 3578
3574 err = -EOPNOTSUPP; 3579 err = -EOPNOTSUPP;
3575 if (msg->msg_flags & MSG_OOB) 3580 if (msg->msg_flags & MSG_OOB)
@@ -3592,9 +3597,9 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
3592 if (!hdr) 3597 if (!hdr)
3593 goto out; 3598 goto out;
3594 3599
3595 mutex_lock(&xfrm_cfg_mutex); 3600 mutex_lock(&net->xfrm.xfrm_cfg_mutex);
3596 err = pfkey_process(sk, skb, hdr); 3601 err = pfkey_process(sk, skb, hdr);
3597 mutex_unlock(&xfrm_cfg_mutex); 3602 mutex_unlock(&net->xfrm.xfrm_cfg_mutex);
3598 3603
3599out: 3604out:
3600 if (err && hdr && pfkey_error(hdr, err, sk) == 0) 3605 if (err && hdr && pfkey_error(hdr, err, sk) == 0)