Move operation needs to do RCU transaction on mask array. That could make mask delete expensive.
On Wed, May 7, 2014 at 10:29 PM, Andy Zhou <az...@nicira.com> wrote: > I have a high level question: > Since mask can be moved around in the array without causing problem, > when deleting a mask, why not simply move the highest > element over? > > On Mon, Apr 7, 2014 at 3:00 PM, Pravin <pshe...@nicira.com> wrote: >> From: Pravin Shelar <pshe...@nicira.com> >> >> 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 5665cfc..b2c0497 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; >> @@ -521,7 +535,7 @@ static struct sw_flow *flow_lookup(struct flow_table >> *tbl, >> int i, c; >> >> c = 0; >> - 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]); >> @@ -631,7 +645,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--; >> @@ -688,7 +702,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]); >> @@ -736,8 +750,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; >> } >> } >> @@ -777,6 +792,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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev