[ovs-dev] [PATCH 11/12] datapath: Check locks on access to flow table.

Jesse Gross jesse at nicira.com
Sun Dec 12 20:53:06 UTC 2010


When accessing the flow table without holding rcu_read_lcok
we need to hold the lock on the datapath.  This enables lockdep
to validate that that is the case.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/datapath.c |   25 +++++++++++++++----------
 1 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index db68057..dfae8d1 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -94,6 +94,11 @@ static struct datapath *get_dp_locked(int dp_idx)
 	return dp;
 }
 
+static struct tbl *get_table_protected(struct datapath *dp)
+{
+	return rcu_dereference_protected(dp->table, lockdep_is_held(&dp->mutex));
+}
+
 /* Must be called with rcu_read_lock or RTNL lock. */
 const char *dp_name(const struct datapath *dp)
 {
@@ -643,7 +648,7 @@ err:
 
 static int flush_flows(struct datapath *dp)
 {
-	struct tbl *old_table = rcu_dereference(dp->table);
+	struct tbl *old_table = get_table_protected(dp);
 	struct tbl *new_table;
 
 	new_table = tbl_create(0);
@@ -790,7 +795,7 @@ static void clear_stats(struct sw_flow *flow)
 
 static int expand_table(struct datapath *dp)
 {
-	struct tbl *old_table = rcu_dereference(dp->table);
+	struct tbl *old_table = get_table_protected(dp);
 	struct tbl *new_table;
 
 	new_table = tbl_expand(old_table);
@@ -811,7 +816,7 @@ static int do_put_flow(struct datapath *dp, struct odp_flow_put *uf,
 	struct tbl *table;
 	int error;
 
-	table = rcu_dereference(dp->table);
+	table = get_table_protected(dp);
 	flow_node = tbl_lookup(table, &uf->flow.key, flow_hash(&uf->flow.key), flow_cmp);
 	if (!flow_node) {
 		/* No such flow. */
@@ -826,7 +831,7 @@ static int do_put_flow(struct datapath *dp, struct odp_flow_put *uf,
 			error = expand_table(dp);
 			if (error)
 				goto error;
-			table = rcu_dereference(dp->table);
+			table = get_table_protected(dp);
 		}
 
 		/* Allocate flow. */
@@ -962,7 +967,7 @@ static int answer_query(struct sw_flow *flow, u32 query_flags,
 
 static struct sw_flow *do_del_flow(struct datapath *dp, struct odp_flow_key *key)
 {
-	struct tbl *table = rcu_dereference(dp->table);
+	struct tbl *table = get_table_protected(dp);
 	struct tbl_node *flow_node;
 	int error;
 
@@ -1001,7 +1006,7 @@ static int del_flow(struct datapath *dp, struct odp_flow __user *ufp)
 
 static int do_query_flows(struct datapath *dp, const struct odp_flowvec *flowvec)
 {
-	struct tbl *table = rcu_dereference(dp->table);
+	struct tbl *table = get_table_protected(dp);
 	u32 i;
 
 	for (i = 0; i < flowvec->n_flows; i++) {
@@ -1060,7 +1065,7 @@ static int do_list_flows(struct datapath *dp, const struct odp_flowvec *flowvec)
 	cbdata.n_flows = flowvec->n_flows;
 	cbdata.listed_flows = 0;
 
-	error = tbl_foreach(rcu_dereference(dp->table), list_flow, &cbdata);
+	error = tbl_foreach(get_table_protected(dp), list_flow, &cbdata);
 	return error ? error : cbdata.listed_flows;
 }
 
@@ -1166,7 +1171,7 @@ static int execute_packet(struct datapath *dp, const struct odp_execute __user *
 
 static int get_dp_stats(struct datapath *dp, struct odp_stats __user *statsp)
 {
-	struct tbl *table = rcu_dereference(dp->table);
+	struct tbl *table = get_table_protected(dp);
 	struct odp_stats stats;
 	int i;
 
@@ -1588,7 +1593,7 @@ static int compat_query_flows(struct datapath *dp,
 			      struct compat_odp_flow __user *flows,
 			      u32 n_flows)
 {
-	struct tbl *table = rcu_dereference(dp->table);
+	struct tbl *table = get_table_protected(dp);
 	u32 i;
 
 	for (i = 0; i < n_flows; i++) {
@@ -1648,7 +1653,7 @@ static int compat_list_flows(struct datapath *dp,
 	cbdata.n_flows = n_flows;
 	cbdata.listed_flows = 0;
 
-	error = tbl_foreach(rcu_dereference(dp->table), compat_list_flow, &cbdata);
+	error = tbl_foreach(get_table_protected(dp), compat_list_flow, &cbdata);
 	return error ? error : cbdata.listed_flows;
 }
 
-- 
1.7.1





More information about the dev mailing list