Commit 06b8e878 authored by Michael Neuling's avatar Michael Neuling Committed by Linus Torvalds

taskstats scaled time cleanup

This moves the ability to scale cputime into generic code.  This allows us
to fix the issue in kernel/timer.c (noticed by Balbir) where we could only
add an unscaled value to the scaled utime/stime.

This adds a cputime_to_scaled function.  As before, the POWERPC version
does the scaling based on the last SPURR/PURR ratio calculated.  The
generic and s390 (only other arch to implement asm/cputime.h) versions are
both NOPs.

Also moves the SPURR and PURR snapshots closer.
Signed-off-by: default avatarMichael Neuling <mikey@neuling.org>
Cc: Jay Lan <jlan@engr.sgi.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d9afa435
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/vdso_datapage.h> #include <asm/vdso_datapage.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/cputime.h>
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
#include <asm/iseries/it_lp_queue.h> #include <asm/iseries/it_lp_queue.h>
#include <asm/iseries/hv_call_xm.h> #include <asm/iseries/hv_call_xm.h>
...@@ -189,6 +190,8 @@ u64 __cputime_sec_factor; ...@@ -189,6 +190,8 @@ u64 __cputime_sec_factor;
EXPORT_SYMBOL(__cputime_sec_factor); EXPORT_SYMBOL(__cputime_sec_factor);
u64 __cputime_clockt_factor; u64 __cputime_clockt_factor;
EXPORT_SYMBOL(__cputime_clockt_factor); EXPORT_SYMBOL(__cputime_clockt_factor);
DEFINE_PER_CPU(unsigned long, cputime_last_delta);
DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
static void calc_cputime_factors(void) static void calc_cputime_factors(void)
{ {
...@@ -257,8 +260,8 @@ void account_system_vtime(struct task_struct *tsk) ...@@ -257,8 +260,8 @@ void account_system_vtime(struct task_struct *tsk)
} }
account_system_time(tsk, 0, delta); account_system_time(tsk, 0, delta);
account_system_time_scaled(tsk, deltascaled); account_system_time_scaled(tsk, deltascaled);
get_paca()->purrdelta = delta; per_cpu(cputime_last_delta, smp_processor_id()) = delta;
get_paca()->spurrdelta = deltascaled; per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -276,10 +279,7 @@ void account_process_tick(struct task_struct *tsk, int user_tick) ...@@ -276,10 +279,7 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
get_paca()->user_time = 0; get_paca()->user_time = 0;
account_user_time(tsk, utime); account_user_time(tsk, utime);
/* Estimate the scaled utime by scaling the real utime based utimescaled = cputime_to_scaled(utime);
* on the last spurr to purr ratio */
utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta;
get_paca()->spurrdelta = get_paca()->purrdelta = 0;
account_user_time_scaled(tsk, utimescaled); account_user_time_scaled(tsk, utimescaled);
} }
......
...@@ -18,6 +18,7 @@ typedef unsigned long cputime_t; ...@@ -18,6 +18,7 @@ typedef unsigned long cputime_t;
#define cputime_lt(__a, __b) ((__a) < (__b)) #define cputime_lt(__a, __b) ((__a) < (__b))
#define cputime_le(__a, __b) ((__a) <= (__b)) #define cputime_le(__a, __b) ((__a) <= (__b))
#define cputime_to_jiffies(__ct) (__ct) #define cputime_to_jiffies(__ct) (__ct)
#define cputime_to_scaled(__ct) (__ct)
#define jiffies_to_cputime(__hz) (__hz) #define jiffies_to_cputime(__hz) (__hz)
typedef u64 cputime64_t; typedef u64 cputime64_t;
......
...@@ -52,12 +52,26 @@ typedef u64 cputime64_t; ...@@ -52,12 +52,26 @@ typedef u64 cputime64_t;
* Convert cputime <-> jiffies * Convert cputime <-> jiffies
*/ */
extern u64 __cputime_jiffies_factor; extern u64 __cputime_jiffies_factor;
DECLARE_PER_CPU(unsigned long, cputime_last_delta);
DECLARE_PER_CPU(unsigned long, cputime_scaled_last_delta);
static inline unsigned long cputime_to_jiffies(const cputime_t ct) static inline unsigned long cputime_to_jiffies(const cputime_t ct)
{ {
return mulhdu(ct, __cputime_jiffies_factor); return mulhdu(ct, __cputime_jiffies_factor);
} }
/* Estimate the scaled cputime by scaling the real cputime based on
* the last scaled to real ratio */
static inline cputime_t cputime_to_scaled(const cputime_t ct)
{
if (cpu_has_feature(CPU_FTR_SPURR) &&
per_cpu(cputime_last_delta, smp_processor_id()))
return ct *
per_cpu(cputime_scaled_last_delta, smp_processor_id())/
per_cpu(cputime_last_delta, smp_processor_id());
return ct;
}
static inline cputime_t jiffies_to_cputime(const unsigned long jif) static inline cputime_t jiffies_to_cputime(const unsigned long jif)
{ {
cputime_t ct; cputime_t ct;
......
...@@ -115,8 +115,6 @@ struct paca_struct { ...@@ -115,8 +115,6 @@ struct paca_struct {
u64 system_time; /* accumulated system TB ticks */ u64 system_time; /* accumulated system TB ticks */
u64 startpurr; /* PURR/TB value snapshot */ u64 startpurr; /* PURR/TB value snapshot */
u64 startspurr; /* SPURR value snapshot */ u64 startspurr; /* SPURR value snapshot */
u64 purrdelta; /* FIXME: document */
u64 spurrdelta; /* FIXME: document */
}; };
extern struct paca_struct paca[]; extern struct paca_struct paca[];
......
...@@ -54,6 +54,7 @@ __div(unsigned long long n, unsigned int base) ...@@ -54,6 +54,7 @@ __div(unsigned long long n, unsigned int base)
#define cputime_lt(__a, __b) ((__a) < (__b)) #define cputime_lt(__a, __b) ((__a) < (__b))
#define cputime_le(__a, __b) ((__a) <= (__b)) #define cputime_le(__a, __b) ((__a) <= (__b))
#define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ)) #define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ))
#define cputime_to_scaled(__ct) (__ct)
#define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ)) #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ))
#define cputime64_zero (0ULL) #define cputime64_zero (0ULL)
......
...@@ -818,12 +818,14 @@ unsigned long next_timer_interrupt(void) ...@@ -818,12 +818,14 @@ unsigned long next_timer_interrupt(void)
#ifndef CONFIG_VIRT_CPU_ACCOUNTING #ifndef CONFIG_VIRT_CPU_ACCOUNTING
void account_process_tick(struct task_struct *p, int user_tick) void account_process_tick(struct task_struct *p, int user_tick)
{ {
cputime_t one_jiffy = jiffies_to_cputime(1);
if (user_tick) { if (user_tick) {
account_user_time(p, jiffies_to_cputime(1)); account_user_time(p, one_jiffy);
account_user_time_scaled(p, jiffies_to_cputime(1)); account_user_time_scaled(p, cputime_to_scaled(one_jiffy));
} else { } else {
account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1)); account_system_time(p, HARDIRQ_OFFSET, one_jiffy);
account_system_time_scaled(p, jiffies_to_cputime(1)); account_system_time_scaled(p, cputime_to_scaled(one_jiffy));
} }
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment