summaryrefslogtreecommitdiff
path: root/ofproto
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2011-08-10 14:48:33 -0700
committerBen Pfaff <blp@nicira.com>2011-09-13 11:46:09 -0700
commitdd5616b3d2722dba0eb4597d4b04af9386f5bfbb (patch)
tree70699bd9746f13564adbf49ed9ac378d866102b0 /ofproto
parent0ff2282245a87f253843bf357988d7230139888f (diff)
downloadopenvswitch-dd5616b3d2722dba0eb4597d4b04af9386f5bfbb.tar.gz
ofproto: Avoid using list_size() to compute length of 'pending' list.
Currently this only gets checked for incoming OpenFlow OFPT_FLOW_MOD messages, so it's hard to imagine it being any kind of bottleneck, but the NXAST_LEARN action that is soon to be added will be able to create flows more quickly than we normally expect from a controller. (On the other hand, ofproto-dpif, outside of a special testing mode, always completes operations immediately, so 'pending' will always have length 0. But this change still feels right to me for some reason.)
Diffstat (limited to 'ofproto')
-rw-r--r--ofproto/ofproto-provider.h1
-rw-r--r--ofproto/ofproto.c8
2 files changed, 8 insertions, 1 deletions
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index fa583f869..6e29ed9b4 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -64,6 +64,7 @@ struct ofproto {
/* Flow table operation tracking. */
int state; /* Internal state. */
struct list pending; /* List of "struct ofopgroup"s. */
+ unsigned int n_pending; /* list_size(&pending). */
struct hmap deletions; /* All OFOPERATION_DELETE "ofoperation"s. */
};
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index cbd892815..079927bd5 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -338,6 +338,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
ofproto->connmgr = connmgr_create(ofproto, datapath_name, datapath_name);
ofproto->state = S_OPENFLOW;
list_init(&ofproto->pending);
+ ofproto->n_pending = 0;
hmap_init(&ofproto->deletions);
error = ofproto->ofproto_class->construct(ofproto, &n_tables);
@@ -713,6 +714,7 @@ ofproto_destroy__(struct ofproto *ofproto)
struct classifier *table;
assert(list_is_empty(&ofproto->pending));
+ assert(!ofproto->n_pending);
connmgr_destroy(ofproto->connmgr);
@@ -2475,7 +2477,8 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh)
return error;
}
- if (list_size(&ofproto->pending) >= 50) {
+ if (ofproto->n_pending >= 50) {
+ assert(!list_is_empty(&ofproto->pending));
return OFPROTO_POSTPONE;
}
@@ -2778,6 +2781,7 @@ ofopgroup_submit(struct ofopgroup *group)
ofopgroup_destroy(group);
} else {
list_push_back(&group->ofproto->pending, &group->ofproto_node);
+ group->ofproto->n_pending++;
}
}
@@ -2786,6 +2790,8 @@ ofopgroup_destroy(struct ofopgroup *group)
{
assert(list_is_empty(&group->ops));
if (!list_is_empty(&group->ofproto_node)) {
+ assert(group->ofproto->n_pending > 0);
+ group->ofproto->n_pending--;
list_remove(&group->ofproto_node);
}
if (!list_is_empty(&group->ofconn_node)) {