From patchwork Thu Feb 18 11:46:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liran Schour X-Patchwork-Id: 584659 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (unknown [IPv6:2600:3c00::f03c:91ff:fe6e:bdf7]) by ozlabs.org (Postfix) with ESMTP id 927361402C0 for ; Thu, 18 Feb 2016 22:47:20 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id C44C510918; Thu, 18 Feb 2016 03:47:18 -0800 (PST) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id AC05B10916 for ; Thu, 18 Feb 2016 03:47:17 -0800 (PST) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id D1EED42039B for ; Thu, 18 Feb 2016 04:47:16 -0700 (MST) X-ASG-Debug-ID: 1455796035-09eadd7d15346bb0001-byXFYA Received: from mx1-pf1.cudamail.com ([192.168.24.1]) by bar5.cudamail.com with ESMTP id nt5GSw6F4b2uTu6f (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 18 Feb 2016 04:47:15 -0700 (MST) X-Barracuda-Envelope-From: lirans@il.ibm.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.1 Received: from unknown (HELO e06smtp16.uk.ibm.com) (195.75.94.112) by mx1-pf1.cudamail.com with ESMTPS (AES256-SHA encrypted); 18 Feb 2016 11:47:14 -0000 Received-SPF: pass (mx1-pf1.cudamail.com: SPF record at il.ibm.com designates 195.75.94.112 as permitted sender) X-Barracuda-Apparent-Source-IP: 195.75.94.112 X-Barracuda-RBL-IP: 195.75.94.112 Received: from localhost by e06smtp16.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 18 Feb 2016 11:47:12 -0000 Received: from d06dlp01.portsmouth.uk.ibm.com (9.149.20.13) by e06smtp16.uk.ibm.com (192.168.101.146) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 18 Feb 2016 11:47:11 -0000 X-IBM-Helo: d06dlp01.portsmouth.uk.ibm.com X-IBM-MailFrom: lirans@il.ibm.com X-IBM-RcptTo: dev@openvswitch.org Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id C262617D805F for ; Thu, 18 Feb 2016 11:47:29 +0000 (GMT) Received: from d06av10.portsmouth.uk.ibm.com (d06av10.portsmouth.uk.ibm.com [9.149.37.251]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u1IBlBju6226404 for ; Thu, 18 Feb 2016 11:47:11 GMT Received: from d06av10.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u1IAlC6h024011 for ; Thu, 18 Feb 2016 03:47:12 -0700 Received: from moren.haifa.ibm.com (moren.haifa.ibm.com [9.148.32.214]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u1IAlCe4024002; Thu, 18 Feb 2016 03:47:12 -0700 Received: from ovn-dev.haifa.ibm.com (lirans-tp.haifa.ibm.com [9.148.8.160]) by moren.haifa.ibm.com (Postfix) with ESMTP id 8C075380399; Thu, 18 Feb 2016 13:47:21 +0200 (IST) X-CudaMail-Envelope-Sender: lirans@il.ibm.com From: Liran Schour To: dev@openvswitch.org X-CudaMail-MID: CM-E1-217006876 X-CudaMail-DTE: 021816 X-CudaMail-Originating-IP: 195.75.94.112 Date: Thu, 18 Feb 2016 11:46:43 +0000 X-ASG-Orig-Subj: [##CM-E1-217006876##][PATCH monitor_cond V4 05/17] ovsdb: enable JSON cache for none conditional monitored tables Message-Id: <1455796015-14898-6-git-send-email-lirans@il.ibm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455796015-14898-1-git-send-email-lirans@il.ibm.com> References: <1455796015-14898-1-git-send-email-lirans@il.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16021811-0025-0000-0000-00000907649B X-GBUdb-Analysis: 0, 195.75.94.112, Ugly c=0 p=0 Source New X-MessageSniffer-Rules: 0-0-0-23320-c X-Barracuda-Connect: UNKNOWN[192.168.24.1] X-Barracuda-Start-Time: 1455796035 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.10 X-Barracuda-Spam-Status: No, SCORE=1.10 using per-user scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_SC1_TG070, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.27130 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC1_TG070 Custom Rule TG070 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Cc: blp@nicira.com Subject: [ovs-dev] [PATCH monitor_cond V4 05/17] ovsdb: enable JSON cache for none conditional monitored tables X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" This patch enables JSON cache of none conditional monitored tables to reduce computation on sessions with mixed tables (true and none true conditions). Signed-off-by: Liran Schour --- ovsdb/monitor.c | 130 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 52 deletions(-) diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index f4ccad8..75331a2 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -38,6 +38,7 @@ #include "monitor.h" #include "openvswitch/vlog.h" +VLOG_DEFINE_THIS_MODULE(ovsdb_monitor); static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class; static struct hmap ovsdb_monitors = HMAP_INITIALIZER(&ovsdb_monitors); @@ -50,10 +51,16 @@ struct ovsdb_monitor_session_condition { * "struct ovsdb_monitor_table_condition *"s. */ }; +enum monitor_table_condition_mode { + MTC_MODE_TRUE, /* monitor all rows in table */ + MTC_MODE_FULL, /* full conditional monitoring */ +}; + /* Monitored table session's conditions */ struct ovsdb_monitor_table_condition { const struct ovsdb_table *table; struct ovsdb_monitor_table *mt; + enum monitor_table_condition_mode cond_mode; struct ovsdb_condition old_condition; struct ovsdb_condition new_condition; }; @@ -142,6 +149,8 @@ struct ovsdb_monitor_table { * ovsdb_monitor_row. It is used for condition evaluation */ unsigned int *columns_index_map; + /* Contains "ovsdb_monitor_json_cache_node"s.*/ + struct hmap json_cache; /* Contains 'ovsdb_monitor_changes' indexed by 'transaction'. */ struct hmap changes; }; @@ -175,14 +184,14 @@ json_cache_hash(enum ovsdb_monitor_version version, uint64_t from_txn) } static struct ovsdb_monitor_json_cache_node * -ovsdb_monitor_json_cache_search(const struct ovsdb_monitor *dbmon, +ovsdb_monitor_json_cache_search(const struct hmap *json_cache, enum ovsdb_monitor_version version, uint64_t from_txn) { struct ovsdb_monitor_json_cache_node *node; uint32_t hash = json_cache_hash(version, from_txn); - HMAP_FOR_EACH_WITH_HASH(node, hmap_node, hash, &dbmon->json_cache) { + HMAP_FOR_EACH_WITH_HASH(node, hmap_node, hash, json_cache) { if (node->from_txn == from_txn && node->version == version) { return node; } @@ -192,7 +201,7 @@ ovsdb_monitor_json_cache_search(const struct ovsdb_monitor *dbmon, } static void -ovsdb_monitor_json_cache_insert(struct ovsdb_monitor *dbmon, +ovsdb_monitor_json_cache_insert(struct hmap *json_cache, enum ovsdb_monitor_version version, uint64_t from_txn, struct json *json) { @@ -205,16 +214,16 @@ ovsdb_monitor_json_cache_insert(struct ovsdb_monitor *dbmon, node->from_txn = from_txn; node->json = json ? json_clone(json) : NULL; - hmap_insert(&dbmon->json_cache, &node->hmap_node, hash); + hmap_insert(json_cache, &node->hmap_node, hash); } static void -ovsdb_monitor_json_cache_flush(struct ovsdb_monitor *dbmon) +ovsdb_monitor_json_cache_flush(struct hmap *json_cache) { struct ovsdb_monitor_json_cache_node *node, *next; - HMAP_FOR_EACH_SAFE(node, next, hmap_node, &dbmon->json_cache) { - hmap_remove(&dbmon->json_cache, &node->hmap_node); + HMAP_FOR_EACH_SAFE(node, next, hmap_node, json_cache) { + hmap_remove(json_cache, &node->hmap_node); json_destroy(node->json); free(node); } @@ -395,6 +404,7 @@ ovsdb_monitor_add_table(struct ovsdb_monitor *m, mt->dbmon = m; shash_add(&m->tables, table->schema->name, mt); hmap_init(&mt->changes); + hmap_init(&mt->json_cache); mt->columns_index_map = xmalloc(sizeof(unsigned int) * shash_count(&table->schema->columns)); for (i = 0; i < shash_count(&table->schema->columns); i++) { @@ -669,6 +679,8 @@ ovsdb_monitor_table_condition_set( if (ovsdb_condition_is_true(&mtc->old_condition)) { condition->n_true_cnd++; ovsdb_monitor_session_condition_set_mode(condition); + } else { + mtc->cond_mode = MTC_MODE_FULL; } return NULL; @@ -938,46 +950,66 @@ ovsdb_monitor_compose_update( struct ovsdb_monitor *dbmon, bool initial, uint64_t transaction, const struct ovsdb_monitor_session_condition *condition, - compose_row_update_cb_func row_update) + enum ovsdb_monitor_version version) { struct shash_node *node; struct json *json; size_t max_columns = ovsdb_monitor_max_columns(dbmon); unsigned long int *changed = xmalloc(bitmap_n_bytes(max_columns)); + compose_row_update_cb_func row_update = version == OVSDB_MONITOR_V1 ? + ovsdb_monitor_compose_row_update : ovsdb_monitor_compose_row_update2; json = NULL; SHASH_FOR_EACH (node, &dbmon->tables) { struct ovsdb_monitor_table *mt = node->data; + struct ovsdb_monitor_table_condition *mtc = condition ? + shash_find_data(&condition->tables, node->name) : NULL; + struct ovsdb_monitor_json_cache_node *cache_node = NULL; struct ovsdb_monitor_row *row, *next; struct ovsdb_monitor_changes *changes; struct json *table_json = NULL; - changes = ovsdb_monitor_table_find_changes(mt, transaction); - if (!changes) { - continue; + if (!mtc || !mtc->cond_mode) { + cache_node = ovsdb_monitor_json_cache_search(&mt->json_cache, version, transaction); } - - HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) { - struct json *row_json; - - row_json = (*row_update)(mt, condition, row, initial, changed); - if (row_json) { - char uuid[UUID_LEN + 1]; - - /* Create JSON object for transaction overall. */ + if (cache_node) { + table_json = cache_node->json ? json_clone(cache_node->json) : NULL; + if (table_json) { if (!json) { json = json_object_create(); } + json_object_put(json, mt->table->schema->name, table_json); + } + } else { + changes = ovsdb_monitor_table_find_changes(mt, transaction); + if (!changes) { + continue; + } - /* Create JSON object for transaction on this table. */ - if (!table_json) { - table_json = json_object_create(); - json_object_put(json, mt->table->schema->name, table_json); + HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) { + struct json *row_json; + + row_json = (*row_update)(mt, condition, row, initial, changed); + if (row_json) { + char uuid[UUID_LEN + 1]; + + /* Create JSON object for transaction overall. */ + if (!json) { + json = json_object_create(); + } + /* Create JSON object for transaction on this table. */ + if (!table_json) { + table_json = json_object_create(); + json_object_put(json, mt->table->schema->name, table_json); + } + + /* Add JSON row to JSON table. */ + snprintf(uuid, sizeof uuid, UUID_FMT, UUID_ARGS(&row->uuid)); + json_object_put(table_json, uuid, row_json); } - - /* Add JSON row to JSON table. */ - snprintf(uuid, sizeof uuid, UUID_FMT, UUID_ARGS(&row->uuid)); - json_object_put(table_json, uuid, row_json); + } + if (!mtc || !mtc->cond_mode) { + ovsdb_monitor_json_cache_insert(&mt->json_cache, version, transaction, table_json); } } } @@ -1009,25 +1041,17 @@ ovsdb_monitor_get_update( /* Return a clone of cached json if one exists. Otherwise, * generate a new one and add it to the cache. */ if (!condition || !condition->conditional) { - cache_node = ovsdb_monitor_json_cache_search(dbmon, version, prev_txn); + cache_node = ovsdb_monitor_json_cache_search(&dbmon->json_cache, version, prev_txn); } if (cache_node) { json = cache_node->json ? json_clone(cache_node->json) : NULL; } else { - if (version == OVSDB_MONITOR_V1) { - json = - ovsdb_monitor_compose_update(dbmon, initial, prev_txn, - condition, - ovsdb_monitor_compose_row_update); - } else { - ovs_assert(version == OVSDB_MONITOR_V2); - json = - ovsdb_monitor_compose_update(dbmon, initial, prev_txn, + json = ovsdb_monitor_compose_update(dbmon, initial, prev_txn, condition, - ovsdb_monitor_compose_row_update2); - } + version); + if (!condition || !condition->conditional) { - ovsdb_monitor_json_cache_insert(dbmon, version, prev_txn, json); + ovsdb_monitor_json_cache_insert(&dbmon->json_cache, version, prev_txn, json); } } @@ -1198,19 +1222,21 @@ ovsdb_monitor_change_cb(const struct ovsdb_row *old, } mt = aux->mt; - HMAP_FOR_EACH(changes, hmap_node, &mt->changes) { - enum ovsdb_monitor_changes_efficacy efficacy; - enum ovsdb_monitor_selection type; + enum ovsdb_monitor_selection type = + ovsdb_monitor_row_update_type(false, old, new); + enum ovsdb_monitor_changes_efficacy efficacy = + ovsdb_monitor_changes_classify(type, mt, changed); - type = ovsdb_monitor_row_update_type(false, old, new); - efficacy = ovsdb_monitor_changes_classify(type, mt, changed); + if (efficacy == OVSDB_CHANGES_REQUIRE_EXTERNAL_UPDATE) { + ovsdb_monitor_json_cache_flush(&mt->json_cache); + } + HMAP_FOR_EACH(changes, hmap_node, &mt->changes) { if (efficacy > OVSDB_CHANGES_NO_EFFECT) { ovsdb_monitor_changes_update(old, new, mt, changes); } - - if (aux->efficacy < efficacy) { - aux->efficacy = efficacy; - } + } + if (aux->efficacy < efficacy) { + aux->efficacy = efficacy; } return true; @@ -1381,7 +1407,7 @@ ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon) hmap_remove(&ovsdb_monitors, &dbmon->hmap_node); } - ovsdb_monitor_json_cache_flush(dbmon); + ovsdb_monitor_json_cache_flush(&dbmon->json_cache); hmap_destroy(&dbmon->json_cache); SHASH_FOR_EACH (node, &dbmon->tables) { @@ -1413,7 +1439,7 @@ ovsdb_monitor_commit(struct ovsdb_replica *replica, ovsdb_txn_for_each_change(txn, ovsdb_monitor_change_cb, &aux); if (aux.efficacy == OVSDB_CHANGES_REQUIRE_EXTERNAL_UPDATE) { - ovsdb_monitor_json_cache_flush(m); + ovsdb_monitor_json_cache_flush(&m->json_cache); m->n_transactions++; }