From patchwork Fri Aug 21 00:04:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1441560 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dh7Hz0Gt6z9sVF for ; Thu, 18 Feb 2021 19:32:47 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 5787E60601 for ; Thu, 18 Feb 2021 08:32:45 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aChEsNEYOfqF for ; Thu, 18 Feb 2021 08:32:43 +0000 (UTC) Received: by smtp3.osuosl.org (Postfix, from userid 1001) id B013160603; Thu, 18 Feb 2021 08:32:43 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTP id 0153C605DB; Thu, 18 Feb 2021 08:32:34 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id C25F4C000E; Thu, 18 Feb 2021 08:32:34 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 378ACC000D for ; Thu, 18 Feb 2021 08:32:34 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 25B96866B9 for ; Thu, 18 Feb 2021 08:32:34 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WwI--g-3jhs7 for ; Thu, 18 Feb 2021 08:32:33 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from ti0189a330-0925.bb.online.no (ti0189a330-0925.bb.online.no [88.88.218.161]) by whitealder.osuosl.org (Postfix) with ESMTP id C85C4866CA for ; Thu, 18 Feb 2021 08:32:01 +0000 (UTC) X-Mailbox-Line: From a181bfadcee39e7dde6bb0c9fa403e854e338ad7 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Han Zhou To: dev@openvswitch.org Date: Thu, 20 Aug 2020 17:04:04 -0700 Subject: [ovs-dev] [PATCH ovn branch-20.06 05/15] ofctrl.c: Merge opposite changes of tracked flows before installing. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This patch optimizes the previous patch that incrementally processes flow installation by merging the "add-after-delete" flow changes as much as possible to avoid unnecessary OpenFlow updates. Acked-by: Mark Michelson Signed-off-by: Han Zhou (cherry picked from commit f4e508dd7a6cfbfc2e3250a8c11a8d0fdc1dfdd0) Signed-off-by: Frode Nordahl --- controller/ofctrl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/controller/ofctrl.c b/controller/ofctrl.c index b0670bf44..2d0e15978 100644 --- a/controller/ofctrl.c +++ b/controller/ofctrl.c @@ -1693,10 +1693,84 @@ update_installed_flows_by_compare(struct ovn_desired_flow_table *flow_table, } } +/* Finds and returns a desired_flow in 'deleted_flows' that is exactly the + * same as 'target', including cookie and actions. + */ +static struct desired_flow * +deleted_flow_lookup(struct hmap *deleted_flows, struct ovn_flow *target) +{ + struct desired_flow *d; + HMAP_FOR_EACH_WITH_HASH (d, match_hmap_node, target->hash, + deleted_flows) { + struct ovn_flow *f = &d->flow; + if (f->table_id == target->table_id + && f->priority == target->priority + && minimatch_equal(&f->match, &target->match) + && f->cookie == target->cookie + && ofpacts_equal(f->ofpacts, f->ofpacts_len, target->ofpacts, + target->ofpacts_len)) { + return d; + } + } + return NULL; +} + +/* This function scans the tracked flow changes in the order and merges "add" + * or "update" after "deleted" operations for exactly same flow (priority, + * table, match, action and cookie), to avoid unnecessary OF messages being + * sent to OVS. */ +static void +merge_tracked_flows(struct ovn_desired_flow_table *flow_table) +{ + struct hmap deleted_flows = HMAP_INITIALIZER(&deleted_flows); + struct desired_flow *f, *next; + LIST_FOR_EACH_SAFE (f, next, track_list_node, + &flow_table->tracked_flows) { + if (f->is_deleted) { + /* reuse f->match_hmap_node field since it is already removed from + * the desired flow table's match index. */ + hmap_insert(&deleted_flows, &f->match_hmap_node, + f->flow.hash); + } else { + struct desired_flow *del_f = deleted_flow_lookup(&deleted_flows, + &f->flow); + if (!del_f) { + continue; + } + + /* del_f must have been installed, otherwise it should have been + * removed during track_flow_add_or_modify. */ + ovs_assert(del_f->installed_flow); + if (!f->installed_flow) { + /* f is not installed yet. */ + struct installed_flow *i = del_f->installed_flow; + unlink_installed_to_desired(i, del_f); + link_installed_to_desired(i, f); + } else { + /* f has been installed before, and now was updated to exact + * the same flow as del_f. */ + ovs_assert(f->installed_flow == del_f->installed_flow); + unlink_installed_to_desired(del_f->installed_flow, del_f); + } + hmap_remove(&deleted_flows, &del_f->match_hmap_node); + ovs_list_remove(&del_f->track_list_node); + desired_flow_destroy(del_f); + + ovs_list_remove(&f->track_list_node); + ovs_list_init(&f->track_list_node); + } + } + HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, &deleted_flows) { + hmap_remove(&deleted_flows, &f->match_hmap_node); + } + hmap_destroy(&deleted_flows); +} + static void update_installed_flows_by_track(struct ovn_desired_flow_table *flow_table, struct ovs_list *msgs) { + merge_tracked_flows(flow_table); struct desired_flow *f, *f_next; LIST_FOR_EACH_SAFE (f, f_next, track_list_node, &flow_table->tracked_flows) {