s390/vtime: correct system time accounting
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 20 Dec 2016 06:27:59 +0000 (07:27 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 20 Dec 2016 14:22:56 +0000 (15:22 +0100)
There is a slight misaccounting of system time in vtime_account_user.
This function is called once per HZ tick in interrupt context.
The irq_enter function already accounted the system time up to the
point of the irq_enter call. The system time from irq_enter until
vtime_account_user/do_account_vtime is reached is irq time but it
is accounted to the previous context.

Just drop the hardirq offset from arch/s390/kernel/vtime.c.

Reported-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/vtime.c

index 6b246aa..1b5c5ee 100644 (file)
@@ -94,7 +94,7 @@ static void update_mt_scaling(void)
  * Update process times based on virtual cpu times stored by entry.S
  * to the lowcore fields user_timer, system_timer & steal_clock.
  */
-static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
+static int do_account_vtime(struct task_struct *tsk)
 {
        u64 timer, clock, user, system, steal;
        u64 user_scaled, system_scaled;
@@ -138,7 +138,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
        }
        account_user_time(tsk, user);
        tsk->utimescaled += user_scaled;
-       account_system_time(tsk, hardirq_offset, system);
+       account_system_time(tsk, 0, system);
        tsk->stimescaled += system_scaled;
 
        steal = S390_lowcore.steal_timer;
@@ -152,7 +152,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
 
 void vtime_task_switch(struct task_struct *prev)
 {
-       do_account_vtime(prev, 0);
+       do_account_vtime(prev);
        prev->thread.user_timer = S390_lowcore.user_timer;
        prev->thread.system_timer = S390_lowcore.system_timer;
        S390_lowcore.user_timer = current->thread.user_timer;
@@ -166,7 +166,7 @@ void vtime_task_switch(struct task_struct *prev)
  */
 void vtime_account_user(struct task_struct *tsk)
 {
-       if (do_account_vtime(tsk, HARDIRQ_OFFSET))
+       if (do_account_vtime(tsk))
                virt_timer_expire();
 }