aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2013-07-30 18:42:19 -0400
committerJesse Gross <jesse@nicira.com>2013-08-23 19:37:59 -0400
commit59a35d60af3ab80037ad2fa2d60671ce2818b9e4 (patch)
treef37b0c0b2a892d82f75e82dfb0b0fc5dc76511f1
parentd57170b1b1d71382a0d9cf31b01364a97add3f19 (diff)
openvswitch: Use RCU lock for dp dump operation.
RCUfy dp-dump operation which is already read-only. This makes all ovs dump operations lockless. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
-rw-r--r--net/openvswitch/datapath.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index e6fb866e4ed4..9d97ef3c9830 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -951,9 +951,10 @@ static struct genl_ops dp_packet_genl_ops[] = {
951 951
952static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats) 952static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats)
953{ 953{
954 struct flow_table *table;
954 int i; 955 int i;
955 struct flow_table *table = ovsl_dereference(dp->table);
956 956
957 table = rcu_dereference_check(dp->table, lockdep_ovsl_is_held());
957 stats->n_flows = ovs_flow_tbl_count(table); 958 stats->n_flows = ovs_flow_tbl_count(table);
958 959
959 stats->n_hit = stats->n_missed = stats->n_lost = 0; 960 stats->n_hit = stats->n_missed = stats->n_lost = 0;
@@ -1665,7 +1666,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
1665 goto err_destroy_local_port; 1666 goto err_destroy_local_port;
1666 1667
1667 ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id); 1668 ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id);
1668 list_add_tail(&dp->list_node, &ovs_net->dps); 1669 list_add_tail_rcu(&dp->list_node, &ovs_net->dps);
1669 1670
1670 ovs_unlock(); 1671 ovs_unlock();
1671 1672
@@ -1703,7 +1704,7 @@ static void __dp_destroy(struct datapath *dp)
1703 ovs_dp_detach_port(vport); 1704 ovs_dp_detach_port(vport);
1704 } 1705 }
1705 1706
1706 list_del(&dp->list_node); 1707 list_del_rcu(&dp->list_node);
1707 1708
1708 /* OVSP_LOCAL is datapath internal port. We need to make sure that 1709 /* OVSP_LOCAL is datapath internal port. We need to make sure that
1709 * all port in datapath are destroyed first before freeing datapath. 1710 * all port in datapath are destroyed first before freeing datapath.
@@ -1808,8 +1809,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1808 int skip = cb->args[0]; 1809 int skip = cb->args[0];
1809 int i = 0; 1810 int i = 0;
1810 1811
1811 ovs_lock(); 1812 rcu_read_lock();
1812 list_for_each_entry(dp, &ovs_net->dps, list_node) { 1813 list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) {
1813 if (i >= skip && 1814 if (i >= skip &&
1814 ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid, 1815 ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
1815 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1816 cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -1817,7 +1818,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1817 break; 1818 break;
1818 i++; 1819 i++;
1819 } 1820 }
1820 ovs_unlock(); 1821 rcu_read_unlock();
1821 1822
1822 cb->args[0] = i; 1823 cb->args[0] = i;
1823 1824