aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2014-11-11 18:55:16 -0500
committerPravin B Shelar <pshelar@nicira.com>2014-11-14 18:13:26 -0500
commit8ec609d8b561468691b60347ff594bd443ea58c0 (patch)
treef84c0baf1777f642408afa9df69bb69a34cb8d5d /net/openvswitch/datapath.c
parent19e7a3df7261c9b7ebced8163c383712d5b6ac6b (diff)
openvswitch: Convert dp rcu read operation to locked operations
dp read operations depends on ovs_dp_cmd_fill_info(). This API needs to looup vport to find dp name, but vport lookup can fail. Therefore to keep vport reference alive we need to take ovs lock. Introduced by commit 6093ae9abac1 ("openvswitch: Minimize dp and vport critical sections"). Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Acked-by: Andy Zhou <azhou@nicira.com>
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index e6d7255183eb..f9e556b56086 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1265,7 +1265,7 @@ static size_t ovs_dp_cmd_msg_size(void)
1265 return msgsize; 1265 return msgsize;
1266} 1266}
1267 1267
1268/* Called with ovs_mutex or RCU read lock. */ 1268/* Called with ovs_mutex. */
1269static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, 1269static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
1270 u32 portid, u32 seq, u32 flags, u8 cmd) 1270 u32 portid, u32 seq, u32 flags, u8 cmd)
1271{ 1271{
@@ -1555,7 +1555,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
1555 if (!reply) 1555 if (!reply)
1556 return -ENOMEM; 1556 return -ENOMEM;
1557 1557
1558 rcu_read_lock(); 1558 ovs_lock();
1559 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); 1559 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
1560 if (IS_ERR(dp)) { 1560 if (IS_ERR(dp)) {
1561 err = PTR_ERR(dp); 1561 err = PTR_ERR(dp);
@@ -1564,12 +1564,12 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
1564 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid, 1564 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
1565 info->snd_seq, 0, OVS_DP_CMD_NEW); 1565 info->snd_seq, 0, OVS_DP_CMD_NEW);
1566 BUG_ON(err < 0); 1566 BUG_ON(err < 0);
1567 rcu_read_unlock(); 1567 ovs_unlock();
1568 1568
1569 return genlmsg_reply(reply, info); 1569 return genlmsg_reply(reply, info);
1570 1570
1571err_unlock_free: 1571err_unlock_free:
1572 rcu_read_unlock(); 1572 ovs_unlock();
1573 kfree_skb(reply); 1573 kfree_skb(reply);
1574 return err; 1574 return err;
1575} 1575}
@@ -1581,8 +1581,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1581 int skip = cb->args[0]; 1581 int skip = cb->args[0];
1582 int i = 0; 1582 int i = 0;
1583 1583
1584 rcu_read_lock(); 1584 ovs_lock();
1585 list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) { 1585 list_for_each_entry(dp, &ovs_net->dps, list_node) {
1586 if (i >= skip && 1586 if (i >= skip &&
1587 ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid, 1587 ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
1588 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1588 cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -1590,7 +1590,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1590 break; 1590 break;
1591 i++; 1591 i++;
1592 } 1592 }
1593 rcu_read_unlock(); 1593 ovs_unlock();
1594 1594
1595 cb->args[0] = i; 1595 cb->args[0] = i;
1596 1596