From 22ed65468335a3d803b74db2d4ee39344a4543cc Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sat, 13 Jul 2013 14:46:21 +0200 Subject: [PATCH] ifpps: Correct calculation of median values for CPU load ifpps always reported the same values for median as for average in the CPU load fields (usr, sys, idle, iowait). This is of course incorrect. The bug was due to 3 sub-problems: - Summing up long double values (m_cpu_*) in an uint64_t (all) - Not using %Lf (for long double) in mvwprintw() - Explicitely use floating point division in MEDIAN_EVEN Fix the bug by summing up in a separate accumulator of type long double, use the correct format string for long double and divide by 2.0 in MEDIAN_EVEN to force the result to be (long) double. Reported-by: Daniel Borkmann Signed-off-by: Tobias Klauser --- ifpps.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ifpps.c b/ifpps.c index 77dfa6ee..05e34595 100644 --- a/ifpps.c +++ b/ifpps.c @@ -802,7 +802,7 @@ static void screen_percpu_states_one(WINDOW *screen, const struct ifstat *rel, } #define MEDIAN_EVEN(member) do { \ - m_##member = (rel->member[i] + rel->member[j]) / 2; \ + m_##member = (rel->member[i] + rel->member[j]) / 2.0; \ } while (0) #define MEDIAN_ODD(member) do { \ @@ -848,6 +848,7 @@ static void screen_percpu_states(WINDOW *screen, const struct ifstat *rel, if (show_median) { long double m_cpu_user, m_cpu_nice, m_cpu_sys, m_cpu_idle, m_cpu_iow; + long double m_all; i = cpu_hits[cpus / 2].idx; if (cpus % 2 == 0) { @@ -868,16 +869,16 @@ static void screen_percpu_states(WINDOW *screen, const struct ifstat *rel, MEDIAN_ODD(cpu_iow); } - all = m_cpu_user + m_cpu_sys + m_cpu_nice + m_cpu_idle + m_cpu_iow; + m_all = m_cpu_user + m_cpu_sys + m_cpu_nice + m_cpu_idle + m_cpu_iow; mvwprintw(screen, (*voff)++, 2, - "med:%*s%14.1lf%% " - "%9.1lf%% " - "%10.1lf%% " - "%11.1lf%%", max_padd, "", - 100.0 * (m_cpu_user + m_cpu_nice) / all, - 100.0 * m_cpu_sys / all, - 100.0 * m_cpu_idle /all, - 100.0 * m_cpu_iow / all); + "med:%*s%14.1Lf%% " + "%9.1Lf%% " + "%10.1Lf%% " + "%11.1Lf%%", max_padd, "", + 100.0 * (m_cpu_user + m_cpu_nice) / m_all, + 100.0 * m_cpu_sys / m_all, + 100.0 * m_cpu_idle /m_all, + 100.0 * m_cpu_iow / m_all); } } -- 2.11.4.GIT