From 640e1b20776f40633d33a5c2c2bba3e79eda0b64 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 6 May 2011 15:04:29 -0700 Subject: [PATCH] dpif: Improve abstraction by making 'run' and 'wait' functions per-dpif. 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 | 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 fa8eea6e..e2c911cf 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 5efc8697..50052708 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 4d367530..8670906a 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 3786bb72..aaa8075b 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 d6adbc30..a4e5568f 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 002470ec..eb251d6f 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -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); } diff --git a/utilities/ovs-openflowd.c b/utilities/ovs-openflowd.c index c4d41d1e..4e830367 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 b9a24618..203626cb 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(); -- 2.30.2