On Wed, Apr 11, 2012 at 01:04:37PM -0700, Ethan Jackson wrote:
> In some datapaths, adding or deleting OpenFlow ports can take quite
> a bit of time.  If there are lots of OpenFlow ports which needed to
> be added in a run loop, this can cause Open vSwitch to lock up and
> stop setting up flows while trying to catch up.  This patch lessons
> the severity of the problem by only doing a few OpenFlow port adds
> or deletions per run loop allowing other work to be done in
> between.
> 
> Bug #10672.
> Signed-off-by: Ethan Jackson <et...@nicira.com>
> ---
> 
> I've tested this version on my virtual machine, but still need to try it on a
> real server before merging it.  I don't expect it to need to change so I'm
> sending it out for review now.

It looks OK to me.

I couldn't resist the urge to tinker with the details, so here's an
incremental.  Feel free to take it or leave it as you like.

diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 314fc71..57a1b89 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -167,9 +167,9 @@ static size_t bridge_get_controllers(const struct bridge 
*br,
 static void bridge_add_del_ports(struct bridge *,
                                  const unsigned long int *splinter_vlans);
 static void bridge_add_ofproto_ports(struct bridge *,
-                                     long long int port_action_timer);
+                                     long long int *port_action_timer);
 static void bridge_del_ofproto_ports(struct bridge *,
-                                     long long int port_action_timer);
+                                     long long int *port_action_timer);
 static void bridge_refresh_ofp_port(struct bridge *);
 static void bridge_configure_datapath_id(struct bridge *);
 static void bridge_configure_flow_eviction_threshold(struct bridge *);
@@ -416,8 +416,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
*ovs_cfg)
 
     COVERAGE_INC(bridge_reconfigure);
 
-    time_refresh();
-    port_action_timer = time_msec() + OFP_PORT_ACTION_WINDOW;
+    port_action_timer = LLONG_MAX;
     need_reconfigure = false;
 
     /* Create and destroy "struct bridge"s, "struct port"s, and "struct
@@ -442,7 +441,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
*ovs_cfg)
     bridge_del_ofprotos();
     HMAP_FOR_EACH (br, node, &all_bridges) {
         if (br->ofproto) {
-            bridge_del_ofproto_ports(br, port_action_timer);
+            bridge_del_ofproto_ports(br, &port_action_timer);
         }
     }
 
@@ -455,7 +454,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
*ovs_cfg)
     HMAP_FOR_EACH_SAFE (br, next, node, &all_bridges) {
         if (!br->ofproto) {
             if (bridge_add_ofprotos(br)) {
-                bridge_del_ofproto_ports(br, port_action_timer);
+                bridge_del_ofproto_ports(br, &port_action_timer);
             } else {
                 bridge_destroy(br);
             }
@@ -463,7 +462,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
*ovs_cfg)
     }
     HMAP_FOR_EACH (br, node, &all_bridges) {
         bridge_refresh_ofp_port(br);
-        bridge_add_ofproto_ports(br, port_action_timer);
+        bridge_add_ofproto_ports(br, &port_action_timer);
     }
 
     /* Complete the configuration. */
@@ -1053,23 +1052,20 @@ add_del_bridges(const struct ovsrec_open_vswitch *cfg)
 }
 
 static bool
-may_port_action(long long int port_action_timer)
+may_port_action(long long int *port_action_timer)
 {
-    if (time_msec() < port_action_timer) {
-        time_refresh();
-    }
-
-    if (time_msec() < port_action_timer) {
-        return true;
+    if (need_reconfigure) {
+        return false;
     }
 
-    /* Guarantee at least one port is acted on per run loop. */
-    if (!need_reconfigure) {
+    time_refresh();
+    if (*port_action_timer == LLONG_MAX) {
+        *port_action_timer = time_msec() + OFP_PORT_ACTION_WINDOW;
+    } else if (time_msec() > *port_action_timer) {
         need_reconfigure = true;
-        return true;
+        return false;
     }
-
-    return false;
+    return true;
 }
 
 /* Delete each ofproto port on 'br' that doesn't have a corresponding "struct
@@ -1080,7 +1076,7 @@ may_port_action(long long int port_action_timer)
  * deletions before any port additions. */
 static void
 bridge_del_ofproto_ports(struct bridge *br,
-                         long long int port_action_timer)
+                         long long int *port_action_timer)
 {
     struct ofproto_port_dump dump;
     struct ofproto_port ofproto_port;
@@ -1179,7 +1175,7 @@ bridge_refresh_ofp_port(struct bridge *br)
  * Delete any "struct port" that thereby ends up with no ifaces. */
 static void
 bridge_add_ofproto_ports(struct bridge *br,
-                         long long int port_action_timer)
+                         long long int *port_action_timer)
 {
     struct port *port, *next_port;
 

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to