[ovs-dev] [PATCHv2 2/5] ofproto-dpif: Don't poll ports when nothing changes

Joe Stringer joestringer at nicira.com
Thu Nov 14 23:28:26 UTC 2013


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 bfd, cfm, lacp and stp 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 <joestringer at nicira.com>
---
v2: Fixed mutex safety in netdev_vport_changed()
    Track STP changes

NB: I'm tracking STP changes in ofproto_port_set_state(), as the testsuite
would fail when I tracked them in stp_set_port_state(). The latter makes more
sense to me, but I clearly don't understand some interaction there because it
makes STP stop working. I tried a few combinations in lib/stp.c, but I couldn't
get any of them to work.

---
 lib/bfd.c              |    4 ++++
 lib/cfm.c              |    7 +++++++
 lib/lacp.c             |    3 +++
 ofproto/ofproto-dpif.c |    9 ++++++---
 ofproto/ofproto.c      |    1 +
 5 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/bfd.c b/lib/bfd.c
index 740f4fc..83223e1 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();
     }
 }
 
@@ -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();
 }
 
 static uint32_t
diff --git a/lib/cfm.c b/lib/cfm.c
index 9c65b34..2c15224 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();
+        }
+
         if (hmap_is_empty(&cfm->remote_mps)) {
             cfm->fault |= CFM_FAULT_RECV;
         }
@@ -497,6 +502,8 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex)
             if (old_cfm_fault == false || cfm->fault == false) {
                 cfm->flap_count++;
             }
+
+            netdev_notify();
         }
 
         cfm->booted = true;
diff --git a/lib/lacp.c b/lib/lacp.c
index fce65b3..7f153a2 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"
@@ -342,6 +343,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();
     }
 
 out:
@@ -544,6 +546,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();
         }
     }
     ovs_mutex_unlock(&mutex);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 3391594..1e4315f 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1472,7 +1472,6 @@ static int
 run(struct ofproto *ofproto_)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
-    struct ofport_dpif *ofport;
     struct ofbundle *bundle;
     int error;
 
@@ -1506,8 +1505,12 @@ run(struct ofproto *ofproto_)
         dpif_ipfix_run(ofproto->ipfix);
     }
 
-    HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
-        port_run(ofport);
+    if (ofproto_->change_seq != netdev_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);
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index a45e0db..1eae517 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2214,6 +2214,7 @@ ofproto_port_set_state(struct ofport *port, enum ofputil_port_state state)
         port->pp.state = state;
         connmgr_send_port_status(port->ofproto->connmgr, &port->pp,
                                  OFPPR_MODIFY);
+        netdev_notify();
     }
 }
 
-- 
1.7.9.5




More information about the dev mailing list