From: Ethan Jackson Date: Tue, 3 Sep 2013 22:37:14 +0000 (-0700) Subject: ofproto-dpif: Don't manage eviction groups from threads. X-Git-Tag: sliver-openvswitch-2.0.90-1~16^2~23 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;ds=sidebyside;h=448c2fa80c7ef9358179a0cdc68cf1feca782e6d;p=sliver-openvswitch.git ofproto-dpif: Don't manage eviction groups from threads. Managing eviction groups from threads was going to be difficult to do in a performant thread-safe manner, so this patch punts the problem to the main thread. Signed-off-by: Ethan Jackson Acked-by: Ben Pfaff --- diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 455b0f78d..4df12c8bc 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -4530,7 +4530,7 @@ rule_dpif_credit_stats(struct rule_dpif *rule, ovs_mutex_lock(&rule->stats_mutex); rule->packet_count += stats->n_packets; rule->byte_count += stats->n_bytes; - ofproto_rule_update_used(&rule->up, stats->used); + rule->up.used = MAX(rule->up.used, stats->used); ovs_mutex_unlock(&rule->stats_mutex); } diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index ab640c222..52a701409 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -69,6 +69,7 @@ struct ofproto { uint16_t max_ports; /* Max possible OpenFlow port num, plus one. */ /* Flow tables. */ + long long int eviction_group_timer; /* For rate limited reheapification. */ struct oftable *tables; int n_tables; @@ -282,7 +283,6 @@ rule_from_cls_rule(const struct cls_rule *cls_rule) return cls_rule ? CONTAINER_OF(cls_rule, struct rule, cr) : NULL; } -void ofproto_rule_update_used(struct rule *, long long int used); void ofproto_rule_expire(struct rule *rule, uint8_t reason); void ofproto_rule_delete(struct ofproto *, struct classifier *cls, struct rule *) OVS_REQ_WRLOCK(cls->rwlock); diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 5f5cd801a..3747eef79 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -440,6 +440,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type, shash_init(&ofproto->port_by_name); simap_init(&ofproto->ofp_requests); ofproto->max_ports = ofp_to_u16(OFPP_MAX); + ofproto->eviction_group_timer = LLONG_MIN; ofproto->tables = NULL; ofproto->n_tables = 0; hindex_init(&ofproto->cookies); @@ -1278,6 +1279,39 @@ ofproto_run(struct ofproto *p) VLOG_ERR_RL(&rl, "%s: run failed (%s)", p->name, ovs_strerror(error)); } + /* Restore the eviction group heap invariant occasionally. */ + if (p->eviction_group_timer < time_msec()) { + size_t i; + + p->eviction_group_timer = time_msec() + 1000; + + for (i = 0; i < p->n_tables; i++) { + struct oftable *table = &p->tables[i]; + struct eviction_group *evg; + struct cls_cursor cursor; + struct cls_rule cr; + struct rule *rule; + + if (!table->eviction_fields) { + continue; + } + + HEAP_FOR_EACH (evg, size_node, &table->eviction_groups_by_size) { + heap_rebuild(&evg->rules); + } + + ovs_rwlock_rdlock(&table->cls.rwlock); + cls_cursor_init(&cursor, &table->cls, &cr); + CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { + if (!rule->eviction_group + && (rule->idle_timeout || rule->hard_timeout)) { + eviction_group_add_rule(rule); + } + } + ovs_rwlock_unlock(&table->cls.rwlock); + } + } + if (p->ofproto_class->port_poll) { char *devname; @@ -3810,20 +3844,6 @@ ofproto_rule_send_removed(struct rule *rule, uint8_t reason) connmgr_send_flow_removed(rule->ofproto->connmgr, &fr); } -void -ofproto_rule_update_used(struct rule *rule, long long int used) -{ - if (used > rule->used) { - struct eviction_group *evg = rule->eviction_group; - - rule->used = used; - if (evg) { - heap_change(&evg->rules, &rule->evg_node, - rule_eviction_priority(rule)); - } - } -} - /* Sends an OpenFlow "flow removed" message with the given 'reason' (either * OFPRR_HARD_TIMEOUT or OFPRR_IDLE_TIMEOUT), and then removes 'rule' from its * ofproto. @@ -3882,10 +3902,6 @@ ofproto_rule_reduce_timeouts(struct rule *rule, reduce_timeout(idle_timeout, &rule->idle_timeout); reduce_timeout(hard_timeout, &rule->hard_timeout); ovs_mutex_unlock(&rule->timeout_mutex); - - if (!rule->eviction_group) { - eviction_group_add_rule(rule); - } } static enum ofperr