Commit 8ec609d8 authored by Pravin B Shelar's avatar Pravin B Shelar

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 6093ae9a ("openvswitch: Minimize
dp and vport critical sections").
Signed-off-by: default avatarPravin B Shelar <pshelar@nicira.com>
Acked-by: default avatarAndy Zhou <azhou@nicira.com>
parent 19e7a3df
...@@ -1265,7 +1265,7 @@ static size_t ovs_dp_cmd_msg_size(void) ...@@ -1265,7 +1265,7 @@ static size_t ovs_dp_cmd_msg_size(void)
return msgsize; return msgsize;
} }
/* Called with ovs_mutex or RCU read lock. */ /* Called with ovs_mutex. */
static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
u32 portid, u32 seq, u32 flags, u8 cmd) u32 portid, u32 seq, u32 flags, u8 cmd)
{ {
...@@ -1555,7 +1555,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) ...@@ -1555,7 +1555,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
if (!reply) if (!reply)
return -ENOMEM; return -ENOMEM;
rcu_read_lock(); ovs_lock();
dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
if (IS_ERR(dp)) { if (IS_ERR(dp)) {
err = PTR_ERR(dp); err = PTR_ERR(dp);
...@@ -1564,12 +1564,12 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) ...@@ -1564,12 +1564,12 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid, err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
info->snd_seq, 0, OVS_DP_CMD_NEW); info->snd_seq, 0, OVS_DP_CMD_NEW);
BUG_ON(err < 0); BUG_ON(err < 0);
rcu_read_unlock(); ovs_unlock();
return genlmsg_reply(reply, info); return genlmsg_reply(reply, info);
err_unlock_free: err_unlock_free:
rcu_read_unlock(); ovs_unlock();
kfree_skb(reply); kfree_skb(reply);
return err; return err;
} }
...@@ -1581,8 +1581,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -1581,8 +1581,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
int skip = cb->args[0]; int skip = cb->args[0];
int i = 0; int i = 0;
rcu_read_lock(); ovs_lock();
list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) { list_for_each_entry(dp, &ovs_net->dps, list_node) {
if (i >= skip && if (i >= skip &&
ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid, ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, 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,7 +1590,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
break; break;
i++; i++;
} }
rcu_read_unlock(); ovs_unlock();
cb->args[0] = i; cb->args[0] = i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment