[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