X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=a9cf221775f0c8d905293fc08aaec03fef01c915;hb=2d04b6ea214daf96020ce5ca994fcb5380556247;hp=676a6cbe2247a908f911b7af7f58b756dd0ffe7d;hpb=554764d1aac75030c319fc8e2fa87811149421fa;p=sliver-openvswitch.git diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 676a6cbe2..a9cf22177 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * Copyright (c) 2010 Jean Tourrilhes - HP-Labs. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -734,12 +734,12 @@ ofproto_set_mac_table_config(struct ofproto *ofproto, unsigned idle_time, } void -ofproto_set_threads(size_t n_handlers_, size_t n_revalidators_) +ofproto_set_threads(int n_handlers_, int n_revalidators_) { int threads = MAX(count_cpu_cores(), 2); - n_revalidators = n_revalidators_; - n_handlers = n_handlers_; + n_revalidators = MAX(n_revalidators_, 0); + n_handlers = MAX(n_handlers_, 0); if (!n_revalidators) { n_revalidators = n_handlers @@ -1168,7 +1168,7 @@ ofproto_configure_table(struct ofproto *ofproto, int table_id, } table->max_flows = s->max_flows; - ovs_rwlock_wrlock(&table->cls.rwlock); + fat_rwlock_wrlock(&table->cls.rwlock); if (classifier_count(&table->cls) > table->max_flows && table->eviction_fields) { /* 'table' contains more flows than allowed. We might not be able to @@ -1188,7 +1188,7 @@ ofproto_configure_table(struct ofproto *ofproto, int table_id, classifier_set_prefix_fields(&table->cls, s->prefix_fields, s->n_prefix_fields); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); } bool @@ -1217,7 +1217,7 @@ ofproto_rule_delete__(struct ofproto *ofproto, struct rule *rule, ofopgroup_submit(group); } -/* Deletes 'rule' from 'cls' within 'ofproto'. +/* Deletes 'rule' from 'ofproto'. * * Within an ofproto implementation, this function allows an ofproto * implementation to destroy any rules that remain when its ->destruct() @@ -1263,9 +1263,9 @@ ofproto_flush__(struct ofproto *ofproto) continue; } - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, NULL); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, cr, &cursor) { if (!rule->pending) { ofproto_rule_delete__(ofproto, rule, OFPRR_DELETE); @@ -1454,7 +1454,7 @@ ofproto_run(struct ofproto *p) heap_rebuild(&evg->rules); } - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { if (!rule->eviction_group @@ -1462,7 +1462,7 @@ ofproto_run(struct ofproto *p) eviction_group_add_rule(rule); } } - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); ovs_mutex_unlock(&ofproto_mutex); } } @@ -1612,9 +1612,9 @@ ofproto_get_memory_usage(const struct ofproto *ofproto, struct simap *usage) n_rules = 0; OFPROTO_FOR_EACH_TABLE (table, ofproto) { - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); n_rules += classifier_count(&table->cls); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); } simap_increase(usage, "rules", n_rules); @@ -1901,7 +1901,7 @@ ofproto_add_flow(struct ofproto *ofproto, const struct match *match, /* First do a cheap check whether the rule we're looking for already exists * with the actions that we want. If it does, then we're done. */ - ovs_rwlock_rdlock(&ofproto->tables[0].cls.rwlock); + fat_rwlock_rdlock(&ofproto->tables[0].cls.rwlock); rule = rule_from_cls_rule(classifier_find_match_exactly( &ofproto->tables[0].cls, match, priority)); if (rule) { @@ -1913,7 +1913,7 @@ ofproto_add_flow(struct ofproto *ofproto, const struct match *match, } else { must_add = true; } - ovs_rwlock_unlock(&ofproto->tables[0].cls.rwlock); + fat_rwlock_unlock(&ofproto->tables[0].cls.rwlock); /* If there's no such rule or the rule doesn't have the actions we want, * fall back to a executing a full flow mod. We can't optimize this at @@ -1952,10 +1952,10 @@ ofproto_delete_flow(struct ofproto *ofproto, /* First do a cheap check whether the rule we're looking for has already * been deleted. If so, then we're done. */ - ovs_rwlock_rdlock(&cls->rwlock); + fat_rwlock_rdlock(&cls->rwlock); rule = rule_from_cls_rule(classifier_find_match_exactly(cls, target, priority)); - ovs_rwlock_unlock(&cls->rwlock); + fat_rwlock_unlock(&cls->rwlock); if (!rule) { return true; } @@ -2527,26 +2527,16 @@ void ofproto_rule_ref(struct rule *rule) { if (rule) { - unsigned int orig; - - atomic_add(&rule->ref_count, 1, &orig); - ovs_assert(orig != 0); + ovs_refcount_ref(&rule->ref_count); } } void ofproto_rule_unref(struct rule *rule) { - if (rule) { - unsigned int orig; - - atomic_sub(&rule->ref_count, 1, &orig); - if (orig == 1) { - rule->ofproto->ofproto_class->rule_destruct(rule); - ofproto_rule_destroy__(rule); - } else { - ovs_assert(orig != 0); - } + if (rule && ovs_refcount_unref(&rule->ref_count) == 1) { + rule->ofproto->ofproto_class->rule_destruct(rule); + ofproto_rule_destroy__(rule); } } @@ -2578,6 +2568,7 @@ ofproto_rule_destroy__(struct rule *rule) cls_rule_destroy(CONST_CAST(struct cls_rule *, &rule->cr)); rule_actions_unref(rule->actions); ovs_mutex_destroy(&rule->mutex); + ovs_refcount_destroy(&rule->ref_count); rule->ofproto->ofproto_class->rule_dealloc(rule); } @@ -2593,7 +2584,7 @@ rule_actions_create(const struct ofproto *ofproto, struct rule_actions *actions; actions = xmalloc(sizeof *actions); - atomic_init(&actions->ref_count, 1); + ovs_refcount_init(&actions->ref_count); actions->ofpacts = xmemdup(ofpacts, ofpacts_len); actions->ofpacts_len = ofpacts_len; actions->provider_meter_id @@ -2608,10 +2599,7 @@ void rule_actions_ref(struct rule_actions *actions) { if (actions) { - unsigned int orig; - - atomic_add(&actions->ref_count, 1, &orig); - ovs_assert(orig != 0); + ovs_refcount_ref(&actions->ref_count); } } @@ -2620,16 +2608,10 @@ rule_actions_ref(struct rule_actions *actions) void rule_actions_unref(struct rule_actions *actions) { - if (actions) { - unsigned int orig; - - atomic_sub(&actions->ref_count, 1, &orig); - if (orig == 1) { - free(actions->ofpacts); - free(actions); - } else { - ovs_assert(orig != 0); - } + if (actions && ovs_refcount_unref(&actions->ref_count) == 1) { + ovs_refcount_destroy(&actions->ref_count); + free(actions->ofpacts); + free(actions); } } @@ -3078,9 +3060,9 @@ handle_table_stats_request(struct ofconn *ofconn, ots[i].instructions = htonl(OFPIT11_ALL); ots[i].config = htonl(OFPTC11_TABLE_MISS_MASK); ots[i].max_entries = htonl(1000000); /* An arbitrary big number. */ - ovs_rwlock_rdlock(&p->tables[i].cls.rwlock); + fat_rwlock_rdlock(&p->tables[i].cls.rwlock); ots[i].active_count = htonl(classifier_count(&p->tables[i].cls)); - ovs_rwlock_unlock(&p->tables[i].cls.rwlock); + fat_rwlock_unlock(&p->tables[i].cls.rwlock); } p->ofproto_class->get_tables(p, ots); @@ -3442,7 +3424,7 @@ collect_rules_loose(struct ofproto *ofproto, struct cls_cursor cursor; struct rule *rule; - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, &criteria->cr); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { error = collect_rule(rule, criteria, rules); @@ -3450,7 +3432,7 @@ collect_rules_loose(struct ofproto *ofproto, break; } } - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); } } @@ -3502,10 +3484,10 @@ collect_rules_strict(struct ofproto *ofproto, FOR_EACH_MATCHING_TABLE (table, criteria->table_id, ofproto) { struct rule *rule; - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); rule = rule_from_cls_rule(classifier_find_rule_exactly( &table->cls, &criteria->cr)); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); if (rule) { error = collect_rule(rule, criteria, rules); if (error) { @@ -3653,12 +3635,12 @@ ofproto_get_all_flows(struct ofproto *p, struct ds *results) struct cls_cursor cursor; struct rule *rule; - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { flow_stats_ds(rule, results); } - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); } } @@ -3969,9 +3951,9 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, cls_rule_init(&cr, &fm->match, fm->priority); /* Transform "add" into "modify" if there's an existing identical flow. */ - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); rule = rule_from_cls_rule(classifier_find_rule_exactly(&table->cls, &cr)); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); if (rule) { cls_rule_destroy(&cr); if (!rule_is_modifiable(rule)) { @@ -4001,9 +3983,9 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, if (fm->flags & OFPUTIL_FF_CHECK_OVERLAP) { bool overlaps; - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); overlaps = classifier_rule_overlaps(&table->cls, &cr); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); if (overlaps) { cls_rule_destroy(&cr); @@ -4030,7 +4012,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, /* Initialize base state. */ *CONST_CAST(struct ofproto **, &rule->ofproto) = ofproto; cls_rule_move(CONST_CAST(struct cls_rule *, &rule->cr), &cr); - atomic_init(&rule->ref_count, 1); + ovs_refcount_init(&rule->ref_count); rule->pending = NULL; rule->flow_cookie = fm->new_cookie; rule->created = rule->modified = rule->used = time_msec(); @@ -4824,13 +4806,13 @@ ofproto_collect_ofmonitor_refresh_rules(const struct ofmonitor *m, struct cls_cursor cursor; struct rule *rule; - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, &target); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { ovs_assert(!rule->pending); /* XXX */ ofproto_collect_ofmonitor_refresh_rule(m, rule, seqno, rules); } - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); } HMAP_FOR_EACH (op, hmap_node, &ofproto->deletions) { @@ -6659,12 +6641,13 @@ oftable_init(struct oftable *table) static void oftable_destroy(struct oftable *table) { - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); ovs_assert(classifier_is_empty(&table->cls)); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); oftable_disable_eviction(table); classifier_destroy(&table->cls); free(table->name); + atomic_destroy(&table->config); } /* Changes the name of 'table' to 'name'. If 'name' is NULL or the empty @@ -6743,12 +6726,12 @@ oftable_enable_eviction(struct oftable *table, hmap_init(&table->eviction_groups_by_id); heap_init(&table->eviction_groups_by_size); - ovs_rwlock_rdlock(&table->cls.rwlock); + fat_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { eviction_group_add_rule(rule); } - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); } /* Removes 'rule' from the oftable that contains it. */ @@ -6758,9 +6741,9 @@ oftable_remove_rule__(struct ofproto *ofproto, struct rule *rule) { struct classifier *cls = &ofproto->tables[rule->table_id].cls; - ovs_rwlock_wrlock(&cls->rwlock); + fat_rwlock_wrlock(&cls->rwlock); classifier_remove(cls, CONST_CAST(struct cls_rule *, &rule->cr)); - ovs_rwlock_unlock(&cls->rwlock); + fat_rwlock_unlock(&cls->rwlock); cookies_remove(ofproto, rule); @@ -6807,9 +6790,9 @@ oftable_insert_rule(struct rule *rule) struct meter *meter = ofproto->meters[meter_id]; list_insert(&meter->rules, &rule->meter_list_node); } - ovs_rwlock_wrlock(&table->cls.rwlock); + fat_rwlock_wrlock(&table->cls.rwlock); classifier_insert(&table->cls, CONST_CAST(struct cls_rule *, &rule->cr)); - ovs_rwlock_unlock(&table->cls.rwlock); + fat_rwlock_unlock(&table->cls.rwlock); eviction_group_add_rule(rule); } @@ -6878,7 +6861,7 @@ ofproto_get_vlan_usage(struct ofproto *ofproto, unsigned long int *vlan_bitmap) OFPROTO_FOR_EACH_TABLE (oftable, ofproto) { const struct cls_subtable *table; - ovs_rwlock_rdlock(&oftable->cls.rwlock); + fat_rwlock_rdlock(&oftable->cls.rwlock); HMAP_FOR_EACH (table, hmap_node, &oftable->cls.subtables) { if (minimask_get_vid_mask(&table->mask) == VLAN_VID_MASK) { const struct cls_rule *rule; @@ -6890,7 +6873,7 @@ ofproto_get_vlan_usage(struct ofproto *ofproto, unsigned long int *vlan_bitmap) } } } - ovs_rwlock_unlock(&oftable->cls.rwlock); + fat_rwlock_unlock(&oftable->cls.rwlock); } }