Add a set of user space instruction counters to help break down
where instructions are spent.

Here is an example of screen capture of adding a port to database
without any monitoring client.

~/projs/ovs/tutorial$ ovs-appctl -t
ovsdb-server ovsdb-server/perf-counters-clear
~/projs/ovs/tutorial$ ovs-vsctl add-port br0 p3
~/projs/ovs/tutorial$ ovs-appctl -t
ovsdb-server ovsdb-server/perf-counters-show
ovsdb_execute_comment       1        1069 1069.0
ovsdb_execute_insert        2       40849 20424.5
ovsdb_execute_mutate        1       12166 12166.0
ovsdb_execute_select        1        9086 9086.0
ovsdb_execute_update        4      107140 26785.0
ovsdb_execute_wait          6       86628 14438.0
ovsdb_txn_commit            2      906922 453461.0

However, with 300 monitoring clients, add a port yield:

ovsdb_execute_comment       1        1069 1069.0
ovsdb_execute_insert        2       43304 21652.0
ovsdb_execute_mutate        1       15173 15173.0
ovsdb_execute_select        1       10560 10560.0
ovsdb_execute_update        4      118056 29514.0
ovsdb_execute_wait          8      121386 15173.2
ovsdb_txn_commit            2    27976269 13988134.5

It is clear that ovsdb_txn_commit has the biggest scaling issue w.r.t
the number of monitoring clients.

Signed-off-by: Andy Zhou <[email protected]>
---
 lib/perf-counter.h  |  4 ++--
 ovsdb/execution.c   | 35 +++++++++++++++++++++++++++++++++--
 ovsdb/transaction.c |  3 +++
 3 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/lib/perf-counter.h b/lib/perf-counter.h
index c9abf72..851bd63 100644
--- a/lib/perf-counter.h
+++ b/lib/perf-counter.h
@@ -129,8 +129,8 @@ char *perf_counters_to_string(void);
 
 #else
 
-#define PERF_FUNCTON_COUNT_BEGIN
-#define PERF_FUNCTON_COUNT_END
+#define PERF_FUNCTION_BEGIN
+#define PERF_FUNCTION_END
 
 static inline void perf_counters_init(void) {}
 static inline void perf_counters_destroy(void) {}
diff --git a/ovsdb/execution.c b/ovsdb/execution.c
index de25a87..626dd83 100644
--- a/ovsdb/execution.c
+++ b/ovsdb/execution.c
@@ -31,6 +31,7 @@
 #include "server.h"
 #include "table.h"
 #include "timeval.h"
+#include "perf-counter.h"
 #include "transaction.h"
 
 struct ovsdb_execution {
@@ -285,6 +286,8 @@ ovsdb_execute_insert(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     struct ovsdb_error *error;
     struct uuid row_uuid;
 
+    PERF_FUNCTION_BEGIN;
+
     table = parse_table(x, parser, "table");
     uuid_name = ovsdb_parser_member(parser, "uuid-name", OP_ID | OP_OPTIONAL);
     row_json = ovsdb_parser_member(parser, "row", OP_OBJECT);
@@ -343,6 +346,8 @@ ovsdb_execute_insert(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
                         ovsdb_datum_to_json(&row->fields[OVSDB_COL_UUID],
                                             &ovsdb_type_uuid));
     }
+
+    PERF_FUNCTION_END;
     return error;
 }
 
@@ -357,6 +362,8 @@ ovsdb_execute_select(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     struct ovsdb_column_set sort = OVSDB_COLUMN_SET_INITIALIZER;
     struct ovsdb_error *error;
 
+    PERF_FUNCTION_BEGIN;
+
     table = parse_table(x, parser, "table");
     where = ovsdb_parser_member(parser, "where", OP_ARRAY);
     columns_json = ovsdb_parser_member(parser, "columns",
@@ -390,6 +397,7 @@ ovsdb_execute_select(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     ovsdb_column_set_destroy(&sort);
     ovsdb_condition_destroy(&condition);
 
+    PERF_FUNCTION_END;
     return error;
 }
 
@@ -426,6 +434,8 @@ ovsdb_execute_update(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     struct update_row_cbdata ur;
     struct ovsdb_error *error;
 
+    PERF_FUNCTION_BEGIN;
+
     table = parse_table(x, parser, "table");
     where = ovsdb_parser_member(parser, "where", OP_ARRAY);
     row_json = ovsdb_parser_member(parser, "row", OP_OBJECT);
@@ -466,6 +476,8 @@ ovsdb_execute_update(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     ovsdb_column_set_destroy(&columns);
     ovsdb_condition_destroy(&condition);
 
+    PERF_FUNCTION_END;
+
     return error;
 }
 
@@ -500,6 +512,8 @@ ovsdb_execute_mutate(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     struct mutate_row_cbdata mr;
     struct ovsdb_error *error;
 
+    PERF_FUNCTION_BEGIN;
+
     table = parse_table(x, parser, "table");
     where = ovsdb_parser_member(parser, "where", OP_ARRAY);
     mutations_json = ovsdb_parser_member(parser, "mutations", OP_ARRAY);
@@ -525,6 +539,7 @@ ovsdb_execute_mutate(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     ovsdb_mutation_set_destroy(&mutations);
     ovsdb_condition_destroy(&condition);
 
+    PERF_FUNCTION_END;
     return error;
 }
 
@@ -554,6 +569,8 @@ ovsdb_execute_delete(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     struct ovsdb_condition condition = OVSDB_CONDITION_INITIALIZER;
     struct ovsdb_error *error;
 
+    PERF_FUNCTION_BEGIN;
+
     where = ovsdb_parser_member(parser, "where", OP_ARRAY);
     table = parse_table(x, parser, "table");
     error = ovsdb_parser_get_error(parser);
@@ -574,6 +591,7 @@ ovsdb_execute_delete(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
 
     ovsdb_condition_destroy(&condition);
 
+    PERF_FUNCTION_END;
     return error;
 }
 
@@ -615,6 +633,8 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     long long int timeout_msec = 0;
     size_t i;
 
+    PERF_FUNCTION_BEGIN;
+
     timeout = ovsdb_parser_member(parser, "timeout", OP_NUMBER | OP_OPTIONAL);
     where = ovsdb_parser_member(parser, "where", OP_ARRAY);
     columns_json = ovsdb_parser_member(parser, "columns",
@@ -713,6 +733,8 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
     ovsdb_column_set_destroy(&columns);
     ovsdb_condition_destroy(&condition);
 
+    PERF_FUNCTION_END;
+
     return error;
 }
 
@@ -722,12 +744,15 @@ ovsdb_execute_comment(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
 {
     const struct json *comment;
 
+    PERF_FUNCTION_BEGIN;
+
     comment = ovsdb_parser_member(parser, "comment", OP_STRING);
     if (!comment) {
         return NULL;
     }
     ovsdb_txn_add_comment(x->txn, json_string(comment));
 
+    PERF_FUNCTION_END;
     return NULL;
 }
 
@@ -736,6 +761,9 @@ ovsdb_execute_assert(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
                      struct json *result OVS_UNUSED)
 {
     const struct json *lock_name;
+    struct ovsdb_error *error;
+
+    PERF_FUNCTION_BEGIN;
 
     lock_name = ovsdb_parser_member(parser, "lock", OP_ID);
     if (!lock_name) {
@@ -752,6 +780,9 @@ ovsdb_execute_assert(struct ovsdb_execution *x, struct 
ovsdb_parser *parser,
         }
     }
 
-    return ovsdb_error("not owner", "Asserted lock %s not held.",
-                       json_string(lock_name));
+    error = ovsdb_error("not owner", "Asserted lock %s not held.",
+                        json_string(lock_name));
+
+    PERF_FUNCTION_END;
+    return error;
 }
diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c
index 9e03963..11d3293 100644
--- a/ovsdb/transaction.c
+++ b/ovsdb/transaction.c
@@ -27,6 +27,7 @@
 #include "ovsdb.h"
 #include "row.h"
 #include "table.h"
+#include "perf-counter.h"
 #include "uuid.h"
 
 struct ovsdb_txn {
@@ -753,6 +754,7 @@ ovsdb_txn_commit(struct ovsdb_txn *txn, bool durable)
     struct ovsdb_replica *replica;
     struct ovsdb_error *error;
 
+    PERF_FUNCTION_BEGIN;
     /* Figure out what actually changed, and abort early if the transaction
      * was really a no-op. */
     error = for_each_txn_row(txn, determine_changes);
@@ -818,6 +820,7 @@ ovsdb_txn_commit(struct ovsdb_txn *txn, bool durable)
     ovsdb_error_assert(for_each_txn_row(txn, ovsdb_txn_row_commit));
     ovsdb_txn_free(txn);
 
+    PERF_FUNCTION_END;
     return NULL;
 }
 
-- 
1.9.1

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to