dpif: Improve abstraction by making 'run' and 'wait' functions per-dpif.
authorBen Pfaff <blp@nicira.com>
Fri, 6 May 2011 22:04:29 +0000 (15:04 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 11 May 2011 19:26:07 +0000 (12:26 -0700)
Until now, the dp_run() and dp_wait() functions had to be called at the top
level of the program because they applied to every open dpif.  By replacing
them by functions that take a specific dpif as an argument, we can call
them only from ofproto, which is currently the correct layer to deal with
dpifs.

lib/dpif-linux.c
lib/dpif-netdev.c
lib/dpif-provider.h
lib/dpif.c
lib/dpif.h
ofproto/ofproto.c
utilities/ovs-openflowd.c
vswitchd/ovs-vswitchd.c

index fa8eea6e7a26c3c5ac4ceaa1869a7a774c5f3a73..e2c911cf967dc0428898ba65ba97ca7837cca644 100644 (file)
@@ -994,12 +994,12 @@ dpif_linux_recv_purge(struct dpif *dpif_)
 
 const struct dpif_class dpif_linux_class = {
     "system",
-    NULL,                       /* run */
-    NULL,                       /* wait */
     dpif_linux_enumerate,
     dpif_linux_open,
     dpif_linux_close,
     dpif_linux_destroy,
+    NULL,                       /* run */
+    NULL,                       /* wait */
     dpif_linux_get_stats,
     dpif_linux_get_drop_frags,
     dpif_linux_set_drop_frags,
index 5efc8697b0c9fc3b9cce0962a740384f54fd52a6..50052708afe8b982f93de910f79ab0b5ad7cefb1 100644 (file)
@@ -1090,52 +1090,44 @@ dp_netdev_port_input(struct dp_netdev *dp, struct dp_netdev_port *port,
 }
 
 static void
-dp_netdev_run(void)
+dpif_netdev_run(struct dpif *dpif)
 {
-    struct shash_node *node;
+    struct dp_netdev *dp = get_dp_netdev(dpif);
+    struct dp_netdev_port *port;
     struct ofpbuf packet;
 
     ofpbuf_init(&packet, DP_NETDEV_HEADROOM + VLAN_ETH_HEADER_LEN + max_mtu);
-    SHASH_FOR_EACH (node, &dp_netdevs) {
-        struct dp_netdev *dp = node->data;
-        struct dp_netdev_port *port;
-
-        LIST_FOR_EACH (port, node, &dp->port_list) {
-            int error;
-
-            /* Reset packet contents. */
-            ofpbuf_clear(&packet);
-            ofpbuf_reserve(&packet, DP_NETDEV_HEADROOM);
 
-            error = netdev_recv(port->netdev, &packet);
-            if (!error) {
-                dp_netdev_port_input(dp, port, &packet);
-            } else if (error != EAGAIN && error != EOPNOTSUPP) {
-                static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
-                VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
-                            netdev_get_name(port->netdev), strerror(error));
-            }
+    LIST_FOR_EACH (port, node, &dp->port_list) {
+        int error;
+
+        /* Reset packet contents. */
+        ofpbuf_clear(&packet);
+        ofpbuf_reserve(&packet, DP_NETDEV_HEADROOM);
+
+        error = netdev_recv(port->netdev, &packet);
+        if (!error) {
+            dp_netdev_port_input(dp, port, &packet);
+        } else if (error != EAGAIN && error != EOPNOTSUPP) {
+            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+            VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
+                        netdev_get_name(port->netdev), strerror(error));
         }
     }
     ofpbuf_uninit(&packet);
 }
 
 static void
-dp_netdev_wait(void)
+dpif_netdev_wait(struct dpif *dpif)
 {
-    struct shash_node *node;
-
-    SHASH_FOR_EACH (node, &dp_netdevs) {
-        struct dp_netdev *dp = node->data;
-        struct dp_netdev_port *port;
+    struct dp_netdev *dp = get_dp_netdev(dpif);
+    struct dp_netdev_port *port;
 
-        LIST_FOR_EACH (port, node, &dp->port_list) {
-            netdev_recv_wait(port->netdev);
-        }
+    LIST_FOR_EACH (port, node, &dp->port_list) {
+        netdev_recv_wait(port->netdev);
     }
 }
 
-
 static void
 dp_netdev_strip_vlan(struct ofpbuf *packet)
 {
@@ -1378,12 +1370,12 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
 
 const struct dpif_class dpif_netdev_class = {
     "netdev",
-    dp_netdev_run,
-    dp_netdev_wait,
     NULL,                       /* enumerate */
     dpif_netdev_open,
     dpif_netdev_close,
     dpif_netdev_destroy,
+    dpif_netdev_run,
+    dpif_netdev_wait,
     dpif_netdev_get_stats,
     dpif_netdev_get_drop_frags,
     dpif_netdev_set_drop_frags,
index 4d367530e3c220785c2b30edf7a8aa0ef97ed357..8670906a522e090a88c661d4598bc0f86f8bbd5c 100644 (file)
@@ -69,14 +69,6 @@ struct dpif_class {
      * the type assumed if no type is specified when opening a dpif. */
     const char *type;
 
-    /* Performs periodic work needed by dpifs of this class, if any is
-     * necessary. */
-    void (*run)(void);
-
-    /* Arranges for poll_block() to wake up if the "run" member function needs
-     * to be called. */
-    void (*wait)(void);
-
     /* Enumerates the names of all known created datapaths, if possible, into
      * 'all_dps'.  The caller has already initialized 'all_dps' and other dpif
      * classes might already have added names to it.
@@ -108,6 +100,13 @@ struct dpif_class {
      * the 'close' member function. */
     int (*destroy)(struct dpif *dpif);
 
+    /* Performs periodic work needed by 'dpif', if any is necessary. */
+    void (*run)(struct dpif *dpif);
+
+    /* Arranges for poll_block() to wake up if the "run" member function needs
+     * to be called for 'dpif'. */
+    void (*wait)(struct dpif *dpif);
+
     /* Retrieves statistics for 'dpif' into 'stats'. */
     int (*get_stats)(const struct dpif *dpif, struct odp_stats *stats);
 
index 3786bb72d5c70285dcbfd4d6a2c6d878902d3974..aaa8075b1a3809d7aeb080747d7a2b79a975494e 100644 (file)
@@ -101,38 +101,6 @@ dp_initialize(void)
     }
 }
 
-/* Performs periodic work needed by all the various kinds of dpifs.
- *
- * If your program opens any dpifs, it must call both this function and
- * netdev_run() within its main poll loop. */
-void
-dp_run(void)
-{
-    struct shash_node *node;
-    SHASH_FOR_EACH(node, &dpif_classes) {
-        const struct registered_dpif_class *registered_class = node->data;
-        if (registered_class->dpif_class->run) {
-            registered_class->dpif_class->run();
-        }
-    }
-}
-
-/* Arranges for poll_block() to wake up when dp_run() needs to be called.
- *
- * If your program opens any dpifs, it must call both this function and
- * netdev_wait() within its main poll loop. */
-void
-dp_wait(void)
-{
-    struct shash_node *node;
-    SHASH_FOR_EACH(node, &dpif_classes) {
-        const struct registered_dpif_class *registered_class = node->data;
-        if (registered_class->dpif_class->wait) {
-            registered_class->dpif_class->wait();
-        }
-    }
-}
-
 /* Registers a new datapath provider.  After successful registration, new
  * datapaths of that type can be opened using dpif_open(). */
 int
@@ -345,6 +313,25 @@ dpif_close(struct dpif *dpif)
     }
 }
 
+/* Performs periodic work needed by 'dpif'. */
+void
+dpif_run(struct dpif *dpif)
+{
+    if (dpif->dpif_class->run) {
+        dpif->dpif_class->run(dpif);
+    }
+}
+
+/* Arranges for poll_block() to wake up when dp_run() needs to be called for
+ * 'dpif'. */
+void
+dpif_wait(struct dpif *dpif)
+{
+    if (dpif->dpif_class->wait) {
+        dpif->dpif_class->wait(dpif);
+    }
+}
+
 /* Returns the name of datapath 'dpif' prefixed with the type
  * (for use in log messages). */
 const char *
index d6adbc3024e4871f065d096ea1b73cd2c08534d1..a4e5568f97e3b940285833f7624c59c05beaed3a 100644 (file)
@@ -37,9 +37,6 @@ struct ofpbuf;
 struct sset;
 struct dpif_class;
 
-void dp_run(void);
-void dp_wait(void);
-
 int dp_register_provider(const struct dpif_class *);
 int dp_unregister_provider(const char *type);
 void dp_enumerate_types(struct sset *types);
@@ -52,6 +49,9 @@ int dpif_create(const char *name, const char *type, struct dpif **);
 int dpif_create_and_open(const char *name, const char *type, struct dpif **);
 void dpif_close(struct dpif *);
 
+void dpif_run(struct dpif *);
+void dpif_wait(struct dpif *);
+
 const char *dpif_name(const struct dpif *);
 const char *dpif_base_name(const struct dpif *);
 
index 002470ec0aec1437c425d1e74852df162a6a030d..eb251d6f9bf1e6bd41cb4ad4d2fbcf12411f7aa4 100644 (file)
@@ -1351,6 +1351,8 @@ ofproto_run(struct ofproto *p)
     int error;
     int i;
 
+    dpif_run(p->dpif);
+
     for (i = 0; i < 50; i++) {
         struct dpif_upcall packet;
 
@@ -1429,6 +1431,7 @@ ofproto_wait(struct ofproto *p)
     struct ofbundle *bundle;
     struct ofport *ofport;
 
+    dpif_wait(p->dpif);
     HMAP_FOR_EACH (ofport, hmap_node, &p->ports) {
         ofport_wait(ofport);
     }
index c4d41d1ea321212b5edcbf022b9580b3a3e28913..4e83036729d2959e582a40c493dc87ae287af02e 100644 (file)
@@ -170,12 +170,10 @@ main(int argc, char *argv[])
             VLOG_FATAL("unrecoverable datapath error (%s)", strerror(error));
         }
         unixctl_server_run(unixctl);
-        dp_run();
         netdev_run();
 
         ofproto_wait(ofproto);
         unixctl_server_wait(unixctl);
-        dp_wait();
         netdev_wait();
         if (exiting) {
             poll_immediate_wake();
index b9a24618404c6cd753f7b7bdf1034d8a8ea24ff9..203626cb0fe3062d3595750e02cafa7c42ea7da2 100644 (file)
@@ -30,7 +30,6 @@
 #include "command-line.h"
 #include "compiler.h"
 #include "daemon.h"
-#include "dpif.h"
 #include "dummy.h"
 #include "leak-checker.h"
 #include "netdev.h"
@@ -90,13 +89,11 @@ main(int argc, char *argv[])
         }
         bridge_run();
         unixctl_server_run(unixctl);
-        dp_run();
         netdev_run();
 
         signal_wait(sighup);
         bridge_wait();
         unixctl_server_wait(unixctl);
-        dp_wait();
         netdev_wait();
         if (exiting) {
             poll_immediate_wake();