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