From c09f755dff4a7c0f78d59d1388461be3ec7e6895 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 15 Aug 2013 17:38:40 -0700 Subject: [PATCH] ofproto: Avoid extra O(N) work in common case on flow addition. The OpenFlow OFPFF_CHECK_OVERLAP flag requires us to check whether the flow being inserted overlaps with any existing flows. That isn't efficiently implemented and typically requires us to compare the new flow against most or all of the existing flows. We don't have to do that work if OFPFF_CHECK_OVERLAP is not requested, but commit 0b4f207828c (classifier: Make use of the classifier thread safe.) inadvertently made us do it anyway. Signed-off-by: Ben Pfaff Acked-by: Ethan Jackson --- ofproto/ofproto.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index bead3c4a1..c8edb2d47 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3359,7 +3359,6 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, struct rule *victim; struct rule *rule; uint8_t table_id; - bool overlaps; int error; error = check_table_id(ofproto, fm->table_id); @@ -3416,13 +3415,18 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, } /* Check for overlap, if requested. */ - ovs_rwlock_rdlock(&table->cls.rwlock); - overlaps = classifier_rule_overlaps(&table->cls, &rule->cr); - ovs_rwlock_unlock(&table->cls.rwlock); - if (fm->flags & OFPFF_CHECK_OVERLAP && overlaps) { - cls_rule_destroy(&rule->cr); - ofproto->ofproto_class->rule_dealloc(rule); - return OFPERR_OFPFMFC_OVERLAP; + if (fm->flags & OFPFF_CHECK_OVERLAP) { + bool overlaps; + + ovs_rwlock_rdlock(&table->cls.rwlock); + overlaps = classifier_rule_overlaps(&table->cls, &rule->cr); + ovs_rwlock_unlock(&table->cls.rwlock); + + if (overlaps) { + cls_rule_destroy(&rule->cr); + ofproto->ofproto_class->rule_dealloc(rule); + return OFPERR_OFPFMFC_OVERLAP; + } } /* FIXME: Implement OFPFF12_RESET_COUNTS */ -- 2.47.0