From: venu iyer <[email protected]>

Prior to multi-vtep, there was one tunnel for each type, since
there was only one encap-ip. So, the check in
chassis_tunnels_changed():

    sset_count(encap_type_set) != encap_type_count

worked. However, with multiple IPs per tunnel type, the above
check won't work. So, once multiple encap-ips are configured,
ovn-controller will always keep updating the encap list in
the SB (due to the above check); this causes a lot of unnecessary
churn, including recomputing the flows etc. which will put
ovn-controller in overdrive thereby consuming lot of CPU cycles
(see almost 100%)

Verified ovn-controller cpu utilization with the fix (and also
that SB doesn't keep constantly updating). make check didn't
show any additional failures.

Fixes: Fixes: b520ca7 ("Support for multiple VTEP in OVN")
Signed-off-by: venu iyer <[email protected]>
---
 controller/chassis.c | 15 ++++++++++----
 tests/ovn.at         | 48 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/controller/chassis.c b/controller/chassis.c
index a365188e8..7d78366e3 100644
--- a/controller/chassis.c
+++ b/controller/chassis.c
@@ -415,21 +415,25 @@ chassis_tunnels_changed(const struct sset *encap_type_set,
                         const char *encap_csum,
                         const struct sbrec_chassis *chassis_rec)
 {
-    size_t encap_type_count = 0;
+    struct sset chassis_rec_encap_type_set =
+        SSET_INITIALIZER(&chassis_rec_encap_type_set);
 
     for (size_t i = 0; i < chassis_rec->n_encaps; i++) {
 
         if (!sset_contains(encap_type_set, chassis_rec->encaps[i]->type)) {
+            sset_destroy(&chassis_rec_encap_type_set);
             return true;
         }
-        encap_type_count++;
+        sset_add(&chassis_rec_encap_type_set, chassis_rec->encaps[i]->type);
 
         if (!sset_contains(encap_ip_set, chassis_rec->encaps[i]->ip)) {
+            sset_destroy(&chassis_rec_encap_type_set);
             return true;
         }
 
         if (strcmp(smap_get_def(&chassis_rec->encaps[i]->options, "csum", ""),
                    encap_csum)) {
+            sset_destroy(&chassis_rec_encap_type_set);
             return true;
         }
     }
@@ -438,13 +442,16 @@ chassis_tunnels_changed(const struct sset *encap_type_set,
         sset_count(encap_type_set) * sset_count(encap_ip_set);
 
     if (tunnel_count != chassis_rec->n_encaps) {
+        sset_destroy(&chassis_rec_encap_type_set);
         return true;
     }
 
-    if (sset_count(encap_type_set) != encap_type_count) {
+    if (sset_count(encap_type_set) !=
+            sset_count(&chassis_rec_encap_type_set)) {
+        sset_destroy(&chassis_rec_encap_type_set);
         return true;
     }
-
+    sset_destroy(&chassis_rec_encap_type_set);
     return false;
 }
 
diff --git a/tests/ovn.at b/tests/ovn.at
index b6c8622ba..bd5015705 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -22299,3 +22299,51 @@ ovn-sbctl --columns chassis --bare list port_binding 
sw0-p2
 
 OVN_CLEANUP([hv1])
 AT_CLEANUP
+
+#
+# When multiple encap-ips are configued, make sure the
+# ovn-controller doesn't get into a state of constantly
+# updating the SB Chassis's encap information. The test
+# configures multiple vteps and waits for a couple
+# of seconds to makes sure the SB encap info remains
+# unchanged.
+#
+#
+AT_SETUP([ovn -- multi-vtep SB Chassis encap updates])
+ovn_start
+
+net_add n1
+sim_add hv1
+as hv1
+
+ovs-vsctl add-br br-phys
+# Just set the encap type to be geneve for this test.
+ovn_attach n1 br-phys 192.168.0.1 24 geneve
+
+# Get the encap rec, should be just one - with geneve/192.168.0.1
+encap_rec=`ovn-sbctl --data=bare --no-heading --column encaps list chassis hv1`
+#echo "Encap Rec before mvtep is $encap_rec"
+
+# Set multiple IPs
+as hv1
+ovs-vsctl \
+    -- set Open_vSwitch . external-ids:ovn-encap-ip="192.168.0.1,192.168.1.1"
+
+# Check if the encap_rec changed - should have, no need to
+# compare the exact values.
+encap_rec_mvtep=`ovn-sbctl --data=bare --no-heading --column encaps list 
chassis hv1`
+#echo "Encap Rec after mvtep is $encap_rec_mvtep"
+
+AT_CHECK([test "$encap_rec" != "$encap_rec_mvtep"], [0], [])
+
+# now, wait for a couple of secs -  should be enough time, I suppose.
+sleep 2
+
+# Check if the encap_rec changed (it should not have)
+encap_rec_mvtep1=`ovn-sbctl --data=bare --no-heading --column encaps list 
chassis hv1`
+#echo "Encap Rec after wait is $encap_rec_mvtep1"
+
+AT_CHECK([test "$encap_rec_mvtep" == "$encap_rec_mvtep1"], [0], [])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
-- 
2.17.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to