diff options
-rw-r--r-- | include/linux/vtime.h | 8 | ||||
-rw-r--r-- | kernel/sched/cputime.c | 41 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 5 |
3 files changed, 43 insertions, 11 deletions
diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 21ef703d1b25..5368af9bdf06 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h | |||
@@ -10,12 +10,20 @@ extern void vtime_account_system_irqsafe(struct task_struct *tsk); | |||
10 | extern void vtime_account_idle(struct task_struct *tsk); | 10 | extern void vtime_account_idle(struct task_struct *tsk); |
11 | extern void vtime_account_user(struct task_struct *tsk); | 11 | extern void vtime_account_user(struct task_struct *tsk); |
12 | extern void vtime_account(struct task_struct *tsk); | 12 | extern void vtime_account(struct task_struct *tsk); |
13 | |||
14 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | ||
15 | extern bool vtime_accounting_enabled(void); | ||
13 | #else | 16 | #else |
17 | static inline bool vtime_accounting_enabled(void) { return true; } | ||
18 | #endif | ||
19 | |||
20 | #else /* !CONFIG_VIRT_CPU_ACCOUNTING */ | ||
14 | static inline void vtime_task_switch(struct task_struct *prev) { } | 21 | static inline void vtime_task_switch(struct task_struct *prev) { } |
15 | static inline void vtime_account_system(struct task_struct *tsk) { } | 22 | static inline void vtime_account_system(struct task_struct *tsk) { } |
16 | static inline void vtime_account_system_irqsafe(struct task_struct *tsk) { } | 23 | static inline void vtime_account_system_irqsafe(struct task_struct *tsk) { } |
17 | static inline void vtime_account_user(struct task_struct *tsk) { } | 24 | static inline void vtime_account_user(struct task_struct *tsk) { } |
18 | static inline void vtime_account(struct task_struct *tsk) { } | 25 | static inline void vtime_account(struct task_struct *tsk) { } |
26 | static inline bool vtime_accounting_enabled(void) { return false; } | ||
19 | #endif | 27 | #endif |
20 | 28 | ||
21 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | 29 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN |
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 1c964eced92c..e1939d38bf73 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c | |||
@@ -317,8 +317,6 @@ out: | |||
317 | rcu_read_unlock(); | 317 | rcu_read_unlock(); |
318 | } | 318 | } |
319 | 319 | ||
320 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
321 | |||
322 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | 320 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING |
323 | /* | 321 | /* |
324 | * Account a tick to a process and cpustat | 322 | * Account a tick to a process and cpustat |
@@ -383,11 +381,12 @@ static void irqtime_account_idle_ticks(int ticks) | |||
383 | irqtime_account_process_tick(current, 0, rq); | 381 | irqtime_account_process_tick(current, 0, rq); |
384 | } | 382 | } |
385 | #else /* CONFIG_IRQ_TIME_ACCOUNTING */ | 383 | #else /* CONFIG_IRQ_TIME_ACCOUNTING */ |
386 | static void irqtime_account_idle_ticks(int ticks) {} | 384 | static inline void irqtime_account_idle_ticks(int ticks) {} |
387 | static void irqtime_account_process_tick(struct task_struct *p, int user_tick, | 385 | static inline void irqtime_account_process_tick(struct task_struct *p, int user_tick, |
388 | struct rq *rq) {} | 386 | struct rq *rq) {} |
389 | #endif /* CONFIG_IRQ_TIME_ACCOUNTING */ | 387 | #endif /* CONFIG_IRQ_TIME_ACCOUNTING */ |
390 | 388 | ||
389 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE | ||
391 | /* | 390 | /* |
392 | * Account a single tick of cpu time. | 391 | * Account a single tick of cpu time. |
393 | * @p: the process that the cpu time gets accounted to | 392 | * @p: the process that the cpu time gets accounted to |
@@ -398,6 +397,9 @@ void account_process_tick(struct task_struct *p, int user_tick) | |||
398 | cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy); | 397 | cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy); |
399 | struct rq *rq = this_rq(); | 398 | struct rq *rq = this_rq(); |
400 | 399 | ||
400 | if (vtime_accounting_enabled()) | ||
401 | return; | ||
402 | |||
401 | if (sched_clock_irqtime) { | 403 | if (sched_clock_irqtime) { |
402 | irqtime_account_process_tick(p, user_tick, rq); | 404 | irqtime_account_process_tick(p, user_tick, rq); |
403 | return; | 405 | return; |
@@ -439,8 +441,7 @@ void account_idle_ticks(unsigned long ticks) | |||
439 | 441 | ||
440 | account_idle_time(jiffies_to_cputime(ticks)); | 442 | account_idle_time(jiffies_to_cputime(ticks)); |
441 | } | 443 | } |
442 | 444 | #endif /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ | |
443 | #endif | ||
444 | 445 | ||
445 | /* | 446 | /* |
446 | * Use precise platform statistics if available: | 447 | * Use precise platform statistics if available: |
@@ -475,6 +476,9 @@ EXPORT_SYMBOL_GPL(vtime_account_system_irqsafe); | |||
475 | #ifndef __ARCH_HAS_VTIME_TASK_SWITCH | 476 | #ifndef __ARCH_HAS_VTIME_TASK_SWITCH |
476 | void vtime_task_switch(struct task_struct *prev) | 477 | void vtime_task_switch(struct task_struct *prev) |
477 | { | 478 | { |
479 | if (!vtime_accounting_enabled()) | ||
480 | return; | ||
481 | |||
478 | if (is_idle_task(prev)) | 482 | if (is_idle_task(prev)) |
479 | vtime_account_idle(prev); | 483 | vtime_account_idle(prev); |
480 | else | 484 | else |
@@ -498,6 +502,9 @@ void vtime_task_switch(struct task_struct *prev) | |||
498 | #ifndef __ARCH_HAS_VTIME_ACCOUNT | 502 | #ifndef __ARCH_HAS_VTIME_ACCOUNT |
499 | void vtime_account(struct task_struct *tsk) | 503 | void vtime_account(struct task_struct *tsk) |
500 | { | 504 | { |
505 | if (!vtime_accounting_enabled()) | ||
506 | return; | ||
507 | |||
501 | if (!in_interrupt()) { | 508 | if (!in_interrupt()) { |
502 | /* | 509 | /* |
503 | * If we interrupted user, context_tracking_in_user() | 510 | * If we interrupted user, context_tracking_in_user() |
@@ -520,7 +527,7 @@ void vtime_account(struct task_struct *tsk) | |||
520 | EXPORT_SYMBOL_GPL(vtime_account); | 527 | EXPORT_SYMBOL_GPL(vtime_account); |
521 | #endif /* __ARCH_HAS_VTIME_ACCOUNT */ | 528 | #endif /* __ARCH_HAS_VTIME_ACCOUNT */ |
522 | 529 | ||
523 | #else | 530 | #else /* !CONFIG_VIRT_CPU_ACCOUNTING */ |
524 | 531 | ||
525 | static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total) | 532 | static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total) |
526 | { | 533 | { |
@@ -599,7 +606,7 @@ void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime | |||
599 | thread_group_cputime(p, &cputime); | 606 | thread_group_cputime(p, &cputime); |
600 | cputime_adjust(&cputime, &p->signal->prev_cputime, ut, st); | 607 | cputime_adjust(&cputime, &p->signal->prev_cputime, ut, st); |
601 | } | 608 | } |
602 | #endif | 609 | #endif /* !CONFIG_VIRT_CPU_ACCOUNTING */ |
603 | 610 | ||
604 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | 611 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN |
605 | static DEFINE_PER_CPU(unsigned long long, cputime_snap); | 612 | static DEFINE_PER_CPU(unsigned long long, cputime_snap); |
@@ -617,14 +624,23 @@ static cputime_t get_vtime_delta(void) | |||
617 | 624 | ||
618 | void vtime_account_system(struct task_struct *tsk) | 625 | void vtime_account_system(struct task_struct *tsk) |
619 | { | 626 | { |
620 | cputime_t delta_cpu = get_vtime_delta(); | 627 | cputime_t delta_cpu; |
628 | |||
629 | if (!vtime_accounting_enabled()) | ||
630 | return; | ||
621 | 631 | ||
632 | delta_cpu = get_vtime_delta(); | ||
622 | account_system_time(tsk, irq_count(), delta_cpu, cputime_to_scaled(delta_cpu)); | 633 | account_system_time(tsk, irq_count(), delta_cpu, cputime_to_scaled(delta_cpu)); |
623 | } | 634 | } |
624 | 635 | ||
625 | void vtime_account_user(struct task_struct *tsk) | 636 | void vtime_account_user(struct task_struct *tsk) |
626 | { | 637 | { |
627 | cputime_t delta_cpu = get_vtime_delta(); | 638 | cputime_t delta_cpu; |
639 | |||
640 | if (!vtime_accounting_enabled()) | ||
641 | return; | ||
642 | |||
643 | delta_cpu = get_vtime_delta(); | ||
628 | 644 | ||
629 | account_user_time(tsk, delta_cpu, cputime_to_scaled(delta_cpu)); | 645 | account_user_time(tsk, delta_cpu, cputime_to_scaled(delta_cpu)); |
630 | } | 646 | } |
@@ -635,4 +651,9 @@ void vtime_account_idle(struct task_struct *tsk) | |||
635 | 651 | ||
636 | account_idle_time(delta_cpu); | 652 | account_idle_time(delta_cpu); |
637 | } | 653 | } |
654 | |||
655 | bool vtime_accounting_enabled(void) | ||
656 | { | ||
657 | return context_tracking_active(); | ||
658 | } | ||
638 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ | 659 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index d58e552d9fd1..46dfb6d94b1c 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -631,8 +631,11 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) | |||
631 | 631 | ||
632 | static void tick_nohz_account_idle_ticks(struct tick_sched *ts) | 632 | static void tick_nohz_account_idle_ticks(struct tick_sched *ts) |
633 | { | 633 | { |
634 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 634 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
635 | unsigned long ticks; | 635 | unsigned long ticks; |
636 | |||
637 | if (vtime_accounting_enabled()) | ||
638 | return; | ||
636 | /* | 639 | /* |
637 | * We stopped the tick in idle. Update process times would miss the | 640 | * We stopped the tick in idle. Update process times would miss the |
638 | * time we slept as update_process_times does only a 1 tick | 641 | * time we slept as update_process_times does only a 1 tick |