struct bfd_cfg;
struct meter;
+extern struct ovs_mutex ofproto_mutex;
+
/* An OpenFlow switch.
*
* With few exceptions, ofproto implementations may look at these fields but
struct hindex cookies; /* Rules indexed on their cookie values. */
- /* Optimisation for flow expiry.
- * These flows should all be present in tables. */
- struct ovs_mutex expirable_mutex;
- struct list expirable OVS_GUARDED; /* Expirable 'struct rule"s in all
- tables. */
+ /* List of expirable flows, in all flow tables. */
+ struct list expirable OVS_GUARDED_BY(ofproto_mutex);
/* Meter table.
* OpenFlow meters start at 1. To avoid confusion we leave the first
uint64_t add_seqno; /* Sequence number when added. */
uint64_t modify_seqno; /* Sequence number when changed. */
- /* Optimisation for flow expiry. */
- struct list expirable; /* In ofproto's 'expirable' list if this rule
- * is expirable, otherwise empty. */
+ /* Optimisation for flow expiry. In ofproto's 'expirable' list if this
+ * rule is expirable, otherwise empty. */
+ struct list expirable OVS_GUARDED_BY(ofproto_mutex);
};
void ofproto_rule_ref(struct rule *);
struct rule *) OVS_REQ_WRLOCK(cls->rwlock);
void ofproto_rule_reduce_timeouts(struct rule *rule, uint16_t idle_timeout,
uint16_t hard_timeout)
- OVS_EXCLUDED(rule->ofproto->expirable_mutex, rule->timeout_mutex);
+ OVS_EXCLUDED(ofproto_mutex, rule->timeout_mutex);
bool ofproto_rule_has_out_port(const struct rule *, ofp_port_t out_port);
static size_t n_ofproto_classes;
static size_t allocated_ofproto_classes;
+struct ovs_mutex ofproto_mutex;
+
unsigned flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT;
unsigned n_handler_threads;
enum ofproto_flow_miss_model flow_miss_model = OFPROTO_HANDLE_MISS_AUTO;
struct shash_node *node;
size_t i;
+ ovs_mutex_init_recursive(&ofproto_mutex);
+
ofproto_class_register(&ofproto_dpif_class);
/* Make a local copy, since we don't own 'iface_hints' elements. */
}
/* Initialize. */
+ ovs_mutex_lock(&ofproto_mutex);
memset(ofproto, 0, sizeof *ofproto);
ofproto->ofproto_class = class;
ofproto->name = xstrdup(datapath_name);
ofproto->n_tables = 0;
hindex_init(&ofproto->cookies);
list_init(&ofproto->expirable);
- ovs_mutex_init_recursive(&ofproto->expirable_mutex);
ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
ofproto->state = S_OPENFLOW;
list_init(&ofproto->pending);
ofproto->min_mtu = INT_MAX;
ovs_rwlock_init(&ofproto->groups_rwlock);
hmap_init(&ofproto->groups);
+ ovs_mutex_unlock(&ofproto_mutex);
error = ofproto->ofproto_class->construct(ofproto);
if (error) {
free(ofproto->vlan_bitmap);
- ovs_mutex_destroy(&ofproto->expirable_mutex);
ofproto->ofproto_class->dealloc(ofproto);
}
void
ofproto_rule_reduce_timeouts(struct rule *rule,
uint16_t idle_timeout, uint16_t hard_timeout)
- OVS_EXCLUDED(rule->ofproto->expirable_mutex, rule->timeout_mutex)
+ OVS_EXCLUDED(ofproto_mutex, rule->timeout_mutex)
{
if (!idle_timeout && !hard_timeout) {
return;
}
- ovs_mutex_lock(&rule->ofproto->expirable_mutex);
+ ovs_mutex_lock(&ofproto_mutex);
if (list_is_empty(&rule->expirable)) {
list_insert(&rule->ofproto->expirable, &rule->expirable);
}
- ovs_mutex_unlock(&rule->ofproto->expirable_mutex);
+ ovs_mutex_unlock(&ofproto_mutex);
ovs_mutex_lock(&rule->timeout_mutex);
reduce_timeout(idle_timeout, &rule->idle_timeout);
classifier_remove(cls, &rule->cr);
cookies_remove(ofproto, rule);
eviction_group_remove_rule(rule);
- ovs_mutex_lock(&ofproto->expirable_mutex);
+ ovs_mutex_lock(&ofproto_mutex);
if (!list_is_empty(&rule->expirable)) {
list_remove(&rule->expirable);
}
- ovs_mutex_unlock(&ofproto->expirable_mutex);
+ ovs_mutex_unlock(&ofproto_mutex);
if (!list_is_empty(&rule->meter_list_node)) {
list_remove(&rule->meter_list_node);
list_init(&rule->meter_list_node);
ovs_mutex_unlock(&rule->timeout_mutex);
if (may_expire) {
- ovs_mutex_lock(&ofproto->expirable_mutex);
+ ovs_mutex_lock(&ofproto_mutex);
list_insert(&ofproto->expirable, &rule->expirable);
- ovs_mutex_unlock(&ofproto->expirable_mutex);
+ ovs_mutex_unlock(&ofproto_mutex);
}
cookies_insert(ofproto, rule);