Re: [PATCH 6/5] KVM: x86: fix periodic lapic timer with hrtimers

From: Radim KrÄmÃÅ
Date: Wed Oct 26 2016 - 10:01:23 EST


2016-10-26 14:08+0800, Wanpeng Li:
> 2016-10-26 14:02 GMT+08:00 Wanpeng Li <kernellwp@xxxxxxxxx>:
>> 2016-10-25 19:43 GMT+08:00 Radim KrÄmÃÅ <rkrcmar@xxxxxxxxxx>:
>>> I will have some comments, because it would be nicer if it measured the
>>> latency ... expected_expiration is not computed correctly.
>>
>> It measured the latency from guest programs the clock event device to
>> interrupt injected to guest after timer fire.

No. It never computed the time when the timer fires, the test measured
the duration of the period.

Imagine that the dashed line below is a timeline. Pipe is idealized
firing of the periodic timer and caret is the time when the guest read
time in the interrupt. The number below caret is the latency.

The period is 7.

--------------------------------------------
| | | | | | |
^ ^ ^ ^ ^ ^ ^
1 2 3 1 2 1 1

The test would report "latencies" as:

1 1 1 -2 1 -1 0

because it used now() + period to compute the next expected expiration

Similarly in this case,
--------------------------------------------
| | | | | | |
^ ^ ^ ^ ^ ^
6 6 6 6 6 6

The latency is always 6, but the test would report

6 0 0 0 0 0

And if we improved the latency by 1, you'd only see the difference in
the first number. The test measured the duration of the period.

> When compare this with clock event device which is emulated by
> hrtimer, we can calculate the latency bonus from VMX preemption.

If we know when the timer should have fired, then we can measure the
latency:

latency = now() - expected_expiration

The hard part is computing expected_expiration() -- it *cannot* be
precise with one-shot or periodic APIC timer, because we don't send
expected_expiration to KVM, but only a delta and KVM sets
expected_expiration based on the delta and some random time when it gets
to set the expected_expiration.

The guest could do

before = now()
set_apic_timer(delta)
after = now()

to get some bounds on the expected expiration -- it would be between
"before + delta" and "after + delta".