[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