summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2015-08-03 16:16:40 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-08-04 14:26:17 +0200
commitf341b8dff9823a969be5fb3c958e5cb305ac67e8 (patch)
tree95320cc56a2f9af389ffa3bf17e64e1f8dc289d6
parent5a7ff75a0c63222d138d944240146dc49a9624e1 (diff)
s390/vtime: limit MT scaling value updates
The MT scaling values are updated on each calll to do_account_vtime. This function is called for each HZ interrupt and for each context switch. Context switch can happen often, the STCCTM instruction on this path is noticeable. Limit the updates to once per jiffy. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/vtime.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index e53d3595a7c8..b9ce650e9e99 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -28,6 +28,7 @@ static atomic64_t virt_timer_elapsed;
static DEFINE_PER_CPU(u64, mt_cycles[32]);
static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
+static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
static inline u64 get_vtimer(void)
{
@@ -85,7 +86,8 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock;
/* Do MT utilization calculation */
- if (smp_cpu_mtid) {
+ if (smp_cpu_mtid &&
+ time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies))) {
u64 cycles_new[32], *cycles_old;
u64 delta, mult, div;
@@ -105,6 +107,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
sizeof(u64) * (smp_cpu_mtid + 1));
}
}
+ __this_cpu_write(mt_scaling_jiffies, jiffies_64);
}
user = S390_lowcore.user_timer - ti->user_timer;
@@ -376,4 +379,11 @@ void vtime_init(void)
{
/* set initial cpu timer */
set_vtimer(VTIMER_MAX_SLICE);
+ /* Setup initial MT scaling values */
+ if (smp_cpu_mtid) {
+ __this_cpu_write(mt_scaling_jiffies, jiffies);
+ __this_cpu_write(mt_scaling_mult, 1);
+ __this_cpu_write(mt_scaling_div, 1);
+ stcctm5(smp_cpu_mtid + 1, this_cpu_ptr(mt_cycles));
+ }
}