aboutsummaryrefslogtreecommitdiff log msg author committer range
path: root/arch/s390
diff options
 context: 12345678910152025303540 space: includeignore mode: unifiedssdiffstat only
author committer Martin Schwidefsky 2015-09-10 11:18:20 +0200 Martin Schwidefsky 2015-09-17 13:43:43 +0200 61cc37906b45534fcc2bea03c17e135ec010b624 (patch) 9a37958a4a478a8d95abdc4cbd65dbdde1976d2d /arch/s390 58f8e9da33eb0104f5bee3e8b3ca44e1583c78b9 (diff) linux-61cc37906b45534fcc2bea03c17e135ec010b624.tar.gz
s390/vtime: correct scaled cputime for SMT
The scaled cputime is supposed to be derived from the normal per-thread cputime by dividing it with the average thread density in the last interval. The calculation of the scaling values for the average thread density is incorrect. The current, incorrect calculation: Ci = cycle count with i active threads T = unscaled cputime, sT = scaled cputime sT = T * (C1 + C2 + ... + Cn) / (1*C1 + 2*C2 + ... + n*Cn) The calculation happens to yield the correct numbers for the simple cases with only one Ci value not zero. But for cases with multiple Ci values not zero it fails. E.g. on a SMT-2 system with one thread active half the time and two threads active for the other half of the time it fails, the scaling factor should be 3/4 but the formula gives 2/3. The correct formula is sT = T * (C1/1 + C2/2 + ... + Cn/n) / (C1 + C2 + ... + Cn) Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/vtime.c12
1 files changed, 8 insertions, 4 deletions
 diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.cindex b9ce650e9e99..c8653435c70d 100644--- a/arch/s390/kernel/vtime.c+++ b/arch/s390/kernel/vtime.c@@ -89,17 +89,21 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset) if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies))) { u64 cycles_new[32], *cycles_old;- u64 delta, mult, div;+ u64 delta, fac, mult, div; cycles_old = this_cpu_ptr(mt_cycles); if (stcctm5(smp_cpu_mtid + 1, cycles_new) < 2) {+ fac = 1; mult = div = 0; for (i = 0; i <= smp_cpu_mtid; i++) { delta = cycles_new[i] - cycles_old[i];- mult += delta;- div += (i + 1) * delta;+ div += delta;+ mult *= i + 1;+ mult += delta * fac;+ fac *= i + 1; }- if (mult > 0) {+ div *= fac;+ if (div > 0) { /* Update scaling factor */ __this_cpu_write(mt_scaling_mult, mult); __this_cpu_write(mt_scaling_div, div);