Skip to content

Commit

Permalink
sched/cputime: Replace VTIME_GEN irq time code with IRQ_TIME_ACCOUNTI…
Browse files Browse the repository at this point in the history
…NG code

The CONFIG_VIRT_CPU_ACCOUNTING_GEN irq time tracking code does not
appear to currently work right.

On CPUs without nohz_full=, only tick based irq time sampling is
done, which breaks down when dealing with a nohz_idle CPU.

On firewalls and similar systems, no ticks may happen on a CPU for a
while, and the irq time spent may never get accounted properly. This
can cause issues with capacity planning and power saving, which use
the CPU statistics as inputs in decision making.

Remove the VTIME_GEN vtime irq time code, and replace it with the
IRQ_TIME_ACCOUNTING code, when selected as a config option by the user.

Signed-off-by: Rik van Riel <[email protected]>
Signed-off-by: Frederic Weisbecker <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Radim Krcmar <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Wanpeng Li <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Rik van Riel authored and Ingo Molnar committed Jul 14, 2016
1 parent 5743021 commit b58c358
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 34 deletions.
32 changes: 14 additions & 18 deletions include/linux/vtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ struct task_struct;
*/
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
static inline bool vtime_accounting_cpu_enabled(void) { return true; }

#ifdef __ARCH_HAS_VTIME_ACCOUNT
extern void vtime_account_irq_enter(struct task_struct *tsk);
#else
extern void vtime_common_account_irq_enter(struct task_struct *tsk);
static inline void vtime_account_irq_enter(struct task_struct *tsk)
{
if (vtime_accounting_cpu_enabled())
vtime_common_account_irq_enter(tsk);
}
#endif /* __ARCH_HAS_VTIME_ACCOUNT */

#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */

#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
Expand Down Expand Up @@ -64,17 +76,6 @@ extern void vtime_account_system(struct task_struct *tsk);
extern void vtime_account_idle(struct task_struct *tsk);
extern void vtime_account_user(struct task_struct *tsk);

#ifdef __ARCH_HAS_VTIME_ACCOUNT
extern void vtime_account_irq_enter(struct task_struct *tsk);
#else
extern void vtime_common_account_irq_enter(struct task_struct *tsk);
static inline void vtime_account_irq_enter(struct task_struct *tsk)
{
if (vtime_accounting_cpu_enabled())
vtime_common_account_irq_enter(tsk);
}
#endif /* __ARCH_HAS_VTIME_ACCOUNT */

#else /* !CONFIG_VIRT_CPU_ACCOUNTING */

static inline void vtime_task_switch(struct task_struct *prev) { }
Expand All @@ -85,13 +86,8 @@ static inline void vtime_account_irq_enter(struct task_struct *tsk) { }

#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
extern void arch_vtime_task_switch(struct task_struct *tsk);
extern void vtime_gen_account_irq_exit(struct task_struct *tsk);

static inline void vtime_account_irq_exit(struct task_struct *tsk)
{
if (vtime_accounting_cpu_enabled())
vtime_gen_account_irq_exit(tsk);
}
static inline void vtime_account_irq_enter(struct task_struct *tsk) { }
static inline void vtime_account_irq_exit(struct task_struct *tsk) { }

extern void vtime_user_enter(struct task_struct *tsk);

Expand Down
6 changes: 3 additions & 3 deletions init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,11 @@ config VIRT_CPU_ACCOUNTING_GEN

If unsure, say N.

endchoice

config IRQ_TIME_ACCOUNTING
bool "Fine granularity task level IRQ time accounting"
depends on HAVE_IRQ_TIME_ACCOUNTING && !NO_HZ_FULL
depends on HAVE_IRQ_TIME_ACCOUNTING && !VIRT_CPU_ACCOUNTING_NATIVE
help
Select this option to enable fine granularity task irq time
accounting. This is done by reading a timestamp on each
Expand All @@ -386,8 +388,6 @@ config IRQ_TIME_ACCOUNTING

If in doubt, say N here.

endchoice

config BSD_PROCESS_ACCT
bool "BSD Process Accounting"
depends on MULTIUSER
Expand Down
16 changes: 3 additions & 13 deletions kernel/sched/cputime.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,14 +711,14 @@ static cputime_t vtime_delta(struct task_struct *tsk)
static cputime_t get_vtime_delta(struct task_struct *tsk)
{
unsigned long now = READ_ONCE(jiffies);
cputime_t delta, steal;
cputime_t delta, other;

delta = jiffies_to_cputime(now - tsk->vtime_snap);
steal = steal_account_process_time(delta);
other = account_other_time(delta);
WARN_ON_ONCE(tsk->vtime_snap_whence == VTIME_INACTIVE);
tsk->vtime_snap = now;

return delta - steal;
return delta - other;
}

static void __vtime_account_system(struct task_struct *tsk)
Expand All @@ -738,16 +738,6 @@ void vtime_account_system(struct task_struct *tsk)
write_seqcount_end(&tsk->vtime_seqcount);
}

void vtime_gen_account_irq_exit(struct task_struct *tsk)
{
write_seqcount_begin(&tsk->vtime_seqcount);
if (vtime_delta(tsk))
__vtime_account_system(tsk);
if (context_tracking_in_user())
tsk->vtime_snap_whence = VTIME_USER;
write_seqcount_end(&tsk->vtime_seqcount);
}

void vtime_account_user(struct task_struct *tsk)
{
cputime_t delta_cpu;
Expand Down

0 comments on commit b58c358

Please sign in to comment.