bond: Bonds never sleep if carrier changes.
authorEthan Jackson <ethan@nicira.com>
Tue, 17 May 2011 20:47:23 +0000 (13:47 -0700)
committerEthan Jackson <ethan@nicira.com>
Tue, 17 May 2011 21:03:05 +0000 (14:03 -0700)
The bonding code neglected to call netdev_monitor_poll() on its
monitor during bond_run().  Thus carrier changes would be
permanently queued in the monitor, preventing it from ever allowing
poll_loop to sleep.

lib/bond.c
lib/netdev.c
lib/netdev.h

index 929d6823621befa09b5c2ca150b825e4fa0e05fd..cf1d057180f31b920832d7bcdbcb30a57649676d 100644 (file)
@@ -466,6 +466,10 @@ bond_run(struct bond *bond, struct tag_set *tags, bool lacp_negotiated)
         bond->miimon_next_update = time_msec() + bond->miimon_interval;
     }
 
+    if (bond->monitor) {
+        netdev_monitor_flush(bond->monitor);
+    }
+
     /* Enable slaves based on link status and LACP feedback. */
     HMAP_FOR_EACH (slave, hmap_node, &bond->slaves) {
         bond_link_status_update(slave, tags);
index 771db5a5adfbdc9dd458838333d56ae25392350f..01d91dbb2d05ea663006fadb269f4404d836830d 100644 (file)
@@ -1549,6 +1549,15 @@ netdev_monitor_poll(struct netdev_monitor *monitor, char **devnamep)
     }
 }
 
+/* Clears all notifications from 'monitor'.  May be called instead of
+ * netdev_monitor_poll() by clients which don't care specifically which netdevs
+ * have changed.  */
+void
+netdev_monitor_flush(struct netdev_monitor *monitor)
+{
+    sset_clear(&monitor->changed_netdevs);
+}
+
 /* Registers with the poll loop to wake up from the next call to poll_block()
  * when netdev_monitor_poll(monitor) would indicate that a device has
  * changed. */
index 30bcf5ecc87b70971aef6ede5ffefc31d8d31290..81d74ae3108d40760d39cc0bbf275405dd1fe43d 100644 (file)
@@ -214,6 +214,7 @@ void netdev_monitor_destroy(struct netdev_monitor *);
 int netdev_monitor_add(struct netdev_monitor *, struct netdev *);
 void netdev_monitor_remove(struct netdev_monitor *, struct netdev *);
 int netdev_monitor_poll(struct netdev_monitor *, char **devnamep);
+void netdev_monitor_flush(struct netdev_monitor *);
 void netdev_monitor_poll_wait(const struct netdev_monitor *);
 
 #ifdef  __cplusplus