From 2e31a9b8c9b4b6df61ccb12601c1b226254fb492 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 12 Sep 2013 20:30:56 -0700 Subject: [PATCH] ofproto: Refactor eviction cases to use common code. Signed-off-by: Ben Pfaff Acked-by: Ethan Jackson --- ofproto/ofproto.c | 76 +++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 985ed67cd..e86f59806 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3616,32 +3616,40 @@ is_flow_deletion_pending(const struct ofproto *ofproto, return false; } -static enum ofperr -evict_rule_from_table(struct ofproto *ofproto, struct oftable *table) +static bool +should_evict_a_rule(struct oftable *table, unsigned int extra_space) { - struct rule *rule; - size_t n_rules; + size_t count; ovs_rwlock_rdlock(&table->cls.rwlock); - n_rules = classifier_count(&table->cls); + count = classifier_count(&table->cls); ovs_rwlock_unlock(&table->cls.rwlock); - if (n_rules < table->max_flows) { - return 0; - } else if (!choose_rule_to_evict(table, &rule)) { - return OFPERR_OFPFMFC_TABLE_FULL; - } else if (rule->pending) { - ovs_mutex_unlock(&rule->mutex); - return OFPROTO_POSTPONE; - } else { - struct ofopgroup *group; + return count + extra_space > table->max_flows; +} - group = ofopgroup_create_unattached(ofproto); - delete_flow__(rule, group, OFPRR_EVICTION); - ofopgroup_submit(group); +static enum ofperr +evict_rules_from_table(struct ofproto *ofproto, struct oftable *table, + unsigned int extra_space) +{ + while (should_evict_a_rule(table, extra_space)) { + struct rule *rule; - return 0; + if (!choose_rule_to_evict(table, &rule)) { + return OFPERR_OFPFMFC_TABLE_FULL; + } else if (rule->pending) { + ovs_mutex_unlock(&rule->mutex); + return OFPROTO_POSTPONE; + } else { + struct ofopgroup *group = ofopgroup_create_unattached(ofproto); + ofoperation_create(group, rule, + OFOPERATION_DELETE, OFPRR_EVICTION); + oftable_remove_rule(rule); + ofproto->ofproto_class->rule_delete(rule); + } } + + return 0; } /* Implements OFPFC_ADD and the cases for OFPFC_MODIFY and OFPFC_MODIFY_STRICT @@ -3751,7 +3759,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, } /* If necessary, evict an existing rule to clear out space. */ - error = evict_rule_from_table(ofproto, table); + error = evict_rules_from_table(ofproto, table, 1); if (error) { cls_rule_destroy(&cr); return error; @@ -6014,39 +6022,11 @@ choose_rule_to_evict(struct oftable *table, struct rule **rulep) static void ofproto_evict(struct ofproto *ofproto) { - struct ofopgroup *group; struct oftable *table; - group = ofopgroup_create_unattached(ofproto); OFPROTO_FOR_EACH_TABLE (table, ofproto) { - while (table->eviction_fields) { - struct rule *rule; - size_t n_rules; - - ovs_rwlock_rdlock(&table->cls.rwlock); - n_rules = classifier_count(&table->cls); - ovs_rwlock_unlock(&table->cls.rwlock); - - if (n_rules <= table->max_flows) { - break; - } - - if (!choose_rule_to_evict(table, &rule)) { - break; - } - - if (rule->pending) { - ovs_mutex_unlock(&rule->mutex); - break; - } - - ofoperation_create(group, rule, - OFOPERATION_DELETE, OFPRR_EVICTION); - oftable_remove_rule(rule); - ofproto->ofproto_class->rule_delete(rule); - } + evict_rules_from_table(ofproto, table, 0); } - ofopgroup_submit(group); } /* Eviction groups. */ -- 2.43.0