Applications like ovn-controller have hundreds of stopwatches. When analyzing performance of different parts of the application you don't always know which exact stopwatch to look at, but going over all of them manually is tedious. When looking for slowest parts it's useful to be able to set a threshold and not show any stopwatches that are lower. For example, if the full recompute takes 10 seconds, I'd like to look at all the stopwatches that are above 1 second, or something like that.
Adding a new parameter for the stopwatch/show that will achieve that goal. For example: ovn-appctl stopwatch/show -t 1000 msec That will show all stopwatches that had a maximum value above or equal to 1000 msec. If the stopwatch is in usec or nsec the threshold will be applied properly with the units conversion. If the units are not provided, then the value will be checked using the units of each individual stopwatch. If all the stopwatches are in milliseconds, then '-t 10 msec' is equal to '-t 10000 usec', '-t 10000000 nsec' or just '-t 10'. Command also accepts the full version of the argument - '--threshold'. There are no users for this functionality in OVS, so there is no documentation to update. Signed-off-by: Ilya Maximets <[email protected]> --- lib/stopwatch.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/lib/stopwatch.c b/lib/stopwatch.c index 5c59fe71c..ab9df4092 100644 --- a/lib/stopwatch.c +++ b/lib/stopwatch.c @@ -295,7 +295,7 @@ stopwatch_show_protected(int argc, const char *argv[], struct ds *s) { struct stopwatch *sw; - if (argc > 1) { + if (argc == 2) { sw = shash_find_data(&stopwatches, argv[1]); if (!sw) { ds_put_cstr(s, "No such stopwatch"); @@ -303,11 +303,59 @@ stopwatch_show_protected(int argc, const char *argv[], struct ds *s) } stopwatch_print(sw, argv[1], s); } else { + unsigned long long threshold = 0; struct shash_node *node; int no_samples = 0; + int tunits = -1; + + if (argc > 2) { + if (strcmp(argv[1], "-t") && strcmp(argv[1], "--threshold")) { + ds_put_format(s, "Unknown option: %s", argv[1]); + return false; + } + if (!str_to_ullong(argv[2], 10, &threshold)) { + ds_put_format(s, "Invalid threshold: %s", argv[2]); + return false; + } + if (argc == 4) { + enum stopwatch_units all[] = { SW_MS, SW_US, SW_NS }; + for (size_t i = 0; i < ARRAY_SIZE(all); i++) { + if (!strcmp(unit_name[all[i]], argv[3])) { + tunits = all[i]; + break; + } + } + if (tunits < 0) { + ds_put_format(s, "Unknown units: %s" + " (supported: %s, %s or %s).", argv[3], + unit_name[SW_MS], unit_name[SW_US], unit_name[SW_NS]); + return false; + } + } + } SHASH_FOR_EACH (node, &stopwatches) { + double t = threshold; + int u = tunits; + sw = node->data; + + /* Convert threshold units into stopwatch units. */ + if (u >= 0 && u != sw->units) { + while (u < sw->units) { + u++; + t *= 1000; + } + while (u > sw->units) { + u--; + t /= 1000; + } + } + + if (sw->max < t) { + continue; + } + if (!sw->n_samples) { no_samples++; continue; @@ -498,8 +546,9 @@ stopwatch_exit(void) static void do_init_stopwatch(void) { - unixctl_command_register("stopwatch/show", "[NAME]", 0, 1, - stopwatch_show, NULL); + unixctl_command_register("stopwatch/show", + "[ NAME | -t|--threshold N [unit] ]", + 0, 4, stopwatch_show, NULL); unixctl_command_register("stopwatch/reset", "[NAME]", 0, 1, stopwatch_reset, NULL); guarded_list_init(&stopwatch_commands); -- 2.53.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
