summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/time.c
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2016-05-17 08:33:46 +0200
committerScott Wood <oss@buserror.net>2016-07-09 01:43:50 -0500
commitc223c90386bc2306510e0ceacd768a0123ff2a2f (patch)
tree520a7bc88a7e36bbd0615cc5a035337a36729fb8 /arch/powerpc/kernel/time.c
parent1afbf61750364864adf6a17818c5bbbea4dea531 (diff)
downloadop-kernel-dev-c223c90386bc2306510e0ceacd768a0123ff2a2f.zip
op-kernel-dev-c223c90386bc2306510e0ceacd768a0123ff2a2f.tar.gz
powerpc32: provide VIRT_CPU_ACCOUNTING
This patch provides VIRT_CPU_ACCOUTING to PPC32 architecture. PPC32 doesn't have the PACA structure, so we use the task_info structure to store the accounting data. In order to reuse on PPC32 the PPC64 functions, all u64 data has been replaced by 'unsigned long' so that it is u32 on PPC32 and u64 on PPC64 Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Scott Wood <oss@buserror.net>
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r--arch/powerpc/kernel/time.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 6b4d01d..4e7759c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -167,7 +167,15 @@ DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
cputime_t cputime_one_jiffy;
+#ifdef CONFIG_PPC_SPLPAR
void (*dtl_consumer)(struct dtl_entry *, u64);
+#endif
+
+#ifdef CONFIG_PPC64
+#define get_accounting(tsk) (&get_paca()->accounting)
+#else
+#define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
+#endif
static void calc_cputime_factors(void)
{
@@ -187,7 +195,7 @@ static void calc_cputime_factors(void)
* Read the SPURR on systems that have it, otherwise the PURR,
* or if that doesn't exist return the timebase value passed in.
*/
-static u64 read_spurr(u64 tb)
+static unsigned long read_spurr(unsigned long tb)
{
if (cpu_has_feature(CPU_FTR_SPURR))
return mfspr(SPRN_SPURR);
@@ -250,8 +258,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
void accumulate_stolen_time(void)
{
u64 sst, ust;
-
u8 save_soft_enabled = local_paca->soft_enabled;
+ struct cpu_accounting_data *acct = &local_paca->accounting;
/* We are called early in the exception entry, before
* soft/hard_enabled are sync'ed to the expected state
@@ -261,10 +269,10 @@ void accumulate_stolen_time(void)
*/
local_paca->soft_enabled = 0;
- sst = scan_dispatch_log(local_paca->starttime_user);
- ust = scan_dispatch_log(local_paca->starttime);
- local_paca->system_time -= sst;
- local_paca->user_time -= ust;
+ sst = scan_dispatch_log(acct->starttime_user);
+ ust = scan_dispatch_log(acct->starttime);
+ acct->system_time -= sst;
+ acct->user_time -= ust;
local_paca->stolen_time += ust + sst;
local_paca->soft_enabled = save_soft_enabled;
@@ -276,7 +284,7 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) {
stolen = scan_dispatch_log(stop_tb);
- get_paca()->system_time -= stolen;
+ get_paca()->accounting.system_time -= stolen;
}
stolen += get_paca()->stolen_time;
@@ -296,27 +304,29 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
* Account time for a transition between system, hard irq
* or soft irq state.
*/
-static u64 vtime_delta(struct task_struct *tsk,
- u64 *sys_scaled, u64 *stolen)
+static unsigned long vtime_delta(struct task_struct *tsk,
+ unsigned long *sys_scaled,
+ unsigned long *stolen)
{
- u64 now, nowscaled, deltascaled;
- u64 udelta, delta, user_scaled;
+ unsigned long now, nowscaled, deltascaled;
+ unsigned long udelta, delta, user_scaled;
+ struct cpu_accounting_data *acct = get_accounting(tsk);
WARN_ON_ONCE(!irqs_disabled());
now = mftb();
nowscaled = read_spurr(now);
- get_paca()->system_time += now - get_paca()->starttime;
- get_paca()->starttime = now;
- deltascaled = nowscaled - get_paca()->startspurr;
- get_paca()->startspurr = nowscaled;
+ acct->system_time += now - acct->starttime;
+ acct->starttime = now;
+ deltascaled = nowscaled - acct->startspurr;
+ acct->startspurr = nowscaled;
*stolen = calculate_stolen_time(now);
- delta = get_paca()->system_time;
- get_paca()->system_time = 0;
- udelta = get_paca()->user_time - get_paca()->utime_sspurr;
- get_paca()->utime_sspurr = get_paca()->user_time;
+ delta = acct->system_time;
+ acct->system_time = 0;
+ udelta = acct->user_time - acct->utime_sspurr;
+ acct->utime_sspurr = acct->user_time;
/*
* Because we don't read the SPURR on every kernel entry/exit,
@@ -338,14 +348,14 @@ static u64 vtime_delta(struct task_struct *tsk,
*sys_scaled = deltascaled;
}
}
- get_paca()->user_time_scaled += user_scaled;
+ acct->user_time_scaled += user_scaled;
return delta;
}
void vtime_account_system(struct task_struct *tsk)
{
- u64 delta, sys_scaled, stolen;
+ unsigned long delta, sys_scaled, stolen;
delta = vtime_delta(tsk, &sys_scaled, &stolen);
account_system_time(tsk, 0, delta, sys_scaled);
@@ -356,7 +366,7 @@ EXPORT_SYMBOL_GPL(vtime_account_system);
void vtime_account_idle(struct task_struct *tsk)
{
- u64 delta, sys_scaled, stolen;
+ unsigned long delta, sys_scaled, stolen;
delta = vtime_delta(tsk, &sys_scaled, &stolen);
account_idle_time(delta + stolen);
@@ -374,15 +384,32 @@ void vtime_account_idle(struct task_struct *tsk)
void vtime_account_user(struct task_struct *tsk)
{
cputime_t utime, utimescaled;
+ struct cpu_accounting_data *acct = get_accounting(tsk);
- utime = get_paca()->user_time;
- utimescaled = get_paca()->user_time_scaled;
- get_paca()->user_time = 0;
- get_paca()->user_time_scaled = 0;
- get_paca()->utime_sspurr = 0;
+ utime = acct->user_time;
+ utimescaled = acct->user_time_scaled;
+ acct->user_time = 0;
+ acct->user_time_scaled = 0;
+ acct->utime_sspurr = 0;
account_user_time(tsk, utime, utimescaled);
}
+#ifdef CONFIG_PPC32
+/*
+ * Called from the context switch with interrupts disabled, to charge all
+ * accumulated times to the current process, and to prepare accounting on
+ * the next process.
+ */
+void arch_vtime_task_switch(struct task_struct *prev)
+{
+ struct cpu_accounting_data *acct = get_accounting(current);
+
+ acct->starttime = get_accounting(prev)->starttime;
+ acct->system_time = 0;
+ acct->user_time = 0;
+}
+#endif /* CONFIG_PPC32 */
+
#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
#define calc_cputime_factors()
#endif
OpenPOWER on IntegriCloud