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 <je...@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

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to