+ /* 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);
+ }
+ }
+