Commit 2da4c42c authored by Bibo Mao's avatar Bibo Mao Committed by Xianglai Li
Browse files

LoongArch: KVM: Start SW timer only when vcpu is blocking

mainline inclusion
from mainline-v6.9-rc1
commit 8bc15d02d5fdff31bfeca02e58e22e26880dde39
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9BTOX


CVE: NA

--------------------------------

SW timer is enabled when vcpu thread is scheduled out, and it is to wake
up vcpu from blocked queue. If vcpu thread is scheduled out but is not
blocked, such as it is preempted by other threads, it is not necessary
to enable SW timer. Since vcpu thread is still on running queue if it is
preempted and SW timer is only to wake up vcpu on blocking queue, so SW
timer is not useful in this situation.

This patch enables SW timer only when vcpu is scheduled out and is
blocking.

Signed-off-by: default avatarBibo Mao <maobibo@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 4fbd6d38
Loading
Loading
Loading
Loading
+9 −14
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
	/*
	 * Freeze the soft-timer and sync the guest stable timer with it.
	 */
	if (kvm_vcpu_is_blocking(vcpu))
		hrtimer_cancel(&vcpu->arch.swtimer);

	/*
@@ -168,26 +169,20 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu)
	 * Here judge one-shot timer fired by checking whether TVAL is larger
	 * than TCFG
	 */
	if (ticks < cfg) {
	if (ticks < cfg)
		delta = tick_to_ns(vcpu, ticks);
	else
		delta = 0;

	expire = ktime_add_ns(ktime_get(), delta);
	vcpu->arch.expire = expire;
	if (kvm_vcpu_is_blocking(vcpu)) {

		/*
		 * HRTIMER_MODE_PINNED is suggested since vcpu may run in
		 * the same physical cpu in next time
		 */
		hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
	} else if (vcpu->stat.generic.blocking) {
		/*
		 * Inject timer interrupt so that halt polling can dectect and exit.
		 * VCPU is scheduled out already and sleeps in rcuwait queue and
		 * will not poll pending events again. kvm_queue_irq() is not enough,
		 * hrtimer swtimer should be used here.
		 */
		expire = ktime_add_ns(ktime_get(), 10);
		vcpu->arch.expire = expire;
		hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
	}
}