From patchwork Mon Sep 23 07:37:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ales Musil X-Patchwork-Id: 1988411 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=CKXBCy7m; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XBvww4B4bz1xsN for ; Mon, 23 Sep 2024 17:38:08 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id B22D381154; Mon, 23 Sep 2024 07:38:06 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id R6qIHNuUxyK3; Mon, 23 Sep 2024 07:38:05 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 6527581132 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=CKXBCy7m Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 6527581132; Mon, 23 Sep 2024 07:38:05 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3651FC0012; Mon, 23 Sep 2024 07:38:05 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 99332C0011 for ; Mon, 23 Sep 2024 07:38:03 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 74A2E6078A for ; Mon, 23 Sep 2024 07:38:03 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id UbvG2V0znZsm for ; Mon, 23 Sep 2024 07:38:02 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amusil@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org 5B5976077D Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 5B5976077D Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=CKXBCy7m Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 5B5976077D for ; Mon, 23 Sep 2024 07:38:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1727077080; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=g3f/93Yauz7Ji5mx5kPp2/2/WtyJQAern9ZE1+6pMOA=; b=CKXBCy7mOIzC5VXvwEHdHC2/JzMwIVtEa77O9aoKxz3YOmc/ePLO7yS5Esi1YloZDwli4U QP+crb4IQT0rYzmSVrHyHD89PBMVPEvpD3Tspskx8AmeUvMXnGEBU5kpwCm7QHzdbOI3Zo mxh8vVvbvIMh6RjkJozqBkj3PSgh41Y= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-669-Tb6bnkrrOXKVCHRV9BDGqA-1; Mon, 23 Sep 2024 03:37:57 -0400 X-MC-Unique: Tb6bnkrrOXKVCHRV9BDGqA-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (unknown [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 566BC18E68C4; Mon, 23 Sep 2024 07:37:56 +0000 (UTC) Received: from amusil.brq.redhat.com (unknown [10.43.17.32]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9417219560AD; Mon, 23 Sep 2024 07:37:54 +0000 (UTC) From: Ales Musil To: dev@openvswitch.org Date: Mon, 23 Sep 2024 09:37:53 +0200 Message-ID: <20240923073753.66155-1-amusil@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH ovn branch-23.09] controller: Avoid quadratic complexity for multi-chassis ports. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ilya Maximets Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" The processing for ports had a quadratic complexity when MTU change was involved. Avoid the unnecessary processing and do the lookup loop only once and only in case it was actually needed. In addition to the quadratic complexity the condition to do the flow recompute was wrong and this resulted for the lookup in physical_handle_flows_for_lport() to run for all ports. The performance difference is very noticeable, see the number below in a test with 800 LSPs: Before: physical_flow_output, handler for input if_status_mgr took 2072ms After: physical_flow_output, handler for input if_status_mgr took 4ms Fixes: cdd8dea88b3d ("Track interface MTU in if-status-mgr") Fixes: 7084cf437421 ("Always funnel multichassis port traffic through tunnels") Co-authored-by: Ilya Maximets Signed-off-by: Ilya Maximets Signed-off-by: Ales Musil Acked-by: Mark Michelson Signed-off-by: Numan Siddique (cherry picked from commit 16836c3796f7af68437f9f834b40d87c801dc27c) --- controller/ovn-controller.c | 16 +-------- controller/physical.c | 49 ++++++++++++--------------- controller/physical.h | 3 ++ tests/ovn.at | 67 +++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 42 deletions(-) diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 66b656044..c714278b2 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -4742,21 +4742,7 @@ pflow_output_if_status_mgr_handler(struct engine_node *node, } if (pb->n_additional_chassis) { /* Update flows for all ports in datapath. */ - struct sbrec_port_binding *target = - sbrec_port_binding_index_init_row( - p_ctx.sbrec_port_binding_by_datapath); - sbrec_port_binding_index_set_datapath(target, pb->datapath); - - const struct sbrec_port_binding *binding; - SBREC_PORT_BINDING_FOR_EACH_EQUAL ( - binding, target, p_ctx.sbrec_port_binding_by_datapath) { - bool removed = sbrec_port_binding_is_deleted(binding); - if (!physical_handle_flows_for_lport(binding, removed, &p_ctx, - &pfo->flow_table)) { - return false; - } - } - sbrec_port_binding_index_destroy_row(target); + physical_multichassis_reprocess(pb, &p_ctx, &pfo->flow_table); } else { /* If any multichassis ports, update flows for the port. */ bool removed = sbrec_port_binding_is_deleted(pb); diff --git a/controller/physical.c b/controller/physical.c index c93fe9aa6..ad439c71e 100644 --- a/controller/physical.c +++ b/controller/physical.c @@ -2245,33 +2245,9 @@ physical_handle_flows_for_lport(const struct sbrec_port_binding *pb, } } - if (ldp) { - bool multichassis_state_changed = ( - !!pb->additional_chassis == - !!shash_find(&ldp->multichassis_ports, pb->logical_port) - ); - if (multichassis_state_changed) { - if (pb->additional_chassis) { - add_local_datapath_multichassis_port( - ldp, pb->logical_port, pb); - } else { - remove_local_datapath_multichassis_port( - ldp, pb->logical_port); - } - - struct sbrec_port_binding *target = - sbrec_port_binding_index_init_row( - p_ctx->sbrec_port_binding_by_datapath); - sbrec_port_binding_index_set_datapath(target, ldp->datapath); - - const struct sbrec_port_binding *port; - SBREC_PORT_BINDING_FOR_EACH_EQUAL ( - port, target, p_ctx->sbrec_port_binding_by_datapath) { - ofctrl_remove_flows(flow_table, &port->header_.uuid); - physical_eval_port_binding(p_ctx, port, flow_table); - } - sbrec_port_binding_index_destroy_row(target); - } + if (sbrec_port_binding_is_updated( + pb, SBREC_PORT_BINDING_COL_ADDITIONAL_CHASSIS) || removed) { + physical_multichassis_reprocess(pb, p_ctx, flow_table); } if (!removed) { @@ -2288,6 +2264,25 @@ physical_handle_flows_for_lport(const struct sbrec_port_binding *pb, return true; } +void +physical_multichassis_reprocess(const struct sbrec_port_binding *pb, + struct physical_ctx *p_ctx, + struct ovn_desired_flow_table *flow_table) +{ + struct sbrec_port_binding *target = + sbrec_port_binding_index_init_row( + p_ctx->sbrec_port_binding_by_datapath); + sbrec_port_binding_index_set_datapath(target, pb->datapath); + + const struct sbrec_port_binding *port; + SBREC_PORT_BINDING_FOR_EACH_EQUAL (port, target, + p_ctx->sbrec_port_binding_by_datapath) { + ofctrl_remove_flows(flow_table, &port->header_.uuid); + physical_eval_port_binding(p_ctx, port, flow_table); + } + sbrec_port_binding_index_destroy_row(target); +} + void physical_handle_mc_group_changes(struct physical_ctx *p_ctx, struct ovn_desired_flow_table *flow_table) diff --git a/controller/physical.h b/controller/physical.h index 1f1ed55ef..c81613ae2 100644 --- a/controller/physical.h +++ b/controller/physical.h @@ -78,4 +78,7 @@ bool physical_handle_flows_for_lport(const struct sbrec_port_binding *, bool removed, struct physical_ctx *, struct ovn_desired_flow_table *); +void physical_multichassis_reprocess(const struct sbrec_port_binding *, + struct physical_ctx *, + struct ovn_desired_flow_table *); #endif /* controller/physical.h */ diff --git a/tests/ovn.at b/tests/ovn.at index df4b9e22c..987975c1d 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -38063,3 +38063,70 @@ OVN_CHECK_PACKETS([hv/vif1-tx.pcap], [expected-vif1]) AT_CLEANUP ]) + + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([Multichassis port I-P processing]) +ovn_start + +net_add n1 + +sim_add hv1 +as hv1 +check ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.11 +check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys + +sim_add hv2 +as hv2 +check ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.12 +check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys + +check ovn-nbctl ls-add ls +check ovn-nbctl lsp-add ls multi +check ovn-nbctl lsp-set-options multi requested-chassis=hv1 + +check ovn-nbctl lsp-add ls ln +check ovn-nbctl lsp-set-type ln localnet +check ovn-nbctl lsp-set-addresses ln unknown +check ovn-nbctl lsp-set-options ln network_name=phys + +check ovn-nbctl lsp-add ls lsp1 \ + -- lsp-set-options lsp1 requested-chassis=hv1 +as hv1 check ovs-vsctl -- add-port br-int lsp1 \ + -- set Interface lsp1 external-ids:iface-id=lsp1 + +for hv in hv1 hv2; do + as $hv check ovs-vsctl -- add-port br-int multi \ + -- set Interface multi external-ids:iface-id=multi +done + +wait_for_ports_up +ovn-nbctl --wait=hv sync + +OVS_WAIT_UNTIL([test $(as hv2 ovs-ofctl dump-flows br-int table=37 | grep -c check_pkt_larger) -eq 0]) + +check ovn-nbctl --wait=hv lsp-set-options multi requested-chassis=hv1,hv2 +OVS_WAIT_UNTIL([test $(as hv2 ovs-ofctl dump-flows br-int table=37 | grep -c check_pkt_larger) -eq 4]) + +check ovn-nbctl --wait=hv lsp-set-options multi requested-chassis=hv1 +OVS_WAIT_UNTIL([test $(as hv2 ovs-ofctl dump-flows br-int table=37 | grep -c check_pkt_larger) -eq 0]) + +check ovn-nbctl --wait=hv lsp-set-options multi requested-chassis=hv1,hv2 +OVS_WAIT_UNTIL([test $(as hv2 ovs-ofctl dump-flows br-int table=37 | grep -c check_pkt_larger) -eq 4]) + +as hv2 check ovs-vsctl del-port multi +OVS_WAIT_UNTIL([test $(as hv2 ovs-ofctl dump-flows br-int table=37 | grep -c check_pkt_larger) -eq 0]) + +as hv2 check ovs-vsctl -- add-port br-int multi \ + -- set Interface multi external-ids:iface-id=multi +OVS_WAIT_UNTIL([test $(as hv2 ovs-ofctl dump-flows br-int table=37 | grep -c check_pkt_larger) -eq 4]) + +check ovn-nbctl --wait=hv lsp-del multi +OVS_WAIT_UNTIL([test $(as hv2 ovs-ofctl dump-flows br-int table=37 | grep -c check_pkt_larger) -eq 0]) + +OVN_CLEANUP([hv1],[hv2]) + +AT_CLEANUP +])