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

Commit 457533a7 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

[PATCH] fix scaled & unscaled cputime accounting



The utimescaled / stimescaled fields in the task structure and the
global cpustat should be set on all architectures. On s390 the calls
to account_user_time_scaled and account_system_time_scaled never have
been added. In addition system time that is accounted as guest time
to the user time of a process is accounted to the scaled system time
instead of the scaled user time.
To fix the bugs and to prevent future forgetfulness this patch merges
account_system_time_scaled into account_system_time and
account_user_time_scaled into account_user_time.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Jeremy Fitzhardinge <jeremy@xensource.com>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: Michael Neuling <mikey@neuling.org>
Acked-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 6a94cb73
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -93,13 +93,11 @@ void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next)
	now = ia64_get_itc();

	delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp));
	account_system_time(prev, 0, delta_stime);
	account_system_time_scaled(prev, delta_stime);
	account_system_time(prev, 0, delta_stime, delta_stime);

	if (pi->ac_utime) {
		delta_utime = cycle_to_cputime(pi->ac_utime);
		account_user_time(prev, delta_utime);
		account_user_time_scaled(prev, delta_utime);
		account_user_time(prev, delta_utime, delta_utime);
	}

	pi->ac_stamp = ni->ac_stamp = now;
@@ -122,8 +120,7 @@ void account_system_vtime(struct task_struct *tsk)
	now = ia64_get_itc();

	delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
	account_system_time(tsk, 0, delta_stime);
	account_system_time_scaled(tsk, delta_stime);
	account_system_time(tsk, 0, delta_stime, delta_stime);
	ti->ac_stime = 0;

	ti->ac_stamp = now;
@@ -143,8 +140,7 @@ void account_process_tick(struct task_struct *p, int user_tick)

	if (ti->ac_utime) {
		delta_utime = cycle_to_cputime(ti->ac_utime);
		account_user_time(p, delta_utime);
		account_user_time_scaled(p, delta_utime);
		account_user_time(p, delta_utime, delta_utime);
		ti->ac_utime = 0;
	}
}
+2 −5
Original line number Diff line number Diff line
@@ -256,8 +256,7 @@ void account_system_vtime(struct task_struct *tsk)
		delta += sys_time;
		get_paca()->system_time = 0;
	}
	account_system_time(tsk, 0, delta);
	account_system_time_scaled(tsk, deltascaled);
	account_system_time(tsk, 0, delta, deltascaled);
	per_cpu(cputime_last_delta, smp_processor_id()) = delta;
	per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
	local_irq_restore(flags);
@@ -275,10 +274,8 @@ void account_process_tick(struct task_struct *tsk, int user_tick)

	utime = get_paca()->user_time;
	get_paca()->user_time = 0;
	account_user_time(tsk, utime);

	utimescaled = cputime_to_scaled(utime);
	account_user_time_scaled(tsk, utimescaled);
	account_user_time(tsk, utime, utimescaled);
}

/*
+5 −5
Original line number Diff line number Diff line
@@ -50,12 +50,12 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
	rcu_user_flag = cputime != 0;
	S390_lowcore.user_timer -= cputime << 12;
	S390_lowcore.steal_clock -= cputime << 12;
	account_user_time(tsk, cputime);
	account_user_time(tsk, cputime, cputime);

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

	cputime = S390_lowcore.steal_clock;
	if ((__s64) cputime > 0) {
@@ -82,12 +82,12 @@ void account_vtime(struct task_struct *tsk)
	cputime = S390_lowcore.user_timer >> 12;
	S390_lowcore.user_timer -= cputime << 12;
	S390_lowcore.steal_clock -= cputime << 12;
	account_user_time(tsk, cputime);
	account_user_time(tsk, cputime, 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);
	account_system_time(tsk, 0, cputime, cputime);
}

/*
@@ -107,7 +107,7 @@ void account_system_vtime(struct task_struct *tsk)
	cputime =  S390_lowcore.system_timer >> 12;
	S390_lowcore.system_timer -= cputime << 12;
	S390_lowcore.steal_clock -= cputime << 12;
	account_system_time(tsk, 0, cputime);
	account_system_time(tsk, 0, cputime, cputime);
}
EXPORT_SYMBOL_GPL(account_system_vtime);

+2 −4
Original line number Diff line number Diff line
@@ -79,10 +79,8 @@ static inline unsigned int kstat_irqs(unsigned int irq)
}

extern unsigned long long task_delta_exec(struct task_struct *);
extern void account_user_time(struct task_struct *, cputime_t);
extern void account_user_time_scaled(struct task_struct *, cputime_t);
extern void account_system_time(struct task_struct *, int, cputime_t);
extern void account_system_time_scaled(struct task_struct *, cputime_t);
extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
extern void account_steal_time(struct task_struct *, cputime_t);

#endif /* _LINUX_KERNEL_STAT_H */
+16 −25
Original line number Diff line number Diff line
@@ -4080,13 +4080,17 @@ unsigned long long task_delta_exec(struct task_struct *p)
 * Account user cpu time to a process.
 * @p: the process that the cpu time gets accounted to
 * @cputime: the cpu time spent in user space since the last update
 * @cputime_scaled: cputime scaled by cpu frequency
 */
void account_user_time(struct task_struct *p, cputime_t cputime)
void account_user_time(struct task_struct *p, cputime_t cputime,
		       cputime_t cputime_scaled)
{
	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
	cputime64_t tmp;

	/* Add user time to process. */
	p->utime = cputime_add(p->utime, cputime);
	p->utimescaled = cputime_add(p->utimescaled, cputime_scaled);
	account_group_user_time(p, cputime);

	/* Add user time to cpustat. */
@@ -4103,51 +4107,49 @@ void account_user_time(struct task_struct *p, cputime_t cputime)
 * Account guest cpu time to a process.
 * @p: the process that the cpu time gets accounted to
 * @cputime: the cpu time spent in virtual machine since the last update
 * @cputime_scaled: cputime scaled by cpu frequency
 */
static void account_guest_time(struct task_struct *p, cputime_t cputime)
static void account_guest_time(struct task_struct *p, cputime_t cputime,
			       cputime_t cputime_scaled)
{
	cputime64_t tmp;
	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;

	tmp = cputime_to_cputime64(cputime);

	/* Add guest time to process. */
	p->utime = cputime_add(p->utime, cputime);
	p->utimescaled = cputime_add(p->utimescaled, cputime_scaled);
	account_group_user_time(p, cputime);
	p->gtime = cputime_add(p->gtime, cputime);

	/* Add guest time to cpustat. */
	cpustat->user = cputime64_add(cpustat->user, tmp);
	cpustat->guest = cputime64_add(cpustat->guest, tmp);
}

/*
 * Account scaled user cpu time to a process.
 * @p: the process that the cpu time gets accounted to
 * @cputime: the cpu time spent in user space since the last update
 */
void account_user_time_scaled(struct task_struct *p, cputime_t cputime)
{
	p->utimescaled = cputime_add(p->utimescaled, cputime);
}

/*
 * Account system cpu time to a process.
 * @p: the process that the cpu time gets accounted to
 * @hardirq_offset: the offset to subtract from hardirq_count()
 * @cputime: the cpu time spent in kernel space since the last update
 * @cputime_scaled: cputime scaled by cpu frequency
 */
void account_system_time(struct task_struct *p, int hardirq_offset,
			 cputime_t cputime)
			 cputime_t cputime, cputime_t cputime_scaled)
{
	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
	struct rq *rq = this_rq();
	cputime64_t tmp;

	if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
		account_guest_time(p, cputime);
		account_guest_time(p, cputime, cputime_scaled);
		return;
	}

	/* Add system time to process. */
	p->stime = cputime_add(p->stime, cputime);
	p->stimescaled = cputime_add(p->stimescaled, cputime_scaled);
	account_group_system_time(p, cputime);

	/* Add system time to cpustat. */
@@ -4166,17 +4168,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
	acct_update_integrals(p);
}

/*
 * Account scaled system cpu time to a process.
 * @p: the process that the cpu time gets accounted to
 * @hardirq_offset: the offset to subtract from hardirq_count()
 * @cputime: the cpu time spent in kernel space since the last update
 */
void account_system_time_scaled(struct task_struct *p, cputime_t cputime)
{
	p->stimescaled = cputime_add(p->stimescaled, cputime);
}

/*
 * Account for involuntary wait time.
 * @p: the process from which the cpu time has been stolen
Loading