[ovs-dev] [PATCH v2 3/3] dpif-netdev: removed hmap flow_table
Daniele Di Proietto
ddiproietto at vmware.com
Thu May 22 17:13:24 UTC 2014
As suggested by others, we can use the classifier, instead of the
hash table, as the only flow container in dpif-netdev
Signed-off-by: Daniele Di Proietto <ddiproietto at vmware.com>
---
lib/dpif-netdev.c | 73 +++++++++++++++++++++++++++++--------------------------
1 file changed, 38 insertions(+), 35 deletions(-)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index df62912..9b30d4f 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -134,15 +134,14 @@ struct dp_netdev {
/* Flows.
*
- * Readers of 'cls' and 'flow_table' must take a 'cls->rwlock' read lock.
+ * Readers of 'cls' must take a 'cls->rwlock' read lock.
*
- * Writers of 'cls' and 'flow_table' must take the 'flow_mutex' and then
+ * Writers of 'cls' must take the 'flow_mutex' and then
* the 'cls->rwlock' write lock. (The outer 'flow_mutex' allows writers to
- * atomically perform multiple operations on 'cls' and 'flow_table'.)
+ * atomically perform multiple operations on 'cls'.)
*/
struct ovs_mutex flow_mutex;
struct classifier cls; /* Classifier. Protected by cls.rwlock. */
- struct hmap flow_table OVS_GUARDED; /* Flow table. */
/* Queues.
*
@@ -202,7 +201,7 @@ struct dp_netdev_port {
char *type; /* Port type as requested by user. */
};
-/* A flow in dp_netdev's 'flow_table'.
+/* A flow in dp_netdev's flow_table.
*
*
* Thread-safety
@@ -245,8 +244,6 @@ struct dp_netdev_flow {
/* Packet classification. */
const struct cls_rule cr; /* In owning dp_netdev's 'cls'. */
- /* Hash table index by unmasked flow. */
- const struct hmap_node node; /* In owning dp_netdev's 'flow_table'. */
const struct flow flow; /* The flow that created this entry. */
/* Statistics.
@@ -463,7 +460,6 @@ create_dp_netdev(const char *name, const struct dpif_class *class,
ovs_mutex_init(&dp->flow_mutex);
classifier_init(&dp->cls, NULL);
- hmap_init(&dp->flow_table);
fat_rwlock_init(&dp->queue_rwlock);
@@ -565,7 +561,6 @@ dp_netdev_free(struct dp_netdev *dp)
fat_rwlock_destroy(&dp->queue_rwlock);
classifier_destroy(&dp->cls);
- hmap_destroy(&dp->flow_table);
ovs_mutex_destroy(&dp->flow_mutex);
seq_destroy(dp->port_seq);
cmap_destroy(&dp->ports);
@@ -620,7 +615,7 @@ dpif_netdev_get_stats(const struct dpif *dpif, struct dpif_dp_stats *stats)
size_t i;
fat_rwlock_rdlock(&dp->cls.rwlock);
- stats->n_flows = hmap_count(&dp->flow_table);
+ stats->n_flows = classifier_count(&dp->cls);
fat_rwlock_unlock(&dp->cls.rwlock);
stats->n_hit = stats->n_missed = stats->n_lost = 0;
@@ -939,22 +934,22 @@ dp_netdev_remove_flow(struct dp_netdev *dp, struct dp_netdev_flow *flow)
OVS_REQUIRES(dp->flow_mutex)
{
struct cls_rule *cr = CONST_CAST(struct cls_rule *, &flow->cr);
- struct hmap_node *node = CONST_CAST(struct hmap_node *, &flow->node);
classifier_remove(&dp->cls, cr);
- hmap_remove(&dp->flow_table, node);
ovsrcu_postpone(dp_netdev_flow_free, flow);
}
static void
dp_netdev_flow_flush(struct dp_netdev *dp)
{
- struct dp_netdev_flow *netdev_flow, *next;
+ struct dp_netdev_flow *flow, *next_flow;
+ struct cls_cursor cursor;
ovs_mutex_lock(&dp->flow_mutex);
fat_rwlock_wrlock(&dp->cls.rwlock);
- HMAP_FOR_EACH_SAFE (netdev_flow, next, node, &dp->flow_table) {
- dp_netdev_remove_flow(dp, netdev_flow);
+ cls_cursor_init(&cursor, &dp->cls, NULL);
+ CLS_CURSOR_FOR_EACH_SAFE (flow, next_flow, cr, &cursor) {
+ dp_netdev_remove_flow(dp, flow);
}
fat_rwlock_unlock(&dp->cls.rwlock);
ovs_mutex_unlock(&dp->flow_mutex);
@@ -1072,11 +1067,16 @@ dp_netdev_find_flow(const struct dp_netdev *dp, const struct flow *flow)
{
struct dp_netdev_flow *netdev_flow;
- HMAP_FOR_EACH_WITH_HASH (netdev_flow, node, flow_hash(flow, 0),
- &dp->flow_table) {
- if (flow_equal(&netdev_flow->flow, flow)) {
- return netdev_flow;
- }
+ netdev_flow = dp_netdev_flow_cast(classifier_lookup(&dp->cls, flow, NULL));
+
+ if (!netdev_flow) {
+ return NULL;
+ }
+
+ if (flow_equal(&netdev_flow->flow, flow)) {
+ return netdev_flow;
+ } else {
+ VLOG_WARN("classifier_lookup returned different flow");
}
return NULL;
@@ -1253,9 +1253,6 @@ dp_netdev_flow_add(struct dp_netdev *dp, const struct flow *flow,
fat_rwlock_wrlock(&dp->cls.rwlock);
classifier_insert(&dp->cls,
CONST_CAST(struct cls_rule *, &netdev_flow->cr));
- hmap_insert(&dp->flow_table,
- CONST_CAST(struct hmap_node *, &netdev_flow->node),
- flow_hash(flow, 0));
fat_rwlock_unlock(&dp->cls.rwlock);
return 0;
@@ -1303,7 +1300,7 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put)
netdev_flow = dp_netdev_lookup_flow(dp, &miniflow);
if (!netdev_flow) {
if (put->flags & DPIF_FP_CREATE) {
- if (hmap_count(&dp->flow_table) < MAX_FLOWS) {
+ if (classifier_count(&dp->cls) < MAX_FLOWS) {
if (put->stats) {
memset(put->stats, 0, sizeof *put->stats);
}
@@ -1379,8 +1376,11 @@ dpif_netdev_flow_del(struct dpif *dpif, const struct dpif_flow_del *del)
struct dpif_netdev_flow_dump {
struct dpif_flow_dump up;
- uint32_t bucket;
- uint32_t offset;
+ uint32_t subtbl_bucketp,
+ subtbl_offsetp,
+ match_bucketp,
+ match_offsetp,
+ pri_offset;
int status;
struct ovs_mutex mutex;
};
@@ -1396,11 +1396,8 @@ dpif_netdev_flow_dump_create(const struct dpif *dpif_)
{
struct dpif_netdev_flow_dump *dump;
- dump = xmalloc(sizeof *dump);
+ dump = xzalloc(sizeof *dump);
dpif_flow_dump_init(&dump->up, dpif_);
- dump->bucket = 0;
- dump->offset = 0;
- dump->status = 0;
ovs_mutex_init(&dump->mutex);
return &dump->up;
@@ -1469,15 +1466,21 @@ dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread *thread_,
ovs_mutex_lock(&dump->mutex);
error = dump->status;
if (!error) {
- struct hmap_node *node;
+ struct cls_rule *rule;
fat_rwlock_rdlock(&dp->cls.rwlock);
- node = hmap_at_position(&dp->flow_table, &dump->bucket, &dump->offset);
- if (node) {
- netdev_flow = CONTAINER_OF(node, struct dp_netdev_flow, node);
+ rule = classifier_at_position(&dp->cls,
+ &dump->subtbl_bucketp,
+ &dump->subtbl_offsetp,
+ &dump->match_bucketp,
+ &dump->match_offsetp,
+ &dump->pri_offset);
+
+ if (rule) {
+ netdev_flow = CONTAINER_OF(rule, struct dp_netdev_flow, cr);
}
fat_rwlock_unlock(&dp->cls.rwlock);
- if (!node) {
+ if (!rule) {
dump->status = error = EOF;
}
}
--
2.0.0.rc0
More information about the dev
mailing list