The cookie index is only used for flow_mods, so it makes sense to use this global mutex.
Signed-off-by: Ben Pfaff <b...@nicira.com> --- ofproto/ofproto-provider.h | 5 +++-- ofproto/ofproto.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index edc9abc..dd93743 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -77,7 +77,8 @@ struct ofproto { struct oftable *tables; int n_tables; - struct hindex cookies; /* Rules indexed on their cookie values. */ + /* Rules indexed on their cookie values, in all flow tables. */ + struct hindex cookies OVS_GUARDED_BY(ofproto_mutex); /* List of expirable flows, in all flow tables. */ struct list expirable OVS_GUARDED_BY(ofproto_mutex); @@ -230,7 +231,7 @@ struct rule { ovs_be64 flow_cookie; /* Controller-issued identifier. Guarded by rwlock. */ - struct hindex_node cookie_node; /* In owning ofproto's 'cookies' index. */ + struct hindex_node cookie_node OVS_GUARDED_BY(ofproto_mutex); long long int created; /* Creation time. */ long long int modified; /* Time of last modification. */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 9e33684..f5bac6a 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2943,6 +2943,7 @@ hash_cookie(ovs_be64 cookie) static void cookies_insert(struct ofproto *ofproto, struct rule *rule) + OVS_REQUIRES(ofproto_mutex) { hindex_insert(&ofproto->cookies, &rule->cookie_node, hash_cookie(rule->flow_cookie)); @@ -2950,6 +2951,7 @@ cookies_insert(struct ofproto *ofproto, struct rule *rule) static void cookies_remove(struct ofproto *ofproto, struct rule *rule) + OVS_REQUIRES(ofproto_mutex) { hindex_remove(&ofproto->cookies, &rule->cookie_node); } @@ -2959,6 +2961,7 @@ ofproto_rule_change_cookie(struct ofproto *ofproto, struct rule *rule, ovs_be64 new_cookie) { if (new_cookie != rule->flow_cookie) { + ovs_mutex_lock(&ofproto_mutex); cookies_remove(ofproto, rule); ovs_rwlock_wrlock(&rule->rwlock); @@ -2966,6 +2969,7 @@ ofproto_rule_change_cookie(struct ofproto *ofproto, struct rule *rule, ovs_rwlock_unlock(&rule->rwlock); cookies_insert(ofproto, rule); + ovs_mutex_unlock(&ofproto_mutex); } } @@ -3099,6 +3103,7 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, if (cookie_mask == htonll(UINT64_MAX)) { struct rule *rule; + ovs_mutex_lock(&ofproto_mutex); HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie), &ofproto->cookies) { if (cls_rule_is_loose_match(&rule->cr, &cr.match)) { @@ -3109,6 +3114,7 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, } } } + ovs_mutex_unlock(&ofproto_mutex); } else { FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) { struct cls_cursor cursor; @@ -3164,6 +3170,7 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t table_id, if (cookie_mask == htonll(UINT64_MAX)) { struct rule *rule; + ovs_mutex_lock(&ofproto_mutex); HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node, hash_cookie(cookie), &ofproto->cookies) { if (cls_rule_equal(&rule->cr, &cr)) { @@ -3174,6 +3181,7 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t table_id, } } } + ovs_mutex_unlock(&ofproto_mutex); } else { FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) { struct rule *rule; @@ -6205,7 +6213,11 @@ oftable_remove_rule__(struct ofproto *ofproto, struct classifier *cls, OVS_REQ_WRLOCK(cls->rwlock) OVS_RELEASES(rule->rwlock) { classifier_remove(cls, &rule->cr); + + ovs_mutex_lock(&ofproto_mutex); cookies_remove(ofproto, rule); + ovs_mutex_unlock(&ofproto_mutex); + eviction_group_remove_rule(rule); ovs_mutex_lock(&ofproto_mutex); if (!list_is_empty(&rule->expirable)) { @@ -6248,7 +6260,10 @@ oftable_insert_rule(struct rule *rule) list_insert(&ofproto->expirable, &rule->expirable); ovs_mutex_unlock(&ofproto_mutex); } + + ovs_mutex_lock(&ofproto_mutex); cookies_insert(ofproto, rule); + ovs_mutex_unlock(&ofproto_mutex); if (rule->actions->meter_id) { struct meter *meter = ofproto->meters[rule->actions->meter_id]; -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev