The pflow_output SB_port_binding handler triggers a full
recompute when the type column is updated on a port binding.
However, for newly created port bindings, the OVSDB IDL
marks all non-default columns as "updated", even though no
actual update occurred. This caused every new port binding
with a non-default type (e.g., remote, patch, localnet,
router) to unnecessarily trigger a full pflow_output
recompute, severely impacting ovn-controller performance
at scale.
This is particularly problematic in deployments that use
remote LSPs, such as ovn-kubernetes with L2 UDNs, where
frequent creation of remote port bindings leads to
continuous full recomputes and high CPU usage.
Guard the type-update check with sbrec_port_binding_is_new()
and sbrec_port_binding_is_deleted() so that only genuine
type changes on existing port bindings trigger a recompute.
This matches the pattern already used in binding.c for the
tunnel_key column.
Also fix a typo in the test name ("path" -> "patch").
Fixes: 73a10345a29c ("controller: Update physical flows for peer port when the
patch port is removed.")
Reported-at: https://redhat.atlassian.net/browse/FDP-3819
Reported-by: Patryk Diak <[email protected]>
Assisted-by: Claude Opus 4.6, Claude Code
Signed-off-by: Dumitru Ceara <[email protected]>
---
controller/ovn-controller.c | 6 ++++--
tests/ovn-controller.at | 14 +++++++++++++-
tests/ovn-performance.at | 7 +++++++
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 3024399f36..b26ccfbd96 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -5081,12 +5081,14 @@ pflow_output_sb_port_binding_handler(struct engine_node
*node,
*/
const struct sbrec_port_binding *pb;
SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (pb, p_ctx.port_binding_table) {
+ bool removed = sbrec_port_binding_is_deleted(pb);
+
/* Trigger a full recompute if type column is updated. */
- if (sbrec_port_binding_is_updated(pb, SBREC_PORT_BINDING_COL_TYPE)) {
+ if (!removed && !sbrec_port_binding_is_new(pb) &&
+ sbrec_port_binding_is_updated(pb, SBREC_PORT_BINDING_COL_TYPE)) {
destroy_physical_ctx(&p_ctx);
return EN_UNHANDLED;
}
- bool removed = sbrec_port_binding_is_deleted(pb);
if (!physical_handle_flows_for_lport(pb, removed, &p_ctx,
&pfo->flow_table)) {
destroy_physical_ctx(&p_ctx);
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index b1814dfb74..f9f64d691c 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -962,7 +962,7 @@ AT_CLEANUP
])
OVN_FOR_EACH_NORTHD([
-AT_SETUP([ovn-controller - ovn IP check path ports])
+AT_SETUP([ovn-controller - ovn IP check patch ports])
AT_KEYWORDS([ovn-ip-patch-ports])
ovn_start
@@ -1003,6 +1003,18 @@ check as hv1 ovn-appctl -t ovn-controller
inc-engine/clear-stats
check ovn-nbctl --wait=hv lsp-set-type ls0-rp localnet
check_controller_engine_stats hv1 pflow_output recompute nocompute
+# Check that adding a new port with a non-default type does not trigger
+# a pflow_output recompute.
+check as hv1 ovn-appctl -t ovn-controller inc-engine/clear-stats
+check ovn-nbctl --wait=hv lsp-add ls0 lsp-remote -- lsp-set-type lsp-remote
remote
+check_controller_engine_stats hv1 pflow_output norecompute compute
+
+# Check that deleting a port with a non-default type does not trigger
+# a pflow_output recompute.
+check as hv1 ovn-appctl -t ovn-controller inc-engine/clear-stats
+check ovn-nbctl --wait=hv lsp-del lsp-remote
+check_controller_engine_stats hv1 pflow_output norecompute compute
+
OVN_CLEANUP([hv1])
AT_CLEANUP
])
diff --git a/tests/ovn-performance.at b/tests/ovn-performance.at
index 2bccbb06dd..114917832b 100644
--- a/tests/ovn-performance.at
+++ b/tests/ovn-performance.at
@@ -386,6 +386,13 @@ for i in 1 2; do
done
done
+# Check that adding a new port with a non-default type does not trigger
+# a physical_run.
+OVN_CONTROLLER_EXPECT_NO_HIT(
+ [hv1 hv2], [physical_run],
+ [ovn-nbctl --wait=hv lsp-add ls1 lsp-remote -- lsp-set-type lsp-remote
remote]
+)
+
for i in 1 2; do
j=$((i%2 + 1))
as=as$i
--
2.54.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev