X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.c;h=80874b87ff5c389d0e424c6a5dfac62f6ccd27dd;hb=8fd16af26583ad6a3761e30aec458552213ec94a;hp=f5f91dd6a58aa5be383352bff72e67cc0e25245f;hpb=c7c9a7c8ba4bb5b77d1e2f60975317aa8b3d252e;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index f5f91dd6a..80874b87f 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -175,7 +175,6 @@ struct subfacet { struct facet *facet; /* Owning facet. */ struct dpif_backer *backer; /* Owning backer. */ - enum odp_key_fitness key_fitness; struct nlattr *key; int key_len; @@ -508,7 +507,6 @@ struct ofproto_dpif { uint64_t n_missed; /* Work queues. */ - struct guarded_list flow_mods; /* Contains "struct flow_mod"s. */ struct guarded_list pins; /* Contains "struct ofputil_packet_in"s. */ }; @@ -551,16 +549,13 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); /* Initial mappings of port to bridge mappings. */ static struct shash init_ofp_ports = SHASH_INITIALIZER(&init_ofp_ports); -/* Executes and takes ownership of 'fm'. */ +/* Executes 'fm'. The caller retains ownership of 'fm' and everything in + * it. */ void ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto, struct ofputil_flow_mod *fm) { - if (!guarded_list_push_back(&ofproto->flow_mods, &fm->list_node, 1024)) { - COVERAGE_INC(flow_mod_overflow); - free(fm->ofpacts); - free(fm); - } + ofproto_flow_mod(&ofproto->up, fm); } /* Appends 'pin' to the queue of "packet ins" to be sent to the controller. @@ -1083,8 +1078,6 @@ dealloc(struct ofproto *ofproto_) static void close_dpif_backer(struct dpif_backer *backer) { - struct shash_node *node; - ovs_assert(backer->refcount > 0); if (--backer->refcount) { @@ -1094,13 +1087,13 @@ close_dpif_backer(struct dpif_backer *backer) drop_key_clear(backer); hmap_destroy(&backer->drop_keys); + udpif_destroy(backer->udpif); + simap_destroy(&backer->tnl_backers); ovs_rwlock_destroy(&backer->odp_to_ofport_lock); hmap_destroy(&backer->odp_to_ofport_map); - node = shash_find(&all_dpif_backers, backer->type); + shash_find_and_delete(&all_dpif_backers, backer->type); free(backer->type); - shash_delete(&all_dpif_backers, node); - udpif_destroy(backer->udpif); dpif_close(backer->dpif); ovs_assert(hmap_is_empty(&backer->subfacets)); @@ -1267,7 +1260,6 @@ construct(struct ofproto *ofproto_) classifier_init(&ofproto->facets); ofproto->consistency_rl = LLONG_MIN; - guarded_list_init(&ofproto->flow_mods); guarded_list_init(&ofproto->pins); ofproto_dpif_unixctl_init(); @@ -1392,11 +1384,10 @@ destruct(struct ofproto *ofproto_) struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); struct rule_dpif *rule, *next_rule; struct ofputil_packet_in *pin, *next_pin; - struct ofputil_flow_mod *fm, *next_fm; struct facet *facet, *next_facet; - struct list flow_mods, pins; struct cls_cursor cursor; struct oftable *table; + struct list pins; ovs_rwlock_rdlock(&ofproto->facets.rwlock); cls_cursor_init(&cursor, &ofproto->facets, NULL); @@ -1419,22 +1410,14 @@ destruct(struct ofproto *ofproto_) OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) { struct cls_cursor cursor; - ovs_rwlock_wrlock(&table->cls.rwlock); + ovs_rwlock_rdlock(&table->cls.rwlock); cls_cursor_init(&cursor, &table->cls, NULL); + ovs_rwlock_unlock(&table->cls.rwlock); CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, up.cr, &cursor) { - ofproto_rule_delete(&ofproto->up, &table->cls, &rule->up); + ofproto_rule_delete(&ofproto->up, &rule->up); } - ovs_rwlock_unlock(&table->cls.rwlock); } - guarded_list_pop_all(&ofproto->flow_mods, &flow_mods); - LIST_FOR_EACH_SAFE (fm, next_fm, list_node, &flow_mods) { - list_remove(&fm->list_node); - free(fm->ofpacts); - free(fm); - } - guarded_list_destroy(&ofproto->flow_mods); - guarded_list_pop_all(&ofproto->pins, &pins); LIST_FOR_EACH_SAFE (pin, next_pin, list_node, &pins) { list_remove(&pin->list_node); @@ -1469,9 +1452,8 @@ run_fast(struct ofproto *ofproto_) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); struct ofputil_packet_in *pin, *next_pin; - struct ofputil_flow_mod *fm, *next_fm; - struct list flow_mods, pins; struct ofport_dpif *ofport; + struct list pins; /* Do not perform any periodic activity required by 'ofproto' while * waiting for flow restore to complete. */ @@ -1479,19 +1461,6 @@ run_fast(struct ofproto *ofproto_) return 0; } - guarded_list_pop_all(&ofproto->flow_mods, &flow_mods); - LIST_FOR_EACH_SAFE (fm, next_fm, list_node, &flow_mods) { - int error = ofproto_flow_mod(&ofproto->up, fm); - if (error && !VLOG_DROP_WARN(&rl)) { - VLOG_WARN("learning action failed to modify flow table (%s)", - ofperr_get_name(error)); - } - - list_remove(&fm->list_node); - free(fm->ofpacts); - free(fm); - } - guarded_list_pop_all(&ofproto->pins, &pins); LIST_FOR_EACH_SAFE (pin, next_pin, list_node, &pins) { connmgr_send_packet_in(ofproto->up.connmgr, pin); @@ -3272,7 +3241,7 @@ flow_miss_should_make_facet(struct flow_miss *miss) hash = flow_hash_in_wildcards(&miss->flow, &miss->xout.wc, 0); return governor_should_install_flow(backer->governor, hash, - list_size(&miss->packets)); + miss->stats.n_packets); } /* Handles 'miss', which matches 'facet'. May add any required datapath @@ -3350,7 +3319,7 @@ handle_flow_miss(struct flow_miss *miss, struct flow_miss_op *ops, { struct facet *facet; - miss->ofproto->n_missed += list_size(&miss->packets); + miss->ofproto->n_missed += miss->stats.n_packets; facet = facet_lookup_valid(miss->ofproto, &miss->flow); if (!facet) { @@ -3587,7 +3556,7 @@ handle_upcalls(struct dpif_backer *backer) static int subfacet_max_idle(const struct dpif_backer *); static void update_stats(struct dpif_backer *); -static void rule_expire(struct rule_dpif *); +static void rule_expire(struct rule_dpif *) OVS_REQUIRES(ofproto_mutex); static void expire_subfacets(struct dpif_backer *, int dp_max_idle); /* This function is called periodically by run(). Its job is to collect @@ -3907,30 +3876,31 @@ expire_subfacets(struct dpif_backer *backer, int dp_max_idle) * then delete it entirely. */ static void rule_expire(struct rule_dpif *rule) + OVS_REQUIRES(ofproto_mutex) { uint16_t idle_timeout, hard_timeout; - long long int now; - uint8_t reason; + long long int now = time_msec(); + int reason; ovs_assert(!rule->up.pending); - ovs_mutex_lock(&rule->up.timeout_mutex); + /* Has 'rule' expired? */ + ovs_mutex_lock(&rule->up.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 (hard_timeout && now > rule->up.modified + hard_timeout * 1000) { reason = OFPRR_HARD_TIMEOUT; } else if (idle_timeout && now > rule->up.used + idle_timeout * 1000) { reason = OFPRR_IDLE_TIMEOUT; } else { - return; + reason = -1; } + ovs_mutex_unlock(&rule->up.mutex); - COVERAGE_INC(ofproto_dpif_expired); - ofproto_rule_expire(&rule->up, reason); + if (reason >= 0) { + COVERAGE_INC(ofproto_dpif_expired); + ofproto_rule_expire(&rule->up, reason); + } } /* Facets. */ @@ -4122,17 +4092,21 @@ facet_is_controller_flow(struct facet *facet) if (facet) { struct ofproto_dpif *ofproto = facet->ofproto; const struct ofpact *ofpacts; + struct rule_actions *actions; struct rule_dpif *rule; size_t ofpacts_len; bool is_controller; rule_dpif_lookup(ofproto, &facet->flow, NULL, &rule); - ofpacts_len = rule->up.actions->ofpacts_len; - ofpacts = rule->up.actions->ofpacts; + actions = rule_dpif_get_actions(rule); + rule_dpif_unref(rule); + + ofpacts_len = actions->ofpacts_len; + ofpacts = actions->ofpacts; is_controller = ofpacts_len > 0 && ofpacts->type == OFPACT_CONTROLLER && ofpact_next(ofpacts) >= ofpact_end(ofpacts, ofpacts_len); - rule_dpif_unref(rule); + rule_actions_unref(actions); return is_controller; } @@ -4354,7 +4328,10 @@ facet_revalidate(struct facet *facet) facet->xout.nf_output_iface = xout.nf_output_iface; facet->xout.mirrors = xout.mirrors; facet->nf_flow.output_iface = facet->xout.nf_output_iface; + + ovs_mutex_lock(&new_rule->up.mutex); facet->used = MAX(facet->used, new_rule->up.created); + ovs_mutex_unlock(&new_rule->up.mutex); xlate_out_uninit(&xout); rule_dpif_unref(new_rule); @@ -4474,6 +4451,7 @@ rule_dpif_fail_open(const struct rule_dpif *rule) ovs_be64 rule_dpif_get_flow_cookie(const struct rule_dpif *rule) + OVS_REQUIRES(rule->up.mutex) { return rule->up.flow_cookie; } @@ -4491,14 +4469,7 @@ rule_dpif_reduce_timeouts(struct rule_dpif *rule, uint16_t idle_timeout, struct rule_actions * rule_dpif_get_actions(const struct rule_dpif *rule) { - struct rule_actions *actions; - - ovs_mutex_lock(&rule->up.mutex); - actions = rule->up.actions; - rule_actions_ref(actions); - ovs_mutex_unlock(&rule->up.mutex); - - return actions; + return rule_get_actions(&rule->up); } /* Subfacets. */ @@ -4528,7 +4499,6 @@ static struct subfacet * subfacet_create(struct facet *facet, struct flow_miss *miss) { struct dpif_backer *backer = miss->ofproto->backer; - enum odp_key_fitness key_fitness = miss->key_fitness; const struct nlattr *key = miss->key; size_t key_len = miss->key_len; uint32_t key_hash; @@ -4556,7 +4526,6 @@ subfacet_create(struct facet *facet, struct flow_miss *miss) hmap_insert(&backer->subfacets, &subfacet->hmap_node, key_hash); list_push_back(&facet->subfacets, &subfacet->list_node); subfacet->facet = facet; - subfacet->key_fitness = key_fitness; subfacet->key = xmemdup(key, key_len); subfacet->key_len = key_len; subfacet->used = miss->stats.used; @@ -4777,7 +4746,7 @@ rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto, const struct flow *flow, struct flow_wildcards *wc, uint8_t table_id, struct rule_dpif **rule) { - struct cls_rule *cls_rule; + const struct cls_rule *cls_rule; struct classifier *cls; bool frag; @@ -4845,6 +4814,7 @@ rule_dpif_unref(struct rule_dpif *rule) static void complete_operation(struct rule_dpif *rule) + OVS_REQUIRES(ofproto_mutex) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto); @@ -4885,6 +4855,7 @@ rule_construct(struct rule *rule_) static void rule_insert(struct rule *rule_) + OVS_REQUIRES(ofproto_mutex) { struct rule_dpif *rule = rule_dpif_cast(rule_); complete_operation(rule); @@ -4892,6 +4863,7 @@ rule_insert(struct rule *rule_) static void rule_delete(struct rule *rule_) + OVS_REQUIRES(ofproto_mutex) { struct rule_dpif *rule = rule_dpif_cast(rule_); complete_operation(rule); @@ -4956,6 +4928,7 @@ rule_execute(struct rule *rule, const struct flow *flow, static void rule_modify_actions(struct rule *rule_, bool reset_counters) + OVS_REQUIRES(ofproto_mutex) { struct rule_dpif *rule = rule_dpif_cast(rule_); @@ -5270,22 +5243,32 @@ struct trace_ctx { static void trace_format_rule(struct ds *result, int level, const struct rule_dpif *rule) { + struct rule_actions *actions; + ovs_be64 cookie; + ds_put_char_multiple(result, '\t', level); if (!rule) { ds_put_cstr(result, "No match\n"); return; } + ovs_mutex_lock(&rule->up.mutex); + cookie = rule->up.flow_cookie; + ovs_mutex_unlock(&rule->up.mutex); + ds_put_format(result, "Rule: table=%"PRIu8" cookie=%#"PRIx64" ", - rule ? rule->up.table_id : 0, ntohll(rule->up.flow_cookie)); + rule ? rule->up.table_id : 0, ntohll(cookie)); cls_rule_format(&rule->up.cr, result); ds_put_char(result, '\n'); + actions = rule_dpif_get_actions(rule); + ds_put_char_multiple(result, '\t', level); ds_put_cstr(result, "OpenFlow "); - ofpacts_format(rule->up.actions->ofpacts, rule->up.actions->ofpacts_len, - result); + ofpacts_format(actions->ofpacts, actions->ofpacts_len, result); ds_put_char(result, '\n'); + + rule_actions_unref(actions); } static void