Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d57170b1 authored by Pravin B Shelar's avatar Pravin B Shelar Committed by Jesse Gross
Browse files

openvswitch: Use RCU lock for flow dump operation.



Flow dump operation is read-only operation.  There is no need to
take ovs-lock.  Following patch use rcu-lock for dumping flows.

Signed-off-by: default avatarPravin B Shelar <pshelar@nicira.com>
Signed-off-by: default avatarJesse Gross <jesse@nicira.com>
parent 2771399a
Loading
Loading
Loading
Loading
+9 −8
Original line number Original line Diff line number Diff line
@@ -1104,7 +1104,6 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
				  u32 seq, u32 flags, u8 cmd)
				  u32 seq, u32 flags, u8 cmd)
{
{
	const int skb_orig_len = skb->len;
	const int skb_orig_len = skb->len;
	const struct sw_flow_actions *sf_acts;
	struct nlattr *start;
	struct nlattr *start;
	struct ovs_flow_stats stats;
	struct ovs_flow_stats stats;
	struct ovs_header *ovs_header;
	struct ovs_header *ovs_header;
@@ -1113,8 +1112,6 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
	u8 tcp_flags;
	u8 tcp_flags;
	int err;
	int err;


	sf_acts = ovsl_dereference(flow->sf_acts);

	ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, cmd);
	ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, cmd);
	if (!ovs_header)
	if (!ovs_header)
		return -EMSGSIZE;
		return -EMSGSIZE;
@@ -1161,6 +1158,11 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
	 */
	 */
	start = nla_nest_start(skb, OVS_FLOW_ATTR_ACTIONS);
	start = nla_nest_start(skb, OVS_FLOW_ATTR_ACTIONS);
	if (start) {
	if (start) {
		const struct sw_flow_actions *sf_acts;

		sf_acts = rcu_dereference_check(flow->sf_acts,
						lockdep_ovsl_is_held());

		err = actions_to_attr(sf_acts->actions, sf_acts->actions_len, skb);
		err = actions_to_attr(sf_acts->actions, sf_acts->actions_len, skb);
		if (!err)
		if (!err)
			nla_nest_end(skb, start);
			nla_nest_end(skb, start);
@@ -1440,15 +1442,14 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
	struct datapath *dp;
	struct datapath *dp;
	struct flow_table *table;
	struct flow_table *table;


	ovs_lock();
	rcu_read_lock();
	dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
	dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
	if (!dp) {
	if (!dp) {
		ovs_unlock();
		rcu_read_unlock();
		return -ENODEV;
		return -ENODEV;
	}
	}


	table = ovsl_dereference(dp->table);
	table = rcu_dereference(dp->table);

	for (;;) {
	for (;;) {
		struct sw_flow *flow;
		struct sw_flow *flow;
		u32 bucket, obj;
		u32 bucket, obj;
@@ -1468,7 +1469,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
		cb->args[0] = bucket;
		cb->args[0] = bucket;
		cb->args[1] = obj;
		cb->args[1] = obj;
	}
	}
	ovs_unlock();
	rcu_read_unlock();
	return skb->len;
	return skb->len;
}
}