From patchwork Mon Dec 18 02:02:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1877174 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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 4StjlY3S8Mz23yc for ; Mon, 18 Dec 2023 13:03:05 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 7614B81EC4; Mon, 18 Dec 2023 02:03:03 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 7614B81EC4 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vxwPiZxdJ-cq; Mon, 18 Dec 2023 02:03:02 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 9827181EB8; Mon, 18 Dec 2023 02:03:01 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 9827181EB8 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 632CAC0077; Mon, 18 Dec 2023 02:03:01 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 806CEC0077 for ; Mon, 18 Dec 2023 02:02:59 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 4595381EAE for ; Mon, 18 Dec 2023 02:02:59 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 4595381EAE X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xB8HSWATo8WC for ; Mon, 18 Dec 2023 02:02:58 +0000 (UTC) Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::226]) by smtp1.osuosl.org (Postfix) with ESMTPS id 2C26181EAB for ; Mon, 18 Dec 2023 02:02:57 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 2C26181EAB Received: by mail.gandi.net (Postfix) with ESMTPSA id 4F261C0002; Mon, 18 Dec 2023 02:02:55 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Mon, 18 Dec 2023 03:02:40 +0100 Message-ID: <20231218020249.3447973-2-i.maximets@ovn.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218020249.3447973-1-i.maximets@ovn.org> References: <20231218020249.3447973-1-i.maximets@ovn.org> MIME-Version: 1.0 X-GND-Sasl: i.maximets@ovn.org Cc: Ilya Maximets , Dumitru Ceara Subject: [ovs-dev] [PATCH 1/5] ovsdb: Fix incorrect sharing of UUID and _version columns. 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Datum of UUID and _version columns is accessed directly via ovsdb_row_get_uuid_rw() and ovsdb_row_get_version_rw() functions instead of ovsdb_data_* functions. Meaning, the data will be directly modified even if it is shared between rows. Fix that by unsharing the data whenever RW pointer is taken. The issue was mostly hidden because weak reference assessment code always called ovsdb_datum_subtract() even if not needed. This way all the new transaction rows were always implicitly unshared. Also making ovsdb_datum_subtract() call conditional, so the issue can be hit by existing unit tests. Fixes: 485ac63d10f8 ("ovsdb: Add lazy-copy support for ovsdb_datum objects.") Signed-off-by: Ilya Maximets Acked-by: Mike Pattrick --- ovsdb/row.h | 2 ++ ovsdb/transaction.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ovsdb/row.h b/ovsdb/row.h index 59f498a20..6f5e58acb 100644 --- a/ovsdb/row.h +++ b/ovsdb/row.h @@ -130,6 +130,7 @@ ovsdb_row_get_uuid(const struct ovsdb_row *row) static inline struct uuid * ovsdb_row_get_uuid_rw(struct ovsdb_row *row) { + ovsdb_datum_unshare(&row->fields[OVSDB_COL_UUID], &ovsdb_type_uuid); return &row->fields[OVSDB_COL_UUID].keys[0].uuid; } @@ -142,6 +143,7 @@ ovsdb_row_get_version(const struct ovsdb_row *row) static inline struct uuid * ovsdb_row_get_version_rw(struct ovsdb_row *row) { + ovsdb_datum_unshare(&row->fields[OVSDB_COL_VERSION], &ovsdb_type_uuid); return &row->fields[OVSDB_COL_VERSION].keys[0].uuid; } diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index 4fdc5bcea..f43533a8c 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -733,8 +733,10 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row) ovsdb_datum_sort_unique(&deleted_refs, &column->type); /* Removing elements that references deleted rows. */ - ovsdb_datum_subtract(datum, &column->type, - &deleted_refs, &column->type); + if (deleted_refs.n) { + ovsdb_datum_subtract(datum, &column->type, + &deleted_refs, &column->type); + } ovsdb_datum_destroy(&deleted_refs, &column->type); /* Generating the difference between old and new data. */ From patchwork Mon Dec 18 02:02:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1877175 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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 4Stjlc5HPQz23yc for ; Mon, 18 Dec 2023 13:03:08 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id BCE6181F1A; Mon, 18 Dec 2023 02:03:06 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org BCE6181F1A X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6ol-HcDVK7SS; Mon, 18 Dec 2023 02:03:05 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id B02DC81ECF; Mon, 18 Dec 2023 02:03:04 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org B02DC81ECF Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6BFCAC0DD7; Mon, 18 Dec 2023 02:03:04 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id AA8DEC0077 for ; Mon, 18 Dec 2023 02:03:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 8118881EC1 for ; Mon, 18 Dec 2023 02:03:02 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 8118881EC1 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UuUqgTXpxMXv for ; Mon, 18 Dec 2023 02:03:01 +0000 (UTC) Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by smtp1.osuosl.org (Postfix) with ESMTPS id 7270C81EB2 for ; Mon, 18 Dec 2023 02:03:01 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 7270C81EB2 Received: by mail.gandi.net (Postfix) with ESMTPSA id 45D8CC0002; Mon, 18 Dec 2023 02:02:59 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Mon, 18 Dec 2023 03:02:41 +0100 Message-ID: <20231218020249.3447973-3-i.maximets@ovn.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218020249.3447973-1-i.maximets@ovn.org> References: <20231218020249.3447973-1-i.maximets@ovn.org> MIME-Version: 1.0 X-GND-Sasl: i.maximets@ovn.org Cc: Ilya Maximets , Dumitru Ceara Subject: [ovs-dev] [PATCH 2/5] ovsdb: transaction: Avoid diffs for different type references. 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" While counting strong references current code first generates a difference between old and new datums and only after it checks the types of the atoms to be strong references. Similar thing happens while assessing weak references. First the added/removed are generated and then we check for atoms to be weak references. Check the type first to avoid unnecessary work. This change doubles the performance of transactions that modify large sets of references. For example, with this change applied, initial read of OVSDB file containing 136K transactions of large OVN port groups and address sets on my laptop takes 24 seconds vs 43 seconds without. Fixes: 4dbff9f0a685 ("ovsdb: transaction: Incremental reassessment of weak refs.") Fixes: b2712d026eae ("ovsdb: transaction: Use diffs for strong reference counting.") Signed-off-by: Ilya Maximets Acked-by: Mike Pattrick --- lib/ovsdb-types.h | 12 ++++++++++++ ovsdb/transaction.c | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/ovsdb-types.h b/lib/ovsdb-types.h index 9777efea3..688fe5633 100644 --- a/lib/ovsdb-types.h +++ b/lib/ovsdb-types.h @@ -238,6 +238,18 @@ static inline bool ovsdb_type_is_map(const struct ovsdb_type *type) return type->value.type != OVSDB_TYPE_VOID; } +static inline bool ovsdb_type_has_strong_refs(const struct ovsdb_type *type) +{ + return ovsdb_base_type_is_strong_ref(&type->key) + || ovsdb_base_type_is_strong_ref(&type->value); +} + +static inline bool ovsdb_type_has_weak_refs(const struct ovsdb_type *type) +{ + return ovsdb_base_type_is_weak_ref(&type->key) + || ovsdb_base_type_is_weak_ref(&type->value); +} + #ifdef __cplusplus } #endif diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index f43533a8c..bbe4cddc1 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -322,7 +322,8 @@ update_row_ref_count(struct ovsdb_txn *txn, struct ovsdb_txn_row *r) const struct ovsdb_column *column = node->data; struct ovsdb_error *error; - if (bitmap_is_set(r->changed, column->index)) { + if (bitmap_is_set(r->changed, column->index) + && ovsdb_type_has_strong_refs(&column->type)) { if (r->old && !r->new) { error = ovsdb_txn_adjust_row_refs( txn, r->old, column, @@ -718,6 +719,10 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row) unsigned int orig_n; bool zero = false; + if (!ovsdb_type_has_weak_refs(&column->type)) { + continue; + } + orig_n = datum->n; /* Collecting all key-value pairs that references deleted rows. */ From patchwork Mon Dec 18 02:02:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1877176 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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 4Stjll0D3rz23yc for ; Mon, 18 Dec 2023 13:03:15 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 2BFBF81F04; Mon, 18 Dec 2023 02:03:13 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 2BFBF81F04 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DszMO1azfXD0; Mon, 18 Dec 2023 02:03:12 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id E3AA281F46; Mon, 18 Dec 2023 02:03:10 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org E3AA281F46 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B7711C0077; Mon, 18 Dec 2023 02:03:10 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 27A28C0037 for ; Mon, 18 Dec 2023 02:03:09 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 77E5C404F8 for ; Mon, 18 Dec 2023 02:03:05 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 77E5C404F8 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2diDf3qfV7L3 for ; Mon, 18 Dec 2023 02:03:04 +0000 (UTC) Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by smtp2.osuosl.org (Postfix) with ESMTPS id 6C71C404D0 for ; Mon, 18 Dec 2023 02:03:04 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 6C71C404D0 Received: by mail.gandi.net (Postfix) with ESMTPSA id 2B233C0003; Mon, 18 Dec 2023 02:03:02 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Mon, 18 Dec 2023 03:02:42 +0100 Message-ID: <20231218020249.3447973-4-i.maximets@ovn.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218020249.3447973-1-i.maximets@ovn.org> References: <20231218020249.3447973-1-i.maximets@ovn.org> MIME-Version: 1.0 X-GND-Sasl: i.maximets@ovn.org Cc: Ilya Maximets , Dumitru Ceara Subject: [ovs-dev] [PATCH 3/5] ovsdb: transaction: Don't try to diff unchanged columns. 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" While reassessing weak references the code attempts to collect added and removed atoms, even if the column didn't change. In case the column contains a large set, it may take significant amount of time to process. Add a check for the column actually being changed either by removing references to deleted rows or by direct removal. For example, rows in OVN Port_Group tables frequently have two large sets - 'ports' and 'acls'. In case a new ACL is added to the set without changing the ports, ports don't need to be reassessed. Fixes: 4dbff9f0a685 ("ovsdb: transaction: Incremental reassessment of weak refs.") Signed-off-by: Ilya Maximets Acked-by: Mike Pattrick --- ovsdb/transaction.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index bbe4cddc1..a482588a0 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -745,13 +745,17 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row) ovsdb_datum_destroy(&deleted_refs, &column->type); /* Generating the difference between old and new data. */ - if (txn_row->old) { - ovsdb_datum_added_removed(&added, &removed, - &txn_row->old->fields[column->index], - datum, &column->type); - } else { - ovsdb_datum_init_empty(&removed); - ovsdb_datum_clone(&added, datum); + ovsdb_datum_init_empty(&added); + ovsdb_datum_init_empty(&removed); + if (datum->n != orig_n + || bitmap_is_set(txn_row->changed, column->index)) { + if (txn_row->old) { + ovsdb_datum_added_removed(&added, &removed, + &txn_row->old->fields[column->index], + datum, &column->type); + } else { + ovsdb_datum_clone(&added, datum); + } } /* Checking added data and creating new references. */ From patchwork Mon Dec 18 02:02:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1877178 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (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 4Stjm46nSqz23yc for ; Mon, 18 Dec 2023 13:03:32 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 1C6B2416C2; Mon, 18 Dec 2023 02:03:31 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 1C6B2416C2 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6wWqzjzvHvO1; Mon, 18 Dec 2023 02:03:29 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id CBBAE416BE; Mon, 18 Dec 2023 02:03:28 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org CBBAE416BE Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B25F5C0077; Mon, 18 Dec 2023 02:03:28 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 18F57C0037 for ; Mon, 18 Dec 2023 02:03:27 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id C09634051C for ; Mon, 18 Dec 2023 02:03:11 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org C09634051C X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DOo6YEORsqPk for ; Mon, 18 Dec 2023 02:03:07 +0000 (UTC) Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::226]) by smtp2.osuosl.org (Postfix) with ESMTPS id B885040503 for ; Mon, 18 Dec 2023 02:03:06 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org B885040503 Received: by mail.gandi.net (Postfix) with ESMTPSA id 6F7C6C0005; Mon, 18 Dec 2023 02:03:04 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Mon, 18 Dec 2023 03:02:43 +0100 Message-ID: <20231218020249.3447973-5-i.maximets@ovn.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218020249.3447973-1-i.maximets@ovn.org> References: <20231218020249.3447973-1-i.maximets@ovn.org> MIME-Version: 1.0 X-GND-Sasl: i.maximets@ovn.org Cc: Ilya Maximets , Dumitru Ceara Subject: [ovs-dev] [PATCH 4/5] ovsdb: Preserve column diffs read from the storage. 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Database file contains the column diff, but it is discarded once the 'new' state of a row is constructed. Keep it in the transaction row, as it can be used later by other parts of the code. Diffs do not live long, we keep them around only while transaction is alive, so should not affect memory consumption. Users for this data will be added in later commits. Signed-off-by: Ilya Maximets Acked-by: Mike Pattrick --- ovsdb/execution.c | 14 ++++++++--- ovsdb/file.c | 22 +++++++++++----- ovsdb/ovsdb-server.c | 7 ++++-- ovsdb/table.c | 6 +++-- ovsdb/transaction.c | 60 +++++++++++++++++++++++++++++++++----------- ovsdb/transaction.h | 6 +++-- tests/test-ovsdb.c | 2 +- 7 files changed, 86 insertions(+), 31 deletions(-) diff --git a/ovsdb/execution.c b/ovsdb/execution.c index 5587ef96f..8c20c3b54 100644 --- a/ovsdb/execution.c +++ b/ovsdb/execution.c @@ -490,9 +490,11 @@ update_row_cb(const struct ovsdb_row *row, void *ur_) ur->n_matches++; if (!ovsdb_row_equal_columns(row, ur->row, ur->columns)) { + struct ovsdb_row *rw_row; + + ovsdb_txn_row_modify(ur->txn, row, &rw_row, NULL); ovsdb_error_assert(ovsdb_row_update_columns( - ovsdb_txn_row_modify(ur->txn, row), - ur->row, ur->columns, false)); + rw_row, ur->row, ur->columns, false)); } return true; @@ -572,10 +574,14 @@ static bool mutate_row_cb(const struct ovsdb_row *row, void *mr_) { struct mutate_row_cbdata *mr = mr_; + struct ovsdb_row *rw_row; + + /* Not trying to track the row diff here, because user transactions + * may attempt to add duplicates or remove elements that do not exist. */ + ovsdb_txn_row_modify(mr->txn, row, &rw_row, NULL); mr->n_matches++; - *mr->error = ovsdb_mutation_set_execute(ovsdb_txn_row_modify(mr->txn, row), - mr->mutations); + *mr->error = ovsdb_mutation_set_execute(rw_row, mr->mutations); return *mr->error == NULL; } diff --git a/ovsdb/file.c b/ovsdb/file.c index 8bd1d4af3..77a89fd1a 100644 --- a/ovsdb/file.c +++ b/ovsdb/file.c @@ -80,8 +80,8 @@ ovsdb_file_column_diff_disable(void) } static struct ovsdb_error * -ovsdb_file_update_row_from_json(struct ovsdb_row *row, bool converting, - bool row_contains_diff, +ovsdb_file_update_row_from_json(struct ovsdb_row *row, struct ovsdb_row *diff, + bool converting, bool row_contains_diff, const struct json *json) { struct ovsdb_table_schema *schema = row->table->schema; @@ -122,6 +122,12 @@ ovsdb_file_update_row_from_json(struct ovsdb_row *row, bool converting, error = ovsdb_datum_apply_diff_in_place( &row->fields[column->index], &datum, &column->type); + if (!error && diff) { + ovs_assert(ovsdb_datum_is_default(&diff->fields[column->index], + &column->type)); + ovsdb_datum_swap(&diff->fields[column->index], &datum); + } + ovsdb_datum_destroy(&datum, &column->type); if (error) { return error; @@ -150,16 +156,20 @@ ovsdb_file_txn_row_from_json(struct ovsdb_txn *txn, struct ovsdb_table *table, ovsdb_txn_row_delete(txn, row); return NULL; } else if (row) { - return ovsdb_file_update_row_from_json(ovsdb_txn_row_modify(txn, row), - converting, row_contains_diff, - json); + struct ovsdb_row *new, *diff = NULL; + + ovsdb_txn_row_modify(txn, row, &new, + row_contains_diff ? &diff : NULL); + return ovsdb_file_update_row_from_json(new, diff, converting, + row_contains_diff, json); } else { struct ovsdb_error *error; struct ovsdb_row *new; new = ovsdb_row_create(table); *ovsdb_row_get_uuid_rw(new) = *row_uuid; - error = ovsdb_file_update_row_from_json(new, converting, false, json); + error = ovsdb_file_update_row_from_json(new, NULL, converting, + false, json); if (error) { ovsdb_row_destroy(new); } else { diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 4d29043f4..dbf85fe3b 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -1111,7 +1111,7 @@ update_remote_row(const struct ovsdb_row *row, struct ovsdb_txn *txn, /* Bad remote spec or incorrect schema. */ return; } - rw_row = ovsdb_txn_row_modify(txn, row); + ovsdb_txn_row_modify(txn, row, &rw_row, NULL); ovsdb_jsonrpc_server_get_remote_status(jsonrpc, target, &status); /* Update status information columns. */ @@ -1301,7 +1301,10 @@ update_server_status(struct shash *all_dbs) if (!db || !db->db) { ovsdb_txn_row_delete(txn, row); } else { - update_database_status(ovsdb_txn_row_modify(txn, row), db); + struct ovsdb_row *rw_row; + + ovsdb_txn_row_modify(txn, row, &rw_row, NULL); + update_database_status(rw_row, db); } } diff --git a/ovsdb/table.c b/ovsdb/table.c index 0792e1580..3e89ddd44 100644 --- a/ovsdb/table.c +++ b/ovsdb/table.c @@ -415,8 +415,10 @@ ovsdb_table_execute_update(struct ovsdb_txn *txn, const struct uuid *row_uuid, NULL, &columns, xor); if (!error && (xor || !ovsdb_row_equal_columns(row, update, &columns))) { - error = ovsdb_row_update_columns(ovsdb_txn_row_modify(txn, row), - update, &columns, xor); + struct ovsdb_row *rw_row; + + ovsdb_txn_row_modify(txn, row, &rw_row, NULL); + error = ovsdb_row_update_columns(rw_row, update, &columns, xor); } ovsdb_column_set_destroy(&columns); diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index a482588a0..b69d03b5a 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -72,6 +72,8 @@ struct ovsdb_txn_table { * 'new'. * * - A row modified by a transaction will have non-null 'old' and 'new'. + * It may have non-null 'diff' as well in this case, but it is not + * necessary. * * - 'old' and 'new' both null indicates that a row was added then deleted * within a single transaction. Most of the time we instead delete the @@ -83,6 +85,7 @@ struct ovsdb_txn_row { struct hmap_node hmap_node; /* In ovsdb_txn_table's txn_rows hmap. */ struct ovsdb_row *old; /* The old row. */ struct ovsdb_row *new; /* The new row. */ + struct ovsdb_row *diff; /* The difference between old and new. */ size_t n_refs; /* Number of remaining references. */ /* These members are the same as the corresponding members of 'old' or @@ -155,6 +158,7 @@ ovsdb_txn_row_abort(struct ovsdb_txn *txn OVS_UNUSED, { struct ovsdb_row *old = txn_row->old; struct ovsdb_row *new = txn_row->new; + struct ovsdb_row *diff = txn_row->diff; ovsdb_txn_row_prefree(txn_row); if (!old) { @@ -184,6 +188,7 @@ ovsdb_txn_row_abort(struct ovsdb_txn *txn OVS_UNUSED, } ovsdb_row_destroy(new); + ovsdb_row_destroy(diff); free(txn_row); return NULL; @@ -250,7 +255,10 @@ find_or_make_txn_row(struct ovsdb_txn *txn, const struct ovsdb_table *table, if (!txn_row) { const struct ovsdb_row *row = ovsdb_table_get_row(table, uuid); if (row) { - txn_row = ovsdb_txn_row_modify(txn, row)->txn_row; + struct ovsdb_row *rw_row; + + ovsdb_txn_row_modify(txn, row, &rw_row, NULL); + txn_row = rw_row->txn_row; } } return txn_row; @@ -433,6 +441,7 @@ delete_garbage_row(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row) return NULL; } + ovsdb_row_destroy(txn_row->diff); row = txn_row->new; txn_row->new = NULL; hmap_remove(&txn_row->table->rows, &row->hmap_node); @@ -544,6 +553,7 @@ ovsdb_txn_row_commit(struct ovsdb_txn *txn OVS_UNUSED, txn_row->new->n_refs = txn_row->n_refs; } ovsdb_row_destroy(txn_row->old); + ovsdb_row_destroy(txn_row->diff); free(txn_row); return NULL; @@ -1178,6 +1188,7 @@ ovsdb_txn_destroy_cloned(struct ovsdb_txn *txn) if (r->new) { ovsdb_row_destroy(r->new); } + ovs_assert(!r->diff); hmap_remove(&t->txn_rows, &r->hmap_node); free(r); } @@ -1439,7 +1450,8 @@ ovsdb_txn_create_txn_table(struct ovsdb_txn *txn, struct ovsdb_table *table) static struct ovsdb_txn_row * ovsdb_txn_row_create(struct ovsdb_txn *txn, struct ovsdb_table *table, - const struct ovsdb_row *old_, struct ovsdb_row *new) + const struct ovsdb_row *old_, struct ovsdb_row *new, + struct ovsdb_row *diff) { const struct ovsdb_row *row = old_ ? old_ : new; struct ovsdb_row *old = CONST_CAST(struct ovsdb_row *, old_); @@ -1453,6 +1465,7 @@ ovsdb_txn_row_create(struct ovsdb_txn *txn, struct ovsdb_table *table, txn_row->table = row->table; txn_row->old = old; txn_row->new = new; + txn_row->diff = diff; txn_row->n_refs = old ? old->n_refs : 0; txn_row->serial = serial - 1; @@ -1465,6 +1478,9 @@ ovsdb_txn_row_create(struct ovsdb_txn *txn, struct ovsdb_table *table, if (new) { new->txn_row = txn_row; } + if (diff) { + diff->txn_row = txn_row; + } txn_table = ovsdb_txn_create_txn_table(txn, table); hmap_insert(&txn_table->txn_rows, &txn_row->hmap_node, @@ -1473,24 +1489,38 @@ ovsdb_txn_row_create(struct ovsdb_txn *txn, struct ovsdb_table *table, return txn_row; } -struct ovsdb_row * -ovsdb_txn_row_modify(struct ovsdb_txn *txn, const struct ovsdb_row *ro_row_) +void +ovsdb_txn_row_modify(struct ovsdb_txn *txn, const struct ovsdb_row *ro_row_, + struct ovsdb_row **rw_row, struct ovsdb_row **diff) { struct ovsdb_row *ro_row = CONST_CAST(struct ovsdb_row *, ro_row_); + ovs_assert(ro_row); + ovs_assert(rw_row); + if (ro_row->txn_row) { ovs_assert(ro_row == ro_row->txn_row->new); - return ro_row; + *rw_row = ro_row; + if (diff) { + *diff = ro_row->txn_row->diff; + } else { + /* Caller will modify the row without updating the diff. + * Destroy the existing diff, if any, so it will not be + * used for this row anymore. Modification will always + * return NULL from this point on. */ + ovsdb_row_destroy(ro_row->txn_row->diff); + ro_row->txn_row->diff = NULL; + } } else { struct ovsdb_table *table = ro_row->table; - struct ovsdb_row *rw_row; - rw_row = ovsdb_row_clone(ro_row); - rw_row->n_refs = ro_row->n_refs; - ovsdb_txn_row_create(txn, table, ro_row, rw_row); - hmap_replace(&table->rows, &ro_row->hmap_node, &rw_row->hmap_node); - - return rw_row; + *rw_row = ovsdb_row_clone(ro_row); + (*rw_row)->n_refs = ro_row->n_refs; + if (diff) { + *diff = ovsdb_row_create(table); + } + ovsdb_txn_row_create(txn, table, ro_row, *rw_row, diff ? *diff : NULL); + hmap_replace(&table->rows, &ro_row->hmap_node, &(*rw_row)->hmap_node); } } @@ -1502,7 +1532,7 @@ ovsdb_txn_row_insert(struct ovsdb_txn *txn, struct ovsdb_row *row) uuid_generate(ovsdb_row_get_version_rw(row)); - ovsdb_txn_row_create(txn, table, NULL, row); + ovsdb_txn_row_create(txn, table, NULL, row, NULL); hmap_insert(&table->rows, &row->hmap_node, hash); } @@ -1518,9 +1548,11 @@ ovsdb_txn_row_delete(struct ovsdb_txn *txn, const struct ovsdb_row *row_) hmap_remove(&table->rows, &row->hmap_node); if (!txn_row) { - ovsdb_txn_row_create(txn, table, row, NULL); + ovsdb_txn_row_create(txn, table, row, NULL, NULL); } else { ovs_assert(txn_row->new == row); + ovsdb_row_destroy(txn_row->diff); + txn_row->diff = NULL; if (txn_row->old) { txn_row->new = NULL; } else { diff --git a/ovsdb/transaction.h b/ovsdb/transaction.h index 0e054eef3..f659838dc 100644 --- a/ovsdb/transaction.h +++ b/ovsdb/transaction.h @@ -21,6 +21,7 @@ struct json; struct ovsdb; +struct ovsdb_row; struct ovsdb_schema; struct ovsdb_table; struct uuid; @@ -50,8 +51,9 @@ const struct ovsdb_error *ovsdb_txn_progress_get_error( const struct ovsdb_txn_progress *); void ovsdb_txn_progress_destroy(struct ovsdb_txn_progress *); -struct ovsdb_row *ovsdb_txn_row_modify(struct ovsdb_txn *, - const struct ovsdb_row *); +void ovsdb_txn_row_modify(struct ovsdb_txn *, const struct ovsdb_row *, + struct ovsdb_row **row_new, + struct ovsdb_row **row_diff); void ovsdb_txn_row_insert(struct ovsdb_txn *, struct ovsdb_row *); void ovsdb_txn_row_delete(struct ovsdb_txn *, const struct ovsdb_row *); diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index c761822e6..0394eafd2 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -1798,7 +1798,7 @@ do_transact_modify(struct ovs_cmdl_context *ctx) struct ovsdb_row *row_rw; row_ro = do_transact_find_row(ctx->argv[1]); - row_rw = ovsdb_txn_row_modify(do_transact_txn, row_ro); + ovsdb_txn_row_modify(do_transact_txn, row_ro, &row_rw, NULL); do_transact_set_i_j(row_rw, ctx->argv[2], ctx->argv[3]); } From patchwork Mon Dec 18 02:02:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1877177 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (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 4Stjly1dBwz23yc for ; Mon, 18 Dec 2023 13:03:26 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 311544167F; Mon, 18 Dec 2023 02:03:24 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 311544167F X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8fVdqH-QBkj2; Mon, 18 Dec 2023 02:03:23 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id 346AE40164; Mon, 18 Dec 2023 02:03:22 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 346AE40164 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id F2F53C0077; Mon, 18 Dec 2023 02:03:21 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0D262C0037 for ; Mon, 18 Dec 2023 02:03:21 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 4737C4051F for ; Mon, 18 Dec 2023 02:03:10 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 4737C4051F X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0h6xwmV6vsmD for ; Mon, 18 Dec 2023 02:03:09 +0000 (UTC) Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::226]) by smtp2.osuosl.org (Postfix) with ESMTPS id D467D404FC for ; Mon, 18 Dec 2023 02:03:08 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org D467D404FC Received: by mail.gandi.net (Postfix) with ESMTPSA id 475B8C0002; Mon, 18 Dec 2023 02:03:06 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Mon, 18 Dec 2023 03:02:44 +0100 Message-ID: <20231218020249.3447973-6-i.maximets@ovn.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218020249.3447973-1-i.maximets@ovn.org> References: <20231218020249.3447973-1-i.maximets@ovn.org> MIME-Version: 1.0 X-GND-Sasl: i.maximets@ovn.org Cc: Ilya Maximets , Dumitru Ceara Subject: [ovs-dev] [PATCH 5/5] ovsdb: transaction: Calculate added/removed from diff. 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" In case the difference between 'old' and 'new' rows is readily available, it can be used to construct added/removed datums instead. Diffs are typically much smaller than the column itself. This change more than doubles the performance of a transaction replay. For example, with this change applied, initial read of OVSDB file containing 136K small transactions for large OVN port groups and address sets on my laptop takes 11 seconds vs 24 seconds without. Signed-off-by: Ilya Maximets --- lib/ovsdb-data.c | 26 ++++++++++++++++++++++++++ lib/ovsdb-data.h | 1 + ovsdb/transaction.c | 15 ++++++++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/ovsdb-data.c b/lib/ovsdb-data.c index f18f74298..f0d7bee23 100644 --- a/lib/ovsdb-data.c +++ b/lib/ovsdb-data.c @@ -2238,6 +2238,8 @@ ovsdb_symbol_table_insert(struct ovsdb_symbol_table *symtab, /* APIs for Generating and apply diffs. */ /* Find what needs to be added to and removed from 'old' to construct 'new'. + * If the optional 'diff' is porvided, it can be used to speed up processing, + * in case it is smaller than the original 'old' and 'new'. * * The 'added' and 'removed' datums are always safe; the orders of keys are * maintained since they are added in order. */ @@ -2246,6 +2248,7 @@ ovsdb_datum_added_removed(struct ovsdb_datum *added, struct ovsdb_datum *removed, const struct ovsdb_datum *old, const struct ovsdb_datum *new, + const struct ovsdb_datum *diff, const struct ovsdb_type *type) { size_t oi, ni; @@ -2258,6 +2261,29 @@ ovsdb_datum_added_removed(struct ovsdb_datum *added, return; } + /* Use diff, if provided, unless it's comparable in size. */ + if (diff && diff->n * 2 < old->n + new->n) { + unsigned int idx; + + for (size_t di = 0; di < diff->n; di++) { + bool found = ovsdb_datum_find_key(old, &diff->keys[di], + type->key.type, &idx); + + if (!found) { + ovsdb_datum_add_from_index_unsafe(added, diff, di, type); + } else { + if (type->value.type != OVSDB_TYPE_VOID + && !ovsdb_atom_equals(&diff->values[di], + &old->values[idx], + type->value.type)) { + ovsdb_datum_add_from_index_unsafe(added, diff, di, type); + } + ovsdb_datum_add_from_index_unsafe(removed, old, idx, type); + } + } + return; + } + /* Generate the diff in O(n) time. */ for (oi = ni = 0; oi < old->n && ni < new->n;) { int c = ovsdb_atom_compare_3way(&old->keys[oi], &new->keys[ni], diff --git a/lib/ovsdb-data.h b/lib/ovsdb-data.h index f048a8cb0..c0408ee49 100644 --- a/lib/ovsdb-data.h +++ b/lib/ovsdb-data.h @@ -256,6 +256,7 @@ void ovsdb_datum_added_removed(struct ovsdb_datum *added, struct ovsdb_datum *removed, const struct ovsdb_datum *old, const struct ovsdb_datum *new, + const struct ovsdb_datum *diff, const struct ovsdb_type *type); void ovsdb_datum_diff(struct ovsdb_datum *diff, diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index b69d03b5a..e1a87bb74 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -347,12 +347,13 @@ update_row_ref_count(struct ovsdb_txn *txn, struct ovsdb_txn_row *r) return error; } } else if (r->old && r->new) { - struct ovsdb_datum added, removed; + struct ovsdb_datum added, removed, *diff; + diff = (r->diff) ? &r->diff->fields[column->index] : NULL; ovsdb_datum_added_removed(&added, &removed, &r->old->fields[column->index], &r->new->fields[column->index], - &column->type); + diff, &column->type); error = ovsdb_txn_adjust_row_refs( txn, r->old, column, &removed, -1); @@ -760,9 +761,13 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row) if (datum->n != orig_n || bitmap_is_set(txn_row->changed, column->index)) { if (txn_row->old) { + struct ovsdb_datum *diff; + + diff = (txn_row->diff && datum->n == orig_n) + ? &txn_row->diff->fields[column->index] : NULL; ovsdb_datum_added_removed(&added, &removed, &txn_row->old->fields[column->index], - datum, &column->type); + datum, diff, &column->type); } else { ovsdb_datum_clone(&added, datum); } @@ -790,6 +795,10 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row) if (datum->n != orig_n) { bitmap_set1(txn_row->changed, column->index); + /* Can no longer rely on the previous diff. */ + ovsdb_row_destroy(txn_row->diff); + txn_row->diff = NULL; + if (datum->n < column->type.n_min) { const struct uuid *row_uuid = ovsdb_row_get_uuid(txn_row->new); if (zero && !txn_row->old) {