Blob Blame History Raw
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;
 }
 
 /*