aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r--arch/powerpc/kernel/time.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e49e93191b69..c9986fd400d8 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -291,13 +291,12 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
291 * Account time for a transition between system, hard irq 291 * Account time for a transition between system, hard irq
292 * or soft irq state. 292 * or soft irq state.
293 */ 293 */
294void account_system_vtime(struct task_struct *tsk) 294static u64 vtime_delta(struct task_struct *tsk,
295 u64 *sys_scaled, u64 *stolen)
295{ 296{
296 u64 now, nowscaled, delta, deltascaled; 297 u64 now, nowscaled, deltascaled;
297 unsigned long flags; 298 u64 udelta, delta, user_scaled;
298 u64 stolen, udelta, sys_scaled, user_scaled;
299 299
300 local_irq_save(flags);
301 now = mftb(); 300 now = mftb();
302 nowscaled = read_spurr(now); 301 nowscaled = read_spurr(now);
303 get_paca()->system_time += now - get_paca()->starttime; 302 get_paca()->system_time += now - get_paca()->starttime;
@@ -305,7 +304,7 @@ void account_system_vtime(struct task_struct *tsk)
305 deltascaled = nowscaled - get_paca()->startspurr; 304 deltascaled = nowscaled - get_paca()->startspurr;
306 get_paca()->startspurr = nowscaled; 305 get_paca()->startspurr = nowscaled;
307 306
308 stolen = calculate_stolen_time(now); 307 *stolen = calculate_stolen_time(now);
309 308
310 delta = get_paca()->system_time; 309 delta = get_paca()->system_time;
311 get_paca()->system_time = 0; 310 get_paca()->system_time = 0;
@@ -322,35 +321,45 @@ void account_system_vtime(struct task_struct *tsk)
322 * the user ticks get saved up in paca->user_time_scaled to be 321 * the user ticks get saved up in paca->user_time_scaled to be
323 * used by account_process_tick. 322 * used by account_process_tick.
324 */ 323 */
325 sys_scaled = delta; 324 *sys_scaled = delta;
326 user_scaled = udelta; 325 user_scaled = udelta;
327 if (deltascaled != delta + udelta) { 326 if (deltascaled != delta + udelta) {
328 if (udelta) { 327 if (udelta) {
329 sys_scaled = deltascaled * delta / (delta + udelta); 328 *sys_scaled = deltascaled * delta / (delta + udelta);
330 user_scaled = deltascaled - sys_scaled; 329 user_scaled = deltascaled - *sys_scaled;
331 } else { 330 } else {
332 sys_scaled = deltascaled; 331 *sys_scaled = deltascaled;
333 } 332 }
334 } 333 }
335 get_paca()->user_time_scaled += user_scaled; 334 get_paca()->user_time_scaled += user_scaled;
336 335
337 if (in_interrupt() || idle_task(smp_processor_id()) != tsk) { 336 return delta;
338 account_system_time(tsk, 0, delta, sys_scaled); 337}
339 if (stolen) 338
340 account_steal_time(stolen); 339void vtime_account_system(struct task_struct *tsk)
341 } else { 340{
342 account_idle_time(delta + stolen); 341 u64 delta, sys_scaled, stolen;
343 } 342
344 local_irq_restore(flags); 343 delta = vtime_delta(tsk, &sys_scaled, &stolen);
344 account_system_time(tsk, 0, delta, sys_scaled);
345 if (stolen)
346 account_steal_time(stolen);
347}
348
349void vtime_account_idle(struct task_struct *tsk)
350{
351 u64 delta, sys_scaled, stolen;
352
353 delta = vtime_delta(tsk, &sys_scaled, &stolen);
354 account_idle_time(delta + stolen);
345} 355}
346EXPORT_SYMBOL_GPL(account_system_vtime);
347 356
348/* 357/*
349 * Transfer the user and system times accumulated in the paca 358 * Transfer the user and system times accumulated in the paca
350 * by the exception entry and exit code to the generic process 359 * by the exception entry and exit code to the generic process
351 * user and system time records. 360 * user and system time records.
352 * Must be called with interrupts disabled. 361 * Must be called with interrupts disabled.
353 * Assumes that account_system_vtime() has been called recently 362 * Assumes that vtime_account() has been called recently
354 * (i.e. since the last entry from usermode) so that 363 * (i.e. since the last entry from usermode) so that
355 * get_paca()->user_time_scaled is up to date. 364 * get_paca()->user_time_scaled is up to date.
356 */ 365 */
@@ -366,6 +375,12 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
366 account_user_time(tsk, utime, utimescaled); 375 account_user_time(tsk, utime, utimescaled);
367} 376}
368 377
378void vtime_task_switch(struct task_struct *prev)
379{
380 vtime_account(prev);
381 account_process_tick(prev, 0);
382}
383
369#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */ 384#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
370#define calc_cputime_factors() 385#define calc_cputime_factors()
371#endif 386#endif
@@ -493,8 +508,6 @@ void timer_interrupt(struct pt_regs * regs)
493 */ 508 */
494 may_hard_irq_enable(); 509 may_hard_irq_enable();
495 510
496 trace_timer_interrupt_entry(regs);
497
498 __get_cpu_var(irq_stat).timer_irqs++; 511 __get_cpu_var(irq_stat).timer_irqs++;
499 512
500#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) 513#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
@@ -505,6 +518,8 @@ void timer_interrupt(struct pt_regs * regs)
505 old_regs = set_irq_regs(regs); 518 old_regs = set_irq_regs(regs);
506 irq_enter(); 519 irq_enter();
507 520
521 trace_timer_interrupt_entry(regs);
522
508 if (test_irq_work_pending()) { 523 if (test_irq_work_pending()) {
509 clear_irq_work_pending(); 524 clear_irq_work_pending();
510 irq_work_run(); 525 irq_work_run();
@@ -529,10 +544,10 @@ void timer_interrupt(struct pt_regs * regs)
529 } 544 }
530#endif 545#endif
531 546
547 trace_timer_interrupt_exit(regs);
548
532 irq_exit(); 549 irq_exit();
533 set_irq_regs(old_regs); 550 set_irq_regs(old_regs);
534
535 trace_timer_interrupt_exit(regs);
536} 551}
537 552
538/* 553/*