Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f1c12af authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds
Browse files

[PATCH] s390: cputime misaccounting



finish_arch_switch needs to update the user cpu time as well, not just the
system cpu time.  Otherwise the partial user cpu time of a process that is
stored in the lowcore will be (mis-)accounted to the next process.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bcc13265
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -214,7 +214,7 @@ void account_ticks(struct pt_regs *regs)
#endif

#ifdef CONFIG_VIRT_CPU_ACCOUNTING
	account_user_vtime(current);
	account_tick_vtime(current);
#else
	while (ticks--)
		update_process_times(user_mode(regs));
+26 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
 * Update process times based on virtual cpu times stored by entry.S
 * to the lowcore fields user_timer, system_timer & steal_clock.
 */
void account_user_vtime(struct task_struct *tsk)
void account_tick_vtime(struct task_struct *tsk)
{
	cputime_t cputime;
	__u64 timer, clock;
@@ -72,6 +72,31 @@ void account_user_vtime(struct task_struct *tsk)
 	run_posix_cpu_timers(tsk);
}

/*
 * Update process times based on virtual cpu times stored by entry.S
 * to the lowcore fields user_timer, system_timer & steal_clock.
 */
void account_vtime(struct task_struct *tsk)
{
	cputime_t cputime;
	__u64 timer;

	timer = S390_lowcore.last_update_timer;
	asm volatile ("  STPT %0"    /* Store current cpu timer value */
		      : "=m" (S390_lowcore.last_update_timer) );
	S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;

	cputime = S390_lowcore.user_timer >> 12;
	S390_lowcore.user_timer -= cputime << 12;
	S390_lowcore.steal_clock -= cputime << 12;
	account_user_time(tsk, cputime);

	cputime =  S390_lowcore.system_timer >> 12;
	S390_lowcore.system_timer -= cputime << 12;
	S390_lowcore.steal_clock -= cputime << 12;
	account_system_time(tsk, 0, cputime);
}

/*
 * Update process times based on virtual cpu times stored by entry.S
 * to the lowcore fields user_timer, system_timer & steal_clock.
+3 −2
Original line number Diff line number Diff line
@@ -115,13 +115,14 @@ static inline void sched_cacheflush(void)
}

#ifdef CONFIG_VIRT_CPU_ACCOUNTING
extern void account_user_vtime(struct task_struct *);
extern void account_vtime(struct task_struct *);
extern void account_tick_vtime(struct task_struct *);
extern void account_system_vtime(struct task_struct *);
#endif

#define finish_arch_switch(prev) do {					     \
	set_fs(current->thread.mm_segment);				     \
	account_system_vtime(prev);					     \
	account_vtime(prev);						     \
} while (0)

#define nop() __asm__ __volatile__ ("nop")
+0 −4
Original line number Diff line number Diff line
@@ -93,10 +93,6 @@ extern void synchronize_irq(unsigned int irq);
struct task_struct;

#ifndef CONFIG_VIRT_CPU_ACCOUNTING
static inline void account_user_vtime(struct task_struct *tsk)
{
}

static inline void account_system_vtime(struct task_struct *tsk)
{
}