From d6bf059d348d5cb3d6908e839562ce46a9d3f252 Mon Sep 17 00:00:00 2001
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
Date: Wed, 6 Mar 2019 13:31:21 +0200
Subject: [PATCH] s390/vtime: steal time exponential moving average
Patch-mainline: v5.1-rc3
Git-commit: 152e9b8676c6e788c6bff095c1eaae7b86df5003
References: bsc#1119222
To be able to judge the current overcommitment ratio for a CPU add
a lowcore field with the exponential moving average of the steal time.
The average is updated every tick.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Acked-by: Liang Yan <lyan@suse.com>
---
arch/s390/include/asm/lowcore.h | 4 ++--
arch/s390/kernel/smp.c | 3 ++-
arch/s390/kernel/vtime.c | 19 ++++++++++++-------
3 files changed, 16 insertions(+), 10 deletions(-)
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -98,7 +98,7 @@ struct lowcore {
/* Current process. */
__u64 current_task; /* 0x0328 */
- __u8 pad_0x318[0x320-0x318]; /* 0x0330 */
+ __u64 avg_steal_timer; /* 0x0330 */
__u64 kernel_stack; /* 0x0338 */
/* Interrupt, DAT-off and restartstack. */
@@ -140,7 +140,7 @@ struct lowcore {
/* Per cpu primary space access list */
__u32 paste[16]; /* 0x0400 */
- __u8 pad_0x04c0[0x0500-0x0440]; /* 0x0440 */
+ __u8 pad_0x04c0[0x0500-0x0440]; /* 0x0440 */
/* br %r1 trampoline */
__u16 br_r1_trampoline; /* 0x0500 */
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -278,7 +278,8 @@ static void pcpu_prepare_secondary(struc
lc->percpu_offset = __per_cpu_offset[cpu];
lc->kernel_asce = S390_lowcore.kernel_asce;
lc->machine_flags = S390_lowcore.machine_flags;
- lc->user_timer = lc->system_timer = lc->steal_timer = 0;
+ lc->user_timer = lc->system_timer =
+ lc->steal_timer = lc->avg_steal_timer = 0;
__ctl_store(lc->cregs_save_area, 0, 15);
save_access_regs((unsigned int *) lc->access_regs_save_area);
memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -124,7 +124,7 @@ static void account_system_index_scaled(
*/
static int do_account_vtime(struct task_struct *tsk)
{
- u64 timer, clock, user, guest, system, hardirq, softirq, steal;
+ u64 timer, clock, user, guest, system, hardirq, softirq;
timer = S390_lowcore.last_update_timer;
clock = S390_lowcore.last_update_clock;
@@ -185,12 +185,6 @@ static int do_account_vtime(struct task_
account_system_index_scaled(tsk, softirq, scale_vtime(softirq),
CPUTIME_SOFTIRQ);
- steal = S390_lowcore.steal_timer;
- if ((s64) steal > 0) {
- S390_lowcore.steal_timer = 0;
- account_steal_time(cputime_to_nsecs(steal));
- }
-
return virt_timer_forward(user + guest + system + hardirq + softirq);
}
@@ -216,8 +210,19 @@ void vtime_task_switch(struct task_struc
*/
void vtime_flush(struct task_struct *tsk)
{
+ u64 steal, avg_steal;
+
if (do_account_vtime(tsk))
virt_timer_expire();
+
+ steal = S390_lowcore.steal_timer;
+ avg_steal = S390_lowcore.avg_steal_timer / 2;
+ if ((s64) steal > 0) {
+ S390_lowcore.steal_timer = 0;
+ account_steal_time(steal);
+ avg_steal += steal;
+ }
+ S390_lowcore.avg_steal_timer = avg_steal;
}
/*