sched/cputime: Add vtime guest task state
authorFrederic Weisbecker <frederic@kernel.org>
Wed, 16 Oct 2019 02:56:49 +0000 (04:56 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 29 Oct 2019 09:01:11 +0000 (10:01 +0100)
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 <frederic@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rafael J . Wysocki <rjw@rjwysocki.net>
Cc: Rik van Riel <riel@surriel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Wanpeng Li <wanpengli@tencent.com>
Cc: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
Link: https://lkml.kernel.org/r/20191016025700.31277-4-frederic@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
include/linux/sched.h
kernel/sched/cputime.c

index 4ae19be2c1265d8a05ab09e6dfe94848543310ae..988c4da00c31404b33612c051b21200b87861294 100644 (file)
@@ -255,6 +255,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 {
index 2e885e870aa157ed9cdbc6aec736c09f733d805e..34086afc3518bb4f51425ff8515db5880c65fe9a 100644 (file)
@@ -733,7 +733,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);
@@ -788,6 +788,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);
@@ -799,6 +800,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);
@@ -826,6 +828,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();
@@ -860,7 +864,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));
@@ -898,13 +902,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 */