From: Ethan Jackson Date: Wed, 7 Aug 2013 20:06:49 +0000 (-0700) Subject: ofproto: Lock hard_timeout and idle_timeout of struct rule. X-Git-Tag: sliver-openvswitch-2.0.90-1~32^2~16 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=a3779dbced55689b572f03f4e64ee3103add2baf;hp=ec2905a895831667fcfa9dadfdcf334ca73a8346;p=sliver-openvswitch.git ofproto: Lock hard_timeout and idle_timeout of struct rule. Signed-off-by: Ethan Jackson Acked-by: Ben Pfaff --- diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 426493436..1e9ef5b5d 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 305067853..8aa2bb1bc 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 e17326987..d357b8d2d 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) { + uint16_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 41d106a97..75bcefc1c 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -19,7 +19,6 @@ /* Definitions for use within ofproto. */ -#include "ofproto/ofproto.h" #include "cfm.h" #include "classifier.h" #include "heap.h" @@ -27,6 +26,8 @@ #include "list.h" #include "ofp-errors.h" #include "ofp-util.h" +#include "ofproto/ofproto.h" +#include "ovs-thread.h" #include "shash.h" #include "simap.h" #include "timeval.h" @@ -219,11 +220,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 0625ccfa1..34298d456 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, OVS_MUTEX_ADAPTIVE); + 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);