ofproto: Update rule's priority in eviction group.
authorkmindg <kmindg@gmail.com>
Sun, 9 Mar 2014 09:48:04 +0000 (17:48 +0800)
committerBen Pfaff <blp@nicira.com>
Wed, 12 Mar 2014 05:32:20 +0000 (22:32 -0700)
We do call heap_rebuild in ofproto_run, but we do not update rule's
priority with latest hard_timeout and idle_timeout before heap_rebuild.

This patch ensures that rule's priority has been updated before
heap_rebuild, and adds two test cases to check eviction with modified
hard_timeout and idle_timwout.

Signed-off-by: kmindg <kmindg@gmail.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
ofproto/ofproto.c
tests/ofproto.at

index e691bb9..45621e9 100644 (file)
@@ -1451,19 +1451,23 @@ ofproto_run(struct ofproto *p)
             }
 
             ovs_mutex_lock(&ofproto_mutex);
-            HEAP_FOR_EACH (evg, size_node, &table->eviction_groups_by_size) {
-                heap_rebuild(&evg->rules);
-            }
-
             fat_rwlock_rdlock(&table->cls.rwlock);
             cls_cursor_init(&cursor, &table->cls, NULL);
             CLS_CURSOR_FOR_EACH (rule, cr, &cursor) {
-                if (!rule->eviction_group
-                    && (rule->idle_timeout || rule->hard_timeout)) {
-                    eviction_group_add_rule(rule);
+                if (rule->idle_timeout || rule->hard_timeout) {
+                    if (!rule->eviction_group) {
+                        eviction_group_add_rule(rule);
+                    } else {
+                        heap_raw_change(&rule->evg_node,
+                                        rule_eviction_priority(p, rule));
+                    }
                 }
             }
             fat_rwlock_unlock(&table->cls.rwlock);
+
+            HEAP_FOR_EACH (evg, size_node, &table->eviction_groups_by_size) {
+                heap_rebuild(&evg->rules);
+            }
             ovs_mutex_unlock(&ofproto_mutex);
         }
     }
index f6a62cd..eb1680c 100644 (file)
@@ -1365,6 +1365,80 @@ OFPST_FLOW reply (OF1.2):
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - eviction upon table overflow, with modified hard timeout])
+OVS_VSWITCHD_START
+# Configure a maximum of 4 flows.
+AT_CHECK(
+  [ovs-vsctl \
+     -- --id=@t0 create Flow_Table flow-limit=4 overflow-policy=evict \
+     -- set bridge br0 flow_tables:0=@t0 \
+   | ${PERL} $srcdir/uuidfilt.pl],
+  [0], [<0>
+])
+# Add 4 flows.
+for in_port in 4 3 2 1; do
+    ovs-ofctl add-flow br0 hard_timeout=1${in_port},in_port=$in_port,actions=drop
+done
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ hard_timeout=11, in_port=1 actions=drop
+ hard_timeout=12, in_port=2 actions=drop
+ hard_timeout=13, in_port=3 actions=drop
+ hard_timeout=14, in_port=4 actions=drop
+NXST_FLOW reply:
+])
+# Sleep and modify the one that expires soonest
+sleep 2
+AT_CHECK([ovs-ofctl mod-flows br0 in_port=1,actions=drop])
+sleep 2
+# Adding another flow will cause the one that expires soonest to be evicted.
+AT_CHECK([ovs-ofctl add-flow br0 in_port=5,actions=drop])
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ hard_timeout=11, in_port=1 actions=drop
+ hard_timeout=13, in_port=3 actions=drop
+ hard_timeout=14, in_port=4 actions=drop
+ in_port=5 actions=drop
+NXST_FLOW reply:
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ofproto - eviction upon table overflow, with modified idle timeout])
+OVS_VSWITCHD_START([add-port br0 p1 -- set interface p1 type=dummy ofport_request=1])
+# Configure a maximum of 4 flows.
+AT_CHECK(
+  [ovs-vsctl \
+     -- --id=@t0 create Flow_Table flow-limit=4 overflow-policy=evict \
+     -- set bridge br0 flow_tables:0=@t0 \
+   | ${PERL} $srcdir/uuidfilt.pl],
+  [0], [<0>
+])
+# Add 4 flows.
+for in_port in 4 3 2 1; do
+    ovs-ofctl add-flow br0 idle_timeout=1${in_port},in_port=$in_port,actions=drop
+done
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ idle_timeout=11, in_port=1 actions=drop
+ idle_timeout=12, in_port=2 actions=drop
+ idle_timeout=13, in_port=3 actions=drop
+ idle_timeout=14, in_port=4 actions=drop
+NXST_FLOW reply:
+])
+# Sleep and receive on the flow that expires soonest
+sleep 2
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1)'])
+sleep 2
+# Adding another flow will cause the one that expires soonest to be evicted.
+AT_CHECK([ovs-ofctl add-flow br0 in_port=5,actions=drop])
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ idle_timeout=13, in_port=3 actions=drop
+ idle_timeout=14, in_port=4 actions=drop
+ in_port=5 actions=drop
+ n_packets=1, n_bytes=60, idle_timeout=11, in_port=1 actions=drop
+NXST_FLOW reply:
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto - asynchronous message control (OpenFlow 1.0)])
 OVS_VSWITCHD_START
 AT_CHECK([ovs-ofctl -P openflow10 monitor br0 --detach --no-chdir --pidfile])