X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.c;h=4cebd77971d35fcd428340ecc2438628bebf15cd;hb=003ce655b7116d18c86a74c50391e54990346931;hp=5669cd18469fc192f9cf19fa39330d8ecee3b3a9;hpb=1a7c0cd710e19db3ff85606dbfd5fdad964a1eea;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 5669cd184..4cebd7797 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -73,10 +73,8 @@ VLOG_DEFINE_THIS_MODULE(ofproto_dpif); COVERAGE_DEFINE(ofproto_dpif_expired); COVERAGE_DEFINE(packet_in_overflow); -/* Number of implemented OpenFlow tables. */ -enum { N_TABLES = 255 }; -enum { TBL_INTERNAL = N_TABLES - 1 }; /* Used for internal hidden rules. */ -BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); +/* No bfd/cfm status change. */ +#define NO_STATUS_CHANGE -1 struct flow_miss; @@ -91,6 +89,9 @@ struct rule_dpif { struct dpif_flow_stats stats OVS_GUARDED; }; +/* RULE_CAST() depends on this. */ +BUILD_ASSERT_DECL(offsetof(struct rule_dpif, up) == 0); + static void rule_get_stats(struct rule *, uint64_t *packets, uint64_t *bytes, long long int *used); static struct rule_dpif *rule_dpif_cast(const struct rule *); @@ -314,6 +315,8 @@ struct ofproto_dpif { /* Work queues. */ struct guarded_list pins; /* Contains "struct ofputil_packet_in"s. */ + struct seq *pins_seq; /* For notifying 'pins' reception. */ + uint64_t pins_seqno; }; /* All existing ofproto_dpif instances, indexed by ->up.name. */ @@ -385,6 +388,9 @@ ofproto_dpif_send_packet_in(struct ofproto_dpif *ofproto, free(CONST_CAST(void *, pin->up.packet)); free(pin); } + + /* Wakes up main thread for packet-in I/O. */ + seq_change(ofproto->pins_seq); } /* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the @@ -1157,6 +1163,9 @@ construct(struct ofproto *ofproto_) sset_init(&ofproto->port_poll_set); ofproto->port_poll_errno = 0; ofproto->change_seq = 0; + ofproto->pins_seq = seq_create(); + ofproto->pins_seqno = seq_read(ofproto->pins_seq); + SHASH_FOR_EACH_SAFE (node, next, &init_ofp_ports) { struct iface_hint *iface_hint = node->data; @@ -1330,6 +1339,8 @@ destruct(struct ofproto *ofproto_) ovs_mutex_destroy(&ofproto->stats_mutex); ovs_mutex_destroy(&ofproto->vsp_mutex); + seq_destroy(ofproto->pins_seq); + close_dpif_backer(ofproto->backer); } @@ -1338,7 +1349,6 @@ run(struct ofproto *ofproto_) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); uint64_t new_seq, new_dump_seq; - const bool enable_recirc = ofproto_dpif_get_enable_recirc(ofproto); if (mbridge_need_revalidate(ofproto->mbridge)) { ofproto->backer->need_revalidate = REV_RECONFIGURE; @@ -1362,6 +1372,12 @@ run(struct ofproto *ofproto_) } } + /* Always updates the ofproto->pins_seqno to avoid frequent wakeup during + * flow restore. Even though nothing is processed during flow restore, + * all queued 'pins' will be handled immediately when flow restore + * completes. */ + ofproto->pins_seqno = seq_read(ofproto->pins_seq); + if (ofproto->netflow) { netflow_run(ofproto->netflow); } @@ -1416,17 +1432,12 @@ run(struct ofproto *ofproto_) /* All outstanding data in existing flows has been accounted, so it's a * good time to do bond rebalancing. */ - if (enable_recirc && ofproto->has_bonded_bundles) { + if (ofproto->has_bonded_bundles) { struct ofbundle *bundle; HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) { - struct bond *bond = bundle->bond; - - if (bond && bond_may_recirc(bond, NULL, NULL)) { - bond_recirculation_account(bond); - if (bond_rebalance(bundle->bond)) { - bond_update_post_recirc_rules(bond, true); - } + if (bundle->bond) { + bond_rebalance(bundle->bond); } } } @@ -1471,6 +1482,7 @@ wait(struct ofproto *ofproto_) } seq_wait(udpif_dump_seq(ofproto->backer->udpif), ofproto->dump_seq); + seq_wait(ofproto->pins_seq, ofproto->pins_seqno); } static void @@ -1813,22 +1825,28 @@ out: return error; } -static bool +static int get_cfm_status(const struct ofport *ofport_, struct ofproto_cfm_status *status) { struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); + int ret = 0; if (ofport->cfm) { - status->faults = cfm_get_fault(ofport->cfm); - status->flap_count = cfm_get_flap_count(ofport->cfm); - status->remote_opstate = cfm_get_opup(ofport->cfm); - status->health = cfm_get_health(ofport->cfm); - cfm_get_remote_mpids(ofport->cfm, &status->rmps, &status->n_rmps); - return true; + if (cfm_check_status_change(ofport->cfm)) { + status->faults = cfm_get_fault(ofport->cfm); + status->flap_count = cfm_get_flap_count(ofport->cfm); + status->remote_opstate = cfm_get_opup(ofport->cfm); + status->health = cfm_get_health(ofport->cfm); + cfm_get_remote_mpids(ofport->cfm, &status->rmps, &status->n_rmps); + } else { + ret = NO_STATUS_CHANGE; + } } else { - return false; + ret = ENOENT; } + + return ret; } static int @@ -1853,13 +1871,19 @@ static int get_bfd_status(struct ofport *ofport_, struct smap *smap) { struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); + int ret = 0; if (ofport->bfd) { - bfd_get_status(ofport->bfd, smap); - return 0; + if (bfd_check_status_change(ofport->bfd)) { + bfd_get_status(ofport->bfd, smap); + } else { + ret = NO_STATUS_CHANGE; + } } else { - return ENOENT; + ret = ENOENT; } + + return ret; } /* Spanning Tree. */ @@ -3142,24 +3166,6 @@ rule_dpif_credit_stats(struct rule_dpif *rule, ovs_mutex_unlock(&rule->stats_mutex); } -bool -rule_dpif_is_fail_open(const struct rule_dpif *rule) -{ - return is_fail_open_rule(&rule->up); -} - -bool -rule_dpif_is_table_miss(const struct rule_dpif *rule) -{ - return rule_is_table_miss(&rule->up); -} - -bool -rule_dpif_is_internal(const struct rule_dpif *rule) -{ - return rule_is_internal(&rule->up); -} - ovs_be64 rule_dpif_get_flow_cookie(const struct rule_dpif *rule) OVS_REQUIRES(rule->up.mutex) @@ -3177,7 +3183,7 @@ rule_dpif_reduce_timeouts(struct rule_dpif *rule, uint16_t idle_timeout, /* Returns 'rule''s actions. The caller owns a reference on the returned * actions and must eventually release it (with rule_actions_unref()) to avoid * a memory leak. */ -struct rule_actions * +const struct rule_actions * rule_dpif_get_actions(const struct rule_dpif *rule) { return rule_get_actions(&rule->up); @@ -3401,22 +3407,6 @@ choose_miss_rule(enum ofputil_port_config config, struct rule_dpif *miss_rule, } } -void -rule_dpif_ref(struct rule_dpif *rule) -{ - if (rule) { - ofproto_rule_ref(&rule->up); - } -} - -void -rule_dpif_unref(struct rule_dpif *rule) -{ - if (rule) { - ofproto_rule_unref(&rule->up); - } -} - static void complete_operation(struct rule_dpif *rule) OVS_REQUIRES(ofproto_mutex) @@ -3839,7 +3829,7 @@ struct trace_ctx { static void trace_format_rule(struct ds *result, int level, const struct rule_dpif *rule) { - struct rule_actions *actions; + const struct rule_actions *actions; ovs_be64 cookie; ds_put_char_multiple(result, '\t', level); @@ -4524,13 +4514,6 @@ ofproto_dpif_unixctl_init(void) ofproto_unixctl_dpif_dump_flows, NULL); } - -/* Returns true if 'rule' is an internal rule, false otherwise. */ -bool -rule_is_internal(const struct rule *rule) -{ - return rule->table_id == TBL_INTERNAL; -} /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) *