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
