Along with flow-table rehashing OVS can compact masks array.  This
allows us to calculate highest index for mask array.

Signed-off-by: Pravin B Shelar <pshe...@nicira.com>
---
 datapath/flow_table.c |   24 ++++++++++++++++++++----
 datapath/flow_table.h |    2 +-
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/datapath/flow_table.c b/datapath/flow_table.c
index c8bd9d1..ea4100f 100644
--- a/datapath/flow_table.c
+++ b/datapath/flow_table.c
@@ -230,6 +230,7 @@ static struct mask_array *tbl_mask_array_alloc(int size)
 
        new->count = 0;
        new->max = size;
+       new->hi_index = 0;
 
        return new;
 }
@@ -252,6 +253,8 @@ static int tbl_mask_array_realloc(struct flow_table *tbl, 
int size)
                                new->masks[new->count++] = old->masks[i];
                }
        }
+
+       new->hi_index = new->count;
        rcu_assign_pointer(tbl->mask_array, new);
 
        if (old)
@@ -260,6 +263,17 @@ static int tbl_mask_array_realloc(struct flow_table *tbl, 
int size)
        return 0;
 }
 
+static void tbl_mask_array_compact(struct flow_table *tbl)
+{
+       struct mask_array *ma;
+       int size;
+
+       ma = ovsl_dereference(tbl->mask_array);
+
+       size = roundup(ma->count, MASK_ARRAY_SIZE_MIN);
+       tbl_mask_array_realloc(tbl, size);
+}
+
 int ovs_flow_tbl_init(struct flow_table *table)
 {
        struct table_instance *ti;
@@ -524,7 +538,7 @@ static struct sw_flow *flow_lookup(struct flow_table *tbl,
        struct sw_flow *flow;
        int i;
 
-       for (i = 0; i < ma->max; i++) {
+       for (i = 0; i < ma->hi_index; i++) {
                struct sw_flow_mask *mask;
 
                mask = rcu_dereference_ovsl(ma->masks[i]);
@@ -648,7 +662,7 @@ static void flow_mask_remove(struct flow_table *tbl, struct 
sw_flow_mask *mask)
                        int i;
 
                        ma = ovsl_dereference(tbl->mask_array);
-                       for (i = 0; i < ma->max; i++) {
+                       for (i = 0; i < ma->hi_index; i++) {
                                if (mask == ovsl_dereference(ma->masks[i])) {
                                        RCU_INIT_POINTER(ma->masks[i], NULL);
                                        ma->count--;
@@ -705,7 +719,7 @@ static struct sw_flow_mask *flow_mask_find(const struct 
flow_table *tbl,
        int i;
 
        ma = ovsl_dereference(tbl->mask_array);
-       for (i = 0; i < ma->max; i++) {
+       for (i = 0; i < ma->hi_index; i++) {
                struct sw_flow_mask *t;
 
                t = ovsl_dereference(ma->masks[i]);
@@ -753,8 +767,9 @@ static int flow_mask_insert(struct flow_table *tbl, struct 
sw_flow *flow,
 
                        t = ovsl_dereference(ma->masks[i]);
                        if (!t) {
-                               rcu_assign_pointer(ma->masks[i], mask);
                                ma->count++;
+                               ma->hi_index = i + 1;
+                               rcu_assign_pointer(ma->masks[i], mask);
                                break;
                        }
                }
@@ -794,6 +809,7 @@ int ovs_flow_tbl_insert(struct flow_table *table, struct 
sw_flow *flow,
        if (new_ti) {
                rcu_assign_pointer(table->ti, new_ti);
                table_instance_destroy(ti, true);
+               tbl_mask_array_compact(table);
                table->last_rehash = jiffies;
        }
        return 0;
diff --git a/datapath/flow_table.h b/datapath/flow_table.h
index ee86953..cf898ba 100644
--- a/datapath/flow_table.h
+++ b/datapath/flow_table.h
@@ -43,7 +43,7 @@ struct mask_cache_entry {
 
 struct mask_array {
        struct rcu_head rcu;
-       int count, max;
+       int count, max, hi_index;
        struct sw_flow_mask __rcu *masks[];
 };
 
-- 
1.7.9.5

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

Reply via email to