From dd5616b3d2722dba0eb4597d4b04af9386f5bfbb Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 10 Aug 2011 14:48:33 -0700 Subject: [PATCH] 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.) --- ofproto/ofproto-provider.h | 1 + ofproto/ofproto.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index fa583f86..6e29ed9b 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 cbd89281..079927bd 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)) { -- 2.30.2