[ovs-dev] [next 30/35] dpif: Improve abstraction by making 'run' and 'wait' functions per-dpif.

Ben Pfaff blp at nicira.com
Tue Apr 26 16:24:56 UTC 2011


Until now, the dp_run() and dp_wait() functions ad 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          |    4 +-
 lib/dpif-netdev.c         |   56 +++++++++++++++++++-------------------------
 lib/dpif-provider.h       |   15 +++++------
 lib/dpif.c                |   51 +++++++++++++++-------------------------
 lib/dpif.h                |    6 ++--
 ofproto/ofproto.c         |    3 ++
 utilities/ovs-openflowd.c |    2 -
 vswitchd/ovs-vswitchd.c   |    3 --
 8 files changed, 58 insertions(+), 82 deletions(-)

diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index fa8eea6..e2c911c 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -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,
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 5efc869..5005270 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -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,
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index 4d36753..8670906 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -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);
 
diff --git a/lib/dpif.c b/lib/dpif.c
index 3786bb7..aaa8075 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -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 *
diff --git a/lib/dpif.h b/lib/dpif.h
index d6adbc3..a4e5568 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -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 *);
 
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 7a741d5..6960853 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1347,6 +1347,8 @@ ofproto_run(struct ofproto *p)
     int error;
     int i;
 
+    dpif_run(p->dpif);
+
     for (i = 0; i < 50; i++) {
         struct dpif_upcall packet;
 
@@ -1425,6 +1427,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);
     }
diff --git a/utilities/ovs-openflowd.c b/utilities/ovs-openflowd.c
index c4d41d1..4e83036 100644
--- a/utilities/ovs-openflowd.c
+++ b/utilities/ovs-openflowd.c
@@ -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();
diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c
index b9a2461..203626c 100644
--- a/vswitchd/ovs-vswitchd.c
+++ b/vswitchd/ovs-vswitchd.c
@@ -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();
-- 
1.7.4.4




More information about the dev mailing list