Record guest as a VTIME state instead of guessing it from VTIME_SYS and
PF_VCPU. This is going to simplify the cputime read side especially as
its state machine is going to further expand in order to fully support
kcpustat on nohz_full.

Signed-off-by: Frederic Weisbecker <frede...@kernel.org>
Cc: Yauheni Kaliuta <yauheni.kali...@redhat.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Rik van Riel <r...@redhat.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Wanpeng Li <wanpen...@tencent.com>
Cc: Ingo Molnar <mi...@kernel.org>
---
 include/linux/sched.h  |  2 ++
 kernel/sched/cputime.c | 18 +++++++++++-------
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6d13938..d458d65 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -271,6 +271,8 @@ enum vtime_state {
        VTIME_SYS,
        /* Task runs in userspace in a CPU with VTIME active: */
        VTIME_USER,
+       /* Task runs as guests in a CPU with VTIME active: */
+       VTIME_GUEST,
 };
 
 struct vtime {
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index a9f42cc..f64afd7 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -732,7 +732,7 @@ static void __vtime_account_kernel(struct task_struct *tsk,
                                   struct vtime *vtime)
 {
        /* We might have scheduled out from guest path */
-       if (tsk->flags & PF_VCPU)
+       if (vtime->state == VTIME_GUEST)
                vtime_account_guest(tsk, vtime);
        else
                vtime_account_system(tsk, vtime);
@@ -787,6 +787,7 @@ void vtime_guest_enter(struct task_struct *tsk)
        write_seqcount_begin(&vtime->seqcount);
        vtime_account_system(tsk, vtime);
        tsk->flags |= PF_VCPU;
+       vtime->state = VTIME_GUEST;
        write_seqcount_end(&vtime->seqcount);
 }
 EXPORT_SYMBOL_GPL(vtime_guest_enter);
@@ -798,6 +799,7 @@ void vtime_guest_exit(struct task_struct *tsk)
        write_seqcount_begin(&vtime->seqcount);
        vtime_account_guest(tsk, vtime);
        tsk->flags &= ~PF_VCPU;
+       vtime->state = VTIME_SYS;
        write_seqcount_end(&vtime->seqcount);
 }
 EXPORT_SYMBOL_GPL(vtime_guest_exit);
@@ -825,6 +827,8 @@ void vtime_task_switch_generic(struct task_struct *prev)
        write_seqcount_begin(&vtime->seqcount);
        if (is_idle_task(current))
                vtime->state = VTIME_IDLE;
+       else if (current->flags & PF_VCPU)
+               vtime->state = VTIME_GUEST;
        else
                vtime->state = VTIME_SYS;
        vtime->starttime = sched_clock();
@@ -859,7 +863,7 @@ u64 task_gtime(struct task_struct *t)
                seq = read_seqcount_begin(&vtime->seqcount);
 
                gtime = t->gtime;
-               if (vtime->state == VTIME_SYS && t->flags & PF_VCPU)
+               if (vtime->state == VTIME_GUEST)
                        gtime += vtime->gtime + vtime_delta(vtime);
 
        } while (read_seqcount_retry(&vtime->seqcount, seq));
@@ -897,13 +901,13 @@ void task_cputime(struct task_struct *t, u64 *utime, u64 
*stime)
                delta = vtime_delta(vtime);
 
                /*
-                * Task runs either in user or kernel space, add pending nohz 
time to
-                * the right place.
+                * Task runs either in user (including guest) or kernel space,
+                * add pending nohz time to the right place.
                 */
-               if (vtime->state == VTIME_USER || t->flags & PF_VCPU)
-                       *utime += vtime->utime + delta;
-               else if (vtime->state == VTIME_SYS)
+               if (vtime->state == VTIME_SYS)
                        *stime += vtime->stime + delta;
+               else
+                       *utime += vtime->utime + delta;
        } while (read_seqcount_retry(&vtime->seqcount, seq));
 }
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */
-- 
2.7.4

Reply via email to