[ovs-dev] [PATCH 1/2] datapath: Add genl_dereference() and use it.

Jesse Gross jesse at nicira.com
Sat Nov 19 22:11:47 UTC 2011


We currently use a specialized version of what amounts to
genl_dereference() to protect the flow table.  This prepares to
propose genl_dereference() upstream and uses it instead of our
version.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/datapath.c                             |   25 ++++++++++------------
 datapath/linux/compat/include/linux/genetlink.h |    8 +++++++
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 1ea5d1e..0f503df 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -112,12 +112,6 @@ static struct datapath *get_dp(int dp_ifindex)
 	return dp;
 }
 
-/* Must be called with genl_mutex. */
-static struct flow_table *get_table_protected(struct datapath *dp)
-{
-	return rcu_dereference_protected(dp->table, lockdep_genl_is_held());
-}
-
 /* Must be called with rcu_read_lock or RTNL lock. */
 static struct vport *get_vport_protected(struct datapath *dp, u16 port_no)
 {
@@ -506,7 +500,7 @@ static int flush_flows(int dp_ifindex)
 	if (!dp)
 		return -ENODEV;
 
-	old_table = get_table_protected(dp);
+	old_table = genl_dereference(dp->table);
 	new_table = flow_tbl_alloc(TBL_MIN_BUCKETS);
 	if (!new_table)
 		return -ENOMEM;
@@ -828,7 +822,7 @@ static struct genl_ops dp_packet_genl_ops[] = {
 static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats)
 {
 	int i;
-	struct flow_table *table = get_table_protected(dp);
+	struct flow_table *table = genl_dereference(dp->table);
 
 	stats->n_flows = flow_tbl_count(table);
 
@@ -1016,7 +1010,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
 	if (!dp)
 		goto error;
 
-	table = get_table_protected(dp);
+	table = genl_dereference(dp->table);
 	flow = flow_tbl_lookup(table, &key, key_len);
 	if (!flow) {
 		struct sw_flow_actions *acts;
@@ -1034,7 +1028,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
 			if (!IS_ERR(new_table)) {
 				rcu_assign_pointer(dp->table, new_table);
 				flow_tbl_deferred_destroy(table);
-				table = get_table_protected(dp);
+				table = genl_dereference(dp->table);
 			}
 		}
 
@@ -1143,7 +1137,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
 	if (!dp)
 		return -ENODEV;
 
-	table = get_table_protected(dp);
+	table = genl_dereference(dp->table);
 	flow = flow_tbl_lookup(table, &key, key_len);
 	if (!flow)
 		return -ENOENT;
@@ -1178,7 +1172,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	if (!dp)
 		return -ENODEV;
 
-	table = get_table_protected(dp);
+	table = genl_dereference(dp->table);
 	flow = flow_tbl_lookup(table, &key, key_len);
 	if (!flow)
 		return -ENOENT;
@@ -1204,18 +1198,21 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
 	struct datapath *dp;
+	struct flow_table *table;
 
 	dp = get_dp(ovs_header->dp_ifindex);
 	if (!dp)
 		return -ENODEV;
 
+	table = genl_dereference(dp->table);
+
 	for (;;) {
 		struct sw_flow *flow;
 		u32 bucket, obj;
 
 		bucket = cb->args[0];
 		obj = cb->args[1];
-		flow = flow_tbl_next(get_table_protected(dp), &bucket, &obj);
+		flow = flow_tbl_next(table, &bucket, &obj);
 		if (!flow)
 			break;
 
@@ -1429,7 +1426,7 @@ err_destroy_local_port:
 err_destroy_percpu:
 	free_percpu(dp->stats_percpu);
 err_destroy_table:
-	flow_tbl_destroy(get_table_protected(dp));
+	flow_tbl_destroy(genl_dereference(dp->table));
 err_free_dp:
 	kfree(dp);
 err_put_module:
diff --git a/datapath/linux/compat/include/linux/genetlink.h b/datapath/linux/compat/include/linux/genetlink.h
index e45d0854..f7b96d9 100644
--- a/datapath/linux/compat/include/linux/genetlink.h
+++ b/datapath/linux/compat/include/linux/genetlink.h
@@ -12,4 +12,12 @@ static inline int lockdep_genl_is_held(void)
 }
 #endif
 
+/* This is also not upstream yet. */
+#ifndef genl_dereference
+#include <linux/rcupdate.h>
+
+#define genl_dereference(p)					\
+	rcu_dereference_protected(p, lockdep_genl_is_held())
+#endif
+
 #endif /* linux/genetlink.h wrapper */
-- 
1.7.5.4




More information about the dev mailing list