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