[ovs-dev] [thread 08/15] ofproto: Lock hard_timeout and idle_timeout of struct rule.
Ethan Jackson
ethan at nicira.com
Thu Aug 8 19:58:27 UTC 2013
Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
ofproto/connmgr.c | 8 ++++++--
ofproto/ofproto-dpif-xlate.c | 6 ++++--
ofproto/ofproto-dpif.c | 12 ++++++++----
ofproto/ofproto-provider.h | 6 ++++--
ofproto/ofproto.c | 34 +++++++++++++++++++++++++++++-----
5 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index 4264934..1e9ef5b 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -1882,13 +1882,17 @@ ofmonitor_report(struct connmgr *mgr, struct rule *rule,
fu.event = event;
fu.reason = event == NXFME_DELETED ? reason : 0;
- fu.idle_timeout = rule->idle_timeout;
- fu.hard_timeout = rule->hard_timeout;
fu.table_id = rule->table_id;
fu.cookie = rule->flow_cookie;
minimatch_expand(&rule->cr.match, &match);
fu.match = &match;
fu.priority = rule->cr.priority;
+
+ ovs_mutex_lock(&rule->timeout_mutex);
+ fu.idle_timeout = rule->idle_timeout;
+ fu.hard_timeout = rule->hard_timeout;
+ ovs_mutex_unlock(&rule->timeout_mutex);
+
if (flags & NXFMF_ACTIONS) {
fu.ofpacts = rule->ofpacts;
fu.ofpacts_len = rule->ofpacts_len;
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 3050678..8aa2bb1 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2040,8 +2040,10 @@ xlate_fin_timeout(struct xlate_ctx *ctx,
list_insert(&rule->up.ofproto->expirable, &rule->up.expirable);
}
- reduce_timeout(oft->fin_idle_timeout, &rule->up.idle_timeout);
- reduce_timeout(oft->fin_hard_timeout, &rule->up.hard_timeout);
+ ovs_mutex_lock(&rule->up.timeout_mutex);
+ reduce_timeout(oft->fin_idle_timeout, &rule->up.idle_timeout);
+ reduce_timeout(oft->fin_hard_timeout, &rule->up.hard_timeout);
+ ovs_mutex_unlock(&rule->up.timeout_mutex);
}
}
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index e173269..36850d0 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -4293,6 +4293,7 @@ expire_subfacets(struct dpif_backer *backer, int dp_max_idle)
static void
rule_expire(struct rule_dpif *rule)
{
+ uint32_t idle_timeout, hard_timeout;
long long int now;
uint8_t reason;
@@ -4301,13 +4302,16 @@ rule_expire(struct rule_dpif *rule)
return;
}
+ ovs_mutex_lock(&rule->up.timeout_mutex);
+ hard_timeout = rule->up.hard_timeout;
+ idle_timeout = rule->up.idle_timeout;
+ ovs_mutex_unlock(&rule->up.timeout_mutex);
+
/* Has 'rule' expired? */
now = time_msec();
- if (rule->up.hard_timeout
- && now > rule->up.modified + rule->up.hard_timeout * 1000) {
+ if (hard_timeout && now > rule->up.modified + hard_timeout * 1000) {
reason = OFPRR_HARD_TIMEOUT;
- } else if (rule->up.idle_timeout
- && now > rule->up.used + rule->up.idle_timeout * 1000) {
+ } else if (idle_timeout && now > rule->up.used + idle_timeout * 1000) {
reason = OFPRR_IDLE_TIMEOUT;
} else {
return;
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index 41d106a..9db4346 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -219,11 +219,13 @@ struct rule {
long long int created; /* Creation time. */
long long int modified; /* Time of last modification. */
long long int used; /* Last use; time created if never used. */
- uint16_t hard_timeout; /* In seconds from ->modified. */
- uint16_t idle_timeout; /* In seconds from ->used. */
uint8_t table_id; /* Index in ofproto's 'tables' array. */
bool send_flow_removed; /* Send a flow removed message? */
+ struct ovs_mutex timeout_mutex;
+ uint16_t hard_timeout OVS_GUARDED; /* In seconds from ->modified. */
+ uint16_t idle_timeout OVS_GUARDED; /* In seconds from ->used. */
+
/* Eviction groups. */
bool evictable; /* If false, prevents eviction. */
struct heap_node evg_node; /* In eviction_group's "rules" heap. */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 0625ccf..c3f34c6 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2165,6 +2165,7 @@ ofproto_rule_destroy__(struct rule *rule)
if (rule) {
cls_rule_destroy(&rule->cr);
free(rule->ofpacts);
+ ovs_mutex_destroy(&rule->timeout_mutex);
rule->ofproto->ofproto_class->rule_dealloc(rule);
}
}
@@ -3019,8 +3020,6 @@ handle_flow_stats_request(struct ofconn *ofconn,
fs.cookie = rule->flow_cookie;
fs.table_id = rule->table_id;
calc_duration(rule->created, now, &fs.duration_sec, &fs.duration_nsec);
- fs.idle_timeout = rule->idle_timeout;
- fs.hard_timeout = rule->hard_timeout;
fs.idle_age = age_secs(now - rule->used);
fs.hard_age = age_secs(now - rule->modified);
ofproto->ofproto_class->rule_get_stats(rule, &fs.packet_count,
@@ -3028,6 +3027,12 @@ handle_flow_stats_request(struct ofconn *ofconn,
fs.ofpacts = rule->ofpacts;
fs.ofpacts_len = rule->ofpacts_len;
fs.flags = 0;
+
+ ovs_mutex_lock(&rule->timeout_mutex);
+ fs.idle_timeout = rule->idle_timeout;
+ fs.hard_timeout = rule->hard_timeout;
+ ovs_mutex_unlock(&rule->timeout_mutex);
+
if (rule->send_flow_removed) {
fs.flags |= OFPFF_SEND_FLOW_REM;
/* FIXME: Implement OF 1.3 flags OFPFF13_NO_PKT_COUNTS
@@ -3375,8 +3380,13 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn,
rule->pending = NULL;
rule->flow_cookie = fm->new_cookie;
rule->created = rule->modified = rule->used = time_msec();
+
+ ovs_mutex_init(&rule->timeout_mutex, PTHREAD_MUTEX_NORMAL);
+ ovs_mutex_lock(&rule->timeout_mutex);
rule->idle_timeout = fm->idle_timeout;
rule->hard_timeout = fm->hard_timeout;
+ ovs_mutex_unlock(&rule->timeout_mutex);
+
rule->table_id = table - ofproto->tables;
rule->send_flow_removed = (fm->flags & OFPFF_SEND_FLOW_REM) != 0;
/* FIXME: Implement OF 1.3 flags OFPFF13_NO_PKT_COUNTS
@@ -3660,8 +3670,10 @@ ofproto_rule_send_removed(struct rule *rule, uint8_t reason)
fr.table_id = rule->table_id;
calc_duration(rule->created, time_msec(),
&fr.duration_sec, &fr.duration_nsec);
+ ovs_mutex_lock(&rule->timeout_mutex);
fr.idle_timeout = rule->idle_timeout;
fr.hard_timeout = rule->hard_timeout;
+ ovs_mutex_unlock(&rule->timeout_mutex);
rule->ofproto->ofproto_class->rule_get_stats(rule, &fr.packet_count,
&fr.byte_count);
@@ -3967,8 +3979,10 @@ ofproto_compose_flow_refresh_update(const struct rule *rule,
fu.event = (flags & (NXFMF_INITIAL | NXFMF_ADD)
? NXFME_ADDED : NXFME_MODIFIED);
fu.reason = 0;
+ ovs_mutex_lock(&rule->timeout_mutex);
fu.idle_timeout = rule->idle_timeout;
fu.hard_timeout = rule->hard_timeout;
+ ovs_mutex_unlock(&rule->timeout_mutex);
fu.table_id = rule->table_id;
fu.cookie = rule->flow_cookie;
minimatch_expand(&rule->cr.match, &match);
@@ -5218,6 +5232,7 @@ rule_eviction_priority(struct rule *rule)
uint32_t expiration_offset;
/* Calculate time of expiration. */
+ ovs_mutex_lock(&rule->timeout_mutex);
hard_expiration = (rule->hard_timeout
? rule->modified + rule->hard_timeout * 1000
: LLONG_MAX);
@@ -5225,6 +5240,7 @@ rule_eviction_priority(struct rule *rule)
? rule->used + rule->idle_timeout * 1000
: LLONG_MAX);
expiration = MIN(hard_expiration, idle_expiration);
+ ovs_mutex_unlock(&rule->timeout_mutex);
if (expiration == LLONG_MAX) {
return 0;
}
@@ -5251,9 +5267,13 @@ eviction_group_add_rule(struct rule *rule)
{
struct ofproto *ofproto = rule->ofproto;
struct oftable *table = &ofproto->tables[rule->table_id];
+ bool has_timeout;
- if (table->eviction_fields
- && (rule->hard_timeout || rule->idle_timeout)) {
+ ovs_mutex_lock(&rule->timeout_mutex);
+ has_timeout = rule->hard_timeout || rule->idle_timeout;
+ ovs_mutex_unlock(&rule->timeout_mutex);
+
+ if (table->eviction_fields && has_timeout) {
struct eviction_group *evg;
evg = eviction_group_find(table, eviction_group_hash_rule(rule));
@@ -5398,7 +5418,11 @@ oftable_replace_rule(struct rule *rule)
struct ofproto *ofproto = rule->ofproto;
struct oftable *table = &ofproto->tables[rule->table_id];
struct rule *victim;
- bool may_expire = rule->hard_timeout || rule->idle_timeout;
+ bool may_expire;
+
+ ovs_mutex_lock(&rule->timeout_mutex);
+ may_expire = rule->hard_timeout || rule->idle_timeout;
+ ovs_mutex_unlock(&rule->timeout_mutex);
if (may_expire) {
list_insert(&ofproto->expirable, &rule->expirable);
--
1.7.9.5
More information about the dev
mailing list