Currently, as part of ofproto-dpif run() processing, we loop through all ports and poll corresponding devices for changes in carrier, cfm and bfd status. This allows us to determine how it may affect bundles. For the average case where devices are not going up or down constantly, this is a large amount of unnecessary processing.
This patch gets the cfm, bfd and lacp modules to update the global netdev change_seq when changes in port/device status occur. We can then use this global change_seq to check if anything has changed before looping through the ports in ofproto-dpif. In a test environment of 5000 internal ports and 50 tunnel ports with bfd, this reduces CPU usage from about 35% to about 25%. Signed-off-by: Joe Stringer <[email protected]> --- lib/bfd.c | 4 ++++ lib/cfm.c | 7 +++++++ lib/lacp.c | 3 +++ ofproto/ofproto-dpif.c | 9 ++++++--- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/bfd.c b/lib/bfd.c index 740f4fc..470d006 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -1019,6 +1019,8 @@ bfd_set_state(struct bfd *bfd, enum state state, enum diag diag) if (bfd->state == STATE_UP && bfd->decay_min_rx) { bfd_decay_update(bfd); } + + netdev_notify_change(); } } @@ -1090,6 +1092,8 @@ bfd_forwarding_if_rx_update(struct bfd *bfd) OVS_REQUIRES(mutex) { int64_t incr = bfd_rx_interval(bfd) * bfd->mult; bfd->forwarding_if_rx_detect_time = MAX(incr, 2000) + time_msec(); + + netdev_notify_change(); } static uint32_t diff --git a/lib/cfm.c b/lib/cfm.c index d256a5f..2dc9806 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -396,6 +396,7 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex) long long int interval = cfm_fault_interval(cfm); struct remote_mp *rmp, *rmp_next; bool old_cfm_fault = cfm->fault; + bool old_rmp_opup = cfm->remote_opup; bool demand_override; bool rmp_set_opup = false; bool rmp_set_opdown = false; @@ -476,6 +477,10 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex) cfm->remote_opup = true; } + if (old_rmp_opup != cfm->remote_opup) { + netdev_notify_change(); + } + if (hmap_is_empty(&cfm->remote_mps)) { cfm->fault |= CFM_FAULT_RECV; } @@ -495,6 +500,8 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex) if (old_cfm_fault == false || cfm->fault == false) { cfm->flap_count++; } + + netdev_notify_change(); } cfm->booted = true; diff --git a/lib/lacp.c b/lib/lacp.c index 5421e2a..54e3111 100644 --- a/lib/lacp.c +++ b/lib/lacp.c @@ -21,6 +21,7 @@ #include "dynamic-string.h" #include "hash.h" #include "hmap.h" +#include "netdev.h" #include "ofpbuf.h" #include "packets.h" #include "poll-loop.h" @@ -335,6 +336,7 @@ lacp_process_packet(struct lacp *lacp, const void *slave_, if (memcmp(&slave->partner, &pdu->actor, sizeof pdu->actor)) { lacp->update = true; slave->partner = pdu->actor; + netdev_notify_change(); } out: @@ -535,6 +537,7 @@ lacp_run(struct lacp *lacp, lacp_send_pdu *send_pdu) OVS_EXCLUDED(mutex) : LACP_SLOW_TIME_TX); timer_set_duration(&slave->tx, duration); + netdev_notify_change(); } } ovs_mutex_unlock(&mutex); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index da27f6a..3717365 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1470,7 +1470,6 @@ static int run(struct ofproto *ofproto_) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); - struct ofport_dpif *ofport; struct ofbundle *bundle; int error; @@ -1504,8 +1503,12 @@ run(struct ofproto *ofproto_) dpif_ipfix_run(ofproto->ipfix); } - HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) { - port_run(ofport); + if (netdev_changed(ofproto_->change_seq)) { + struct ofport_dpif *ofport; + + HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) { + port_run(ofport); + } } HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) { bundle_run(bundle); -- 1.7.9.5 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
