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.
Unified · Split
| @@ -255,6 +255,8 @@ enum vtime_state { · 254 unmodified lines | ||
| 255 | 255 | VTIME_SYS, |
| 256 | 256 | /* Task runs in userspace in a CPU with VTIME active: */ |
| 257 | 257 | VTIME_USER, |
| 258 | + /* Task runs as guests in a CPU with VTIME active: */ | |
| 259 | + VTIME_GUEST, | |
| 258 | 260 | }; |
| 259 | 261 | |
| 260 | 262 | struct vtime { |
| @@ -733,7 +733,7 @@ static void __vtime_account_kernel(struct task_struct *tsk, · 732 unmodified lines | ||
| 733 | 733 | struct vtime *vtime) |
| 734 | 734 | { |
| 735 | 735 | /* We might have scheduled out from guest path */ |
| 736 | − if (tsk->flags & PF_VCPU) | |
| 736 | + if (vtime->state == VTIME_GUEST) | |
| 737 | 737 | vtime_account_guest(tsk, vtime); |
| 738 | 738 | else |
| 739 | 739 | vtime_account_system(tsk, vtime); |
| @@ -788,6 +788,7 @@ void vtime_guest_enter(struct task_struct *tsk) · 48 unmodified lines | ||
| 788 | 788 | write_seqcount_begin(&vtime->seqcount); |
| 789 | 789 | vtime_account_system(tsk, vtime); |
| 790 | 790 | tsk->flags |= PF_VCPU; |
| 791 | + vtime->state = VTIME_GUEST; | |
| 791 | 792 | write_seqcount_end(&vtime->seqcount); |
| 792 | 793 | } |
| 793 | 794 | EXPORT_SYMBOL_GPL(vtime_guest_enter); |
| @@ -799,6 +800,7 @@ void vtime_guest_exit(struct task_struct *tsk) · 5 unmodified lines | ||
| 799 | 800 | write_seqcount_begin(&vtime->seqcount); |
| 800 | 801 | vtime_account_guest(tsk, vtime); |
| 801 | 802 | tsk->flags &= ~PF_VCPU; |
| 803 | + vtime->state = VTIME_SYS; | |
| 802 | 804 | write_seqcount_end(&vtime->seqcount); |
| 803 | 805 | } |
| 804 | 806 | EXPORT_SYMBOL_GPL(vtime_guest_exit); |
| @@ -826,6 +828,8 @@ void vtime_task_switch_generic(struct task_struct *prev) · 21 unmodified lines | ||
| 826 | 828 | write_seqcount_begin(&vtime->seqcount); |
| 827 | 829 | if (is_idle_task(current)) |
| 828 | 830 | vtime->state = VTIME_IDLE; |
| 831 | + else if (current->flags & PF_VCPU) | |
| 832 | + vtime->state = VTIME_GUEST; | |
| 829 | 833 | else |
| 830 | 834 | vtime->state = VTIME_SYS; |
| 831 | 835 | vtime->starttime = sched_clock(); |
| @@ -860,7 +864,7 @@ u64 task_gtime(struct task_struct *t) · 28 unmodified lines | ||
| 860 | 864 | seq = read_seqcount_begin(&vtime->seqcount); |
| 861 | 865 | |
| 862 | 866 | gtime = t->gtime; |
| 863 | − if (vtime->state == VTIME_SYS && t->flags & PF_VCPU) | |
| 867 | + if (vtime->state == VTIME_GUEST) | |
| 864 | 868 | gtime += vtime->gtime + vtime_delta(vtime); |
| 865 | 869 | |
| 866 | 870 | } while (read_seqcount_retry(&vtime->seqcount, seq)); |
| @@ -898,13 +902,13 @@ void task_cputime(struct task_struct *t, u64 *utime, u64 *stime) · 31 unmodified lines | ||
| 898 | 902 | delta = vtime_delta(vtime); |
| 899 | 903 | |
| 900 | 904 | /* |
| 901 | − * Task runs either in user or kernel space, add pending nohz time to | |
| 902 | − * the right place. | |
| 905 | + * Task runs either in user (including guest) or kernel space, | |
| 906 | + * add pending nohz time to the right place. | |
| 903 | 907 | */ |
| 904 | − if (vtime->state == VTIME_USER || t->flags & PF_VCPU) | |
| 905 | − *utime += vtime->utime + delta; | |
| 906 | − else if (vtime->state == VTIME_SYS) | |
| 908 | + if (vtime->state == VTIME_SYS) | |
| 907 | 909 | *stime += vtime->stime + delta; |
| 910 | + else | |
| 911 | + *utime += vtime->utime + delta; | |
| 908 | 912 | } while (read_seqcount_retry(&vtime->seqcount, seq)); |
| 909 | 913 | } |
| 910 | 914 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ |