[ovs-dev] [threaded-learning 16/25] ofproto: Protect index by cookie with ofproto_mutex.
Ben Pfaff
blp at nicira.com
Wed Sep 11 05:27:16 UTC 2013
The cookie index is only used for flow_mods, so it makes sense to use this
global mutex.
Signed-off-by: Ben Pfaff <blp at 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
More information about the dev
mailing list