From patchwork Mon Aug 26 13:15:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ales Musil X-Patchwork-Id: 1976837 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=B5PdGZB8; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (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 4Wsrkz4xZYz1yXd for ; Mon, 26 Aug 2024 23:15:23 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id B6A15606B1; Mon, 26 Aug 2024 13:15:21 +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 PKL5qA7PIZ-E; Mon, 26 Aug 2024 13:15:20 +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 smtp3.osuosl.org 68B6E60670 Authentication-Results: smtp3.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=B5PdGZB8 Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 68B6E60670; Mon, 26 Aug 2024 13:15:20 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 518DBC07E7; Mon, 26 Aug 2024 13:15:20 +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 F1BBFC07E6 for ; Mon, 26 Aug 2024 13:15:18 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id E0FC760670 for ; Mon, 26 Aug 2024 13:15:18 +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 rFS4whrE5vQe for ; Mon, 26 Aug 2024 13:15:18 +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 D6E80606B1 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 D6E80606B1 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 D6E80606B1 for ; Mon, 26 Aug 2024 13:15:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1724678115; 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=r9l3SAbdhmWdZA1c+eWjgbIZ+JmtI13FG7TbwRLuHU0=; b=B5PdGZB8Mxvq+9EGhdAME7ZNQ5WhLKebayXi/JRCSE8l0cYxcFrFM0e0YxrqPk/DbDPUjR YlZQ5rqM2k0M7EzNw6BN1HfKxVg7jPZYyCV5ljgQV+JNc8T6rP1Gw97gfJ5lqG7HhfylR1 AMv7915Fze2d0MmNdltsVexntgyWd3g= Received: from mx-prod-mc-02.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-107-O4h_uzj_NRGdQcGKO12AVA-1; Mon, 26 Aug 2024 09:15:14 -0400 X-MC-Unique: O4h_uzj_NRGdQcGKO12AVA-1 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (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-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6919D19540F0; Mon, 26 Aug 2024 13:15:13 +0000 (UTC) Received: from amusil.redhat.com (unknown [10.45.225.68]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7443919560AA; Mon, 26 Aug 2024 13:15:11 +0000 (UTC) From: Ales Musil To: dev@openvswitch.org Date: Mon, 26 Aug 2024 15:15:09 +0200 Message-ID: <20240826131509.202811-1-amusil@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH ovn] 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 --- controller/ovn-controller.c | 17 +--------- controller/physical.c | 49 ++++++++++++--------------- controller/physical.h | 3 ++ tests/ovn.at | 67 +++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 43 deletions(-) diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 854d80bdf..baced288e 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -4456,22 +4456,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)) { - destroy_physical_ctx(&p_ctx); - 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 9e04ad5f2..36a146a58 100644 --- a/controller/physical.c +++ b/controller/physical.c @@ -2397,33 +2397,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) { @@ -2440,6 +2416,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 dd4be7041..f0aecc852 100644 --- a/controller/physical.h +++ b/controller/physical.h @@ -81,4 +81,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 50c9f04da..fc3b32494 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -38924,3 +38924,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=OFTABLE_OUTPUT_LARGE_PKT_DETECT | 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=OFTABLE_OUTPUT_LARGE_PKT_DETECT | 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=OFTABLE_OUTPUT_LARGE_PKT_DETECT | 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=OFTABLE_OUTPUT_LARGE_PKT_DETECT | 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=OFTABLE_OUTPUT_LARGE_PKT_DETECT | 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=OFTABLE_OUTPUT_LARGE_PKT_DETECT | 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=OFTABLE_OUTPUT_LARGE_PKT_DETECT | grep -c check_pkt_larger) -eq 0]) + +OVN_CLEANUP([hv1],[hv2]) + +AT_CLEANUP +])