if (ctx->xin->tcp_flags & (TCP_FIN | TCP_RST) && ctx->rule) {
struct rule_dpif *rule = ctx->rule;
- if (list_is_empty(&rule->up.expirable)) {
- list_insert(&rule->up.ofproto->expirable, &rule->up.expirable);
- }
-
- 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);
+ ovs_mutex_lock(&rule->up.ofproto->expirable_mutex);
+ if (list_is_empty(&rule->up.expirable)) {
+ list_insert(&rule->up.ofproto->expirable, &rule->up.expirable);
+ }
+ ovs_mutex_unlock(&rule->up.ofproto->expirable_mutex);
+
+ 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);
}
}
/* Expire OpenFlow flows whose idle_timeout or hard_timeout
* has passed. */
+ ovs_mutex_lock(&ofproto->up.expirable_mutex);
LIST_FOR_EACH_SAFE (rule, next_rule, expirable,
&ofproto->up.expirable) {
rule_expire(rule_dpif_cast(rule));
}
+ ovs_mutex_unlock(&ofproto->up.expirable_mutex);
/* All outstanding data in existing flows has been accounted, so it's a
* good time to do bond rebalancing. */
/* Optimisation for flow expiry.
* These flows should all be present in tables. */
- struct list expirable; /* Expirable 'struct rule"s in all tables. */
+ struct ovs_mutex expirable_mutex;
+ struct list expirable OVS_GUARDED; /* Expirable 'struct rule"s in all
+ tables. */
/* Meter table.
* OpenFlow meters start at 1. To avoid confusion we leave the first
ofproto->n_tables = 0;
hindex_init(&ofproto->cookies);
list_init(&ofproto->expirable);
+ ovs_mutex_init(&ofproto->expirable_mutex, PTHREAD_MUTEX_RECURSIVE);
ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
ofproto->state = S_OPENFLOW;
list_init(&ofproto->pending);
free(ofproto->vlan_bitmap);
+ ovs_mutex_destroy(&ofproto->expirable_mutex);
ofproto->ofproto_class->dealloc(ofproto);
}
}
cookies_remove(ofproto, rule);
eviction_group_remove_rule(rule);
+ ovs_mutex_lock(&ofproto->expirable_mutex);
if (!list_is_empty(&rule->expirable)) {
list_remove(&rule->expirable);
}
+ ovs_mutex_unlock(&ofproto->expirable_mutex);
if (!list_is_empty(&rule->meter_list_node)) {
list_remove(&rule->meter_list_node);
}
ovs_mutex_unlock(&rule->timeout_mutex);
if (may_expire) {
+ ovs_mutex_lock(&ofproto->expirable_mutex);
list_insert(&ofproto->expirable, &rule->expirable);
+ ovs_mutex_unlock(&ofproto->expirable_mutex);
}
cookies_insert(ofproto, rule);
if (rule->meter_id) {
}
cookies_remove(ofproto, victim);
+ ovs_mutex_lock(&ofproto->expirable_mutex);
if (!list_is_empty(&victim->expirable)) {
list_remove(&victim->expirable);
}
+ ovs_mutex_unlock(&ofproto->expirable_mutex);
eviction_group_remove_rule(victim);
}
eviction_group_add_rule(rule);