summaryrefslogtreecommitdiff
path: root/ofproto
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2018-02-23 14:03:15 -0800
committerBen Pfaff <blp@ovn.org>2018-02-26 11:35:33 -0800
commitc381bca52f629f3d35f00471dcd10cba1a9a3d99 (patch)
tree7e9a1c344cba8b2ee5cbfc3ef8c27ce5464d5431 /ofproto
parentee1c7296ece67b5b35e528620c645a9c3f2a5c16 (diff)
downloadopenvswitch-c381bca52f629f3d35f00471dcd10cba1a9a3d99.tar.gz
ofproto: Make ofproto_port_open_type() faster.
ofproto_port_open_type() was surprisingly slow because it called the function ofproto_class_find__(), which itself was surprisingly slow because it actually creates a set of strings and enumerates all of the available classes. This patch improves performance by eliminating the call to ofproto_class_find__() from ofproto_port_open_type(). In turn that required changing a parameter type and updating all the callers. Possibly it would be worth making ofproto_class_find__() itself faster, but it doesn't look like any of its other callers would be used in inner loops. For more background, see also https://mail.openvswitch.org/pipermail/ovs-discuss/2018-February/046140.html This patch arises as a result of testing done by Ali Ginwala and Han Zhou. Their test showed that commit 2d4beba resulted in slower performance of ovs-vswitchd than was seen in previous versions of OVS. With this patch, Ali retested and reported that performance drastically improved by ~60%. The test for 10k lports, 40 LSs and 8 LRs and 1k HVs just got completed in 3 hours 39 min vs 8+ hours for branch-2.9. Cpu utilization graph of a farm comparing Ben's ofproto patch vs branch-2.9 is available @ https://raw.githubusercontent.com/noah8713/ovn-scale-test/scale_results/results/ovs_2.9_vs_ben_ofproto.png Reported-by: Mark Michelson <mmichels@redhat.com> Acked-by: Mark Michelson <mmichels@redhat.com> Tested-by: aginwala <aginwala@asu.edu> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto')
-rw-r--r--ofproto/in-band.c2
-rw-r--r--ofproto/ofproto.c30
-rw-r--r--ofproto/ofproto.h2
3 files changed, 12 insertions, 22 deletions
diff --git a/ofproto/in-band.c b/ofproto/in-band.c
index 849b1ceda..82d8dfa14 100644
--- a/ofproto/in-band.c
+++ b/ofproto/in-band.c
@@ -428,7 +428,7 @@ in_band_create(struct ofproto *ofproto, const char *local_name,
struct in_band *in_band;
struct netdev *local_netdev;
int error;
- const char *type = ofproto_port_open_type(ofproto->type, "internal");
+ const char *type = ofproto_port_open_type(ofproto, "internal");
*in_bandp = NULL;
error = netdev_open(local_name, type, &local_netdev);
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index f28bb896e..a982de9d8 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1966,27 +1966,18 @@ ofproto_port_dump_done(struct ofproto_port_dump *dump)
return dump->error == EOF ? 0 : dump->error;
}
-/* Returns the type to pass to netdev_open() when a datapath of type
- * 'datapath_type' has a port of type 'port_type', for a few special
- * cases when a netdev type differs from a port type. For example, when
- * using the userspace datapath, a port of type "internal" needs to be
- * opened as "tap".
+/* Returns the type to pass to netdev_open() when 'ofproto' has a port of type
+ * 'port_type', for a few special cases when a netdev type differs from a port
+ * type. For example, when using the userspace datapath, a port of type
+ * "internal" needs to be opened as "tap".
*
* Returns either 'type' itself or a string literal, which must not be
* freed. */
const char *
-ofproto_port_open_type(const char *datapath_type, const char *port_type)
+ofproto_port_open_type(const struct ofproto *ofproto, const char *port_type)
{
- const struct ofproto_class *class;
-
- datapath_type = ofproto_normalize_type(datapath_type);
- class = ofproto_class_find__(datapath_type);
- if (!class) {
- return port_type;
- }
-
- return (class->port_open_type
- ? class->port_open_type(datapath_type, port_type)
+ return (ofproto->ofproto_class->port_open_type
+ ? ofproto->ofproto_class->port_open_type(ofproto->type, port_type)
: port_type);
}
@@ -2728,10 +2719,9 @@ init_ports(struct ofproto *p)
static bool
ofport_is_internal_or_patch(const struct ofproto *p, const struct ofport *port)
{
- return !strcmp(netdev_get_type(port->netdev),
- ofproto_port_open_type(p->type, "internal")) ||
- !strcmp(netdev_get_type(port->netdev),
- ofproto_port_open_type(p->type, "patch"));
+ const char *netdev_type = netdev_get_type(port->netdev);
+ return !strcmp(netdev_type, ofproto_port_open_type(p, "internal")) ||
+ !strcmp(netdev_type, ofproto_port_open_type(p, "patch"));
}
/* If 'port' is internal or patch and if the user didn't explicitly specify an
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index 1e48e1952..8c85bbf7f 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -290,7 +290,7 @@ int ofproto_port_dump_done(struct ofproto_port_dump *);
#define OFPROTO_FLOW_LIMIT_DEFAULT 200000
#define OFPROTO_MAX_IDLE_DEFAULT 10000 /* ms */
-const char *ofproto_port_open_type(const char *datapath_type,
+const char *ofproto_port_open_type(const struct ofproto *,
const char *port_type);
int ofproto_port_add(struct ofproto *, struct netdev *, ofp_port_t *ofp_portp);
int ofproto_port_del(struct ofproto *, ofp_port_t ofp_port);