Commit 34839f5a authored by Steven Rostedt (Red Hat)'s avatar Steven Rostedt (Red Hat) Committed by Steven Rostedt

tracing: Only calculate stats of tracepoint benchmarks for 2^32 times

When calculating the average and standard deviation, it is required that
the count be less than UINT_MAX, otherwise the do_div() will get
undefined results. After 2^32 counts of data, the average and standard
deviation should pretty much be set anyway.
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 72e2fe38
...@@ -16,7 +16,10 @@ static u64 bm_last; ...@@ -16,7 +16,10 @@ static u64 bm_last;
static u64 bm_max; static u64 bm_max;
static u64 bm_min; static u64 bm_min;
static u64 bm_first; static u64 bm_first;
static s64 bm_cnt; static u64 bm_cnt;
static u64 bm_stddev;
static unsigned int bm_avg;
static unsigned int bm_std;
/* /*
* This gets called in a loop recording the time it took to write * This gets called in a loop recording the time it took to write
...@@ -66,22 +69,35 @@ static void trace_do_benchmark(void) ...@@ -66,22 +69,35 @@ static void trace_do_benchmark(void)
bm_last = delta; bm_last = delta;
bm_total += delta;
bm_totalsq += delta * delta;
if (delta > bm_max) if (delta > bm_max)
bm_max = delta; bm_max = delta;
if (!bm_min || delta < bm_min) if (!bm_min || delta < bm_min)
bm_min = delta; bm_min = delta;
/*
* When bm_cnt is greater than UINT_MAX, it breaks the statistics
* accounting. Freeze the statistics when that happens.
* We should have enough data for the avg and stddev anyway.
*/
if (bm_cnt > UINT_MAX) {
scnprintf(bm_str, BENCHMARK_EVENT_STRLEN,
"last=%llu first=%llu max=%llu min=%llu ** avg=%u std=%d std^2=%lld",
bm_last, bm_first, bm_max, bm_min, bm_avg, bm_std, bm_stddev);
return;
}
bm_total += delta;
bm_totalsq += delta * delta;
if (bm_cnt > 1) { if (bm_cnt > 1) {
/* /*
* Apply Welford's method to calculate standard deviation: * Apply Welford's method to calculate standard deviation:
* s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2)
*/ */
stddev = (u64)bm_cnt * bm_totalsq - bm_total * bm_total; stddev = (u64)bm_cnt * bm_totalsq - bm_total * bm_total;
do_div(stddev, bm_cnt); do_div(stddev, (u32)bm_cnt);
do_div(stddev, bm_cnt - 1); do_div(stddev, (u32)bm_cnt - 1);
} else } else
stddev = 0; stddev = 0;
...@@ -119,6 +135,10 @@ static void trace_do_benchmark(void) ...@@ -119,6 +135,10 @@ static void trace_do_benchmark(void)
scnprintf(bm_str, BENCHMARK_EVENT_STRLEN, scnprintf(bm_str, BENCHMARK_EVENT_STRLEN,
"last=%llu first=%llu max=%llu min=%llu avg=%u std=%d std^2=%lld", "last=%llu first=%llu max=%llu min=%llu avg=%u std=%d std^2=%lld",
bm_last, bm_first, bm_max, bm_min, avg, std, stddev); bm_last, bm_first, bm_max, bm_min, avg, std, stddev);
bm_std = std;
bm_avg = avg;
bm_stddev = stddev;
} }
static int benchmark_event_kthread(void *arg) static int benchmark_event_kthread(void *arg)
...@@ -170,6 +190,9 @@ void trace_benchmark_unreg(void) ...@@ -170,6 +190,9 @@ void trace_benchmark_unreg(void)
bm_max = 0; bm_max = 0;
bm_min = 0; bm_min = 0;
bm_cnt = 0; bm_cnt = 0;
/* bm_first doesn't need to be reset but reset it anyway */ /* These don't need to be reset but reset them anyway */
bm_first = 0; bm_first = 0;
bm_std = 0;
bm_avg = 0;
bm_stddev = 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment