Re: [PATCH v2] sched/cputime: add steal time support to full dynticks CPU time accounting

From: Mika PenttilÃ
Date: Wed May 18 2016 - 06:02:26 EST


On 05/18/2016 11:28 AM, Wanpeng Li wrote:
> From: Wanpeng Li <wanpeng.li@xxxxxxxxxxx>
>
> This patch adds steal guest time support to full dynticks CPU
> time accounting. After 'commit ff9a9b4c4334 ("sched, time: Switch
> VIRT_CPU_ACCOUNTING_GEN to jiffy granularity")', time is jiffy
> based sampling even if it's still listened to ring boundaries, so
> steal_account_process_tick() is reused to account how much 'ticks'
> are steal time after the last accumulation.
>
> Suggested-by: Rik van Riel <riel@xxxxxxxxxx>
> Cc: Ingo Molnar <mingo@xxxxxxxxxx>
> Cc: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
> Cc: Rik van Riel <riel@xxxxxxxxxx>
> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
> Cc: Radim <rkrcmar@xxxxxxxxxx>
> Signed-off-by: Wanpeng Li <wanpeng.li@xxxxxxxxxxx>
> ---
> v1 -> v2:
> * fix divide zero bug, thanks Rik
>
> kernel/sched/cputime.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
> index 75f98c5..bfa50a0 100644
> --- a/kernel/sched/cputime.c
> +++ b/kernel/sched/cputime.c
> @@ -257,7 +257,7 @@ void account_idle_time(cputime_t cputime)
> cpustat[CPUTIME_IDLE] += (__force u64) cputime;
> }
>
> -static __always_inline bool steal_account_process_tick(void)
> +static __always_inline unsigned long steal_account_process_tick(void)
> {
> #ifdef CONFIG_PARAVIRT
> if (static_key_false(&paravirt_steal_enabled)) {
> @@ -279,7 +279,7 @@ static __always_inline bool steal_account_process_tick(void)
> return steal_jiffies;
> }
> #endif
> - return false;
> + return 0;
> }
>
> /*
> @@ -691,8 +691,12 @@ static cputime_t get_vtime_delta(struct task_struct *tsk)
>
> static void __vtime_account_system(struct task_struct *tsk)
> {
> + unsigned long steal_time = steal_account_process_tick();
> cputime_t delta_cpu = get_vtime_delta(tsk);
>
> + if (steal_time >= delta_cpu)
> + return;
> + delta_cpu -= steal_time;
> account_system_time(tsk, irq_count(), delta_cpu, cputime_to_scaled(delta_cpu));
> }
>
> @@ -723,7 +727,12 @@ void vtime_account_user(struct task_struct *tsk)
> write_seqcount_begin(&tsk->vtime_seqcount);
> tsk->vtime_snap_whence = VTIME_SYS;
> if (vtime_delta(tsk)) {
> + unsigned long steal_time = steal_account_process_tick();
> delta_cpu = get_vtime_delta(tsk);


afaik steal_account_process_tick() returns jiffies and get_vtime_delta() cputime, so can't mix them like this : ?

> +
> + if (steal_time >= delta_cpu)
> + return;



> + delta_cpu -= steal_time;
> account_user_time(tsk, delta_cpu, cputime_to_scaled(delta_cpu));
> }
> write_seqcount_end(&tsk->vtime_seqcount);
>


--Mika