[PATCH RFC 2/2] sched/core: Defer preempted remote vCPU task clock updates
Dongli Zhang <[email protected]>
| Newsgroups | org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
A remote update of a runqueue can advance rq->clock while the owner vCPU is still preempted by the host. KVM publishes the matching stealtime when the vCPU is about to re-enter the guest, so the remote CPU can otherwise charge the stolen interval to rq->clock_task. Defer clock_task updates made by a remote CPU while the owner vCPU is reported preempted. Fold the deferred delta back into the next update that can proceed so IRQ and steal accounting process it together. This requires the hypervisor to publish up-to-date stealtime before clearing the preempted data. Assisted-by: Codex:GPT-5.5 Signed-off-by: Dongli Zhang <[email protected]> --- kernel/sched/core.c | 24 ++++++++++++++++++++++++ kernel/sched/sched.h | 1 + 2 files changed, 25 insertions(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f78275192036..56aa439182c7 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -816,6 +816,30 @@ static void update_rq_clock_task(struct rq *rq, s64 delta) */ s64 __maybe_unused steal = 0, irq_delta = 0; +#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING + if (static_key_false((¶virt_steal_rq_enabled))) { + int rq_cpu = cpu_of(rq); + + /* + * A remote CPU can update this rq before the owner vCPU + * has re-entered the guest and refreshed its stealtime + * state. Do not charge that elapsed time to the current + * task until stealtime can be sampled after the vCPU is + * no longer preempted. + */ + if (rq_cpu != raw_smp_processor_id() && + vcpu_is_preempted(rq_cpu)) { + rq->deferred_clock_task += delta; + return; + } + + if (rq->deferred_clock_task) { + delta += rq->deferred_clock_task; + rq->deferred_clock_task = 0; + } + } +#endif + #ifdef CONFIG_IRQ_TIME_ACCOUNTING if (irqtime_enabled()) { irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index e656c7059bf8..4fd00228afef 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1325,6 +1325,7 @@ struct rq { #endif #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING u64 prev_steal_time_rq; + u64 deferred_clock_task; #endif /* calc_load related fields */ -- 2.43.5