Re: [PATCH 1/9] KVM: arm64: Document PV-time interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 7 Aug 2019, at 15:21, Steven Price <steven.price@xxxxxxx> wrote:

On 05/08/2019 17:40, Christophe de Dinechin wrote:

Steven Price writes:

Introduce a paravirtualization interface for KVM/arm64 based on the
"Arm Paravirtualized Time for Arm-Base Systems" specification DEN 0057A.

This only adds the details about "Stolen Time" as the details of "Live
Physical Time" have not been fully agreed.

[...]

+
+Stolen Time
+-----------
+
+The structure pointed to by the PV_TIME_ST hypercall is as follows:
+
+  Field       | Byte Length | Byte Offset | Description
+  ----------- | ----------- | ----------- | --------------------------
+  Revision    |      4      |      0      | Must be 0 for version 0.1
+  Attributes  |      4      |      4      | Must be 0
+  Stolen time |      8      |      8      | Stolen time in unsigned
+              |             |             | nanoseconds indicating how
+              |             |             | much time this VCPU thread
+              |             |             | was involuntarily not
+              |             |             | running on a physical CPU.

I know very little about the topic, but I don't understand how the spec
as proposed allows an accurate reading of the relation between physical
time and stolen time simultaneously. In other words, could you draw
Figure 1 of the spec from within the guest? Or is it a non-objective?

Figure 1 is mostly attempting to explain Live Physical Time (LPT), which
is not part of this patch series. But it does touch on stolen time by
the difference between "live physical time" and "virtual time".

I'm not sure what you mean by "from within the guest". From the
perspective of the guest the parts of the diagram where the guest isn't
running don't exist (therefore there are discontinuities in the
"physical time" and "live physical time" lines).

I meant: If I run code within the guest that attempts to draw Figure 1,
race conditions may cause the diagram actually drawn by your guest
program to look completely wrong on occasions.

This patch series doesn't attempt to provide the guest with a view of
"physical time" (or LPT) - but it might be able to observe that by
consulting something external (e.g. an NTP server, or an emulated RTC
which reports wall-clock time).

… with what appear to be like a built-in race condition, as you correctly
identified. I was wondering if the built-in race condition was deliberate
and/or necessary, or if it was irrelevant for the planned uses of the value.

What it does provide is a mechanism for obtaining the difference (as
reported by the host) between "live physical time" and "virtual time" -
this is reported in nanoseconds in the above structure.

For example, if you read the stolen time before you read CNTVCT_EL0,
isn't it possible for a lengthy event like a migration to occur between
the two reads, causing the stolen time to be obsolete and off by seconds?

"Lengthy events" like migration are represented by the "paused" state in
the diagram - i.e. it's the difference between "physical time" and "live
physical time". So stolen time doesn't attempt to represent that.

And yes, there is a race between reading CNTVCT_EL0 and reading stolen
time - but in practice this doesn't really matter. The usual pseudo-code
way of using stolen time is:

I’m assuming this is the guest scheduler you are talking about,
and I’m assuming virtualization can preempt that code anywhere.
Maybe that’s where I’m wrong?

For the sake of the argument, assume there is a 1s pause.
Not completely unreasonable in a migration scenario.

 * scheduler captures stolen time from structure and CNTVCT_EL0:
     before_timer = CNTVCT_EL0

[insert optional 1s pause here, case A]

     before_stolen = stolen
 * schedule in process
 * process is pre-empted (or blocked in some way)
 * scheduler captures stolen time from structure and CNTVCT_EL0:
     after_timer = CNTVCT_EL0

[insert optional 1s pause here, case B]

     after_stolen = stolen
     time = to_nsecs(after_timer - before_timer) -
            (after_stolen - before_stolen)

In case A, time is too big by one second. In case B, it is too small,
to the point where your code might need to be ready for
“time” unexpectedly showing up as negative.


The scheduler can then charge the process for "time" nanoseconds of
time. This ensures that a process isn't unfairly penalised if the host
doesn't schedule the VCPU while it is supposed to be running.

The race is very small in comparison to the time the process is running,
and in the worst case just means the process is charged slightly more
(or less) than it should be.

At this point, what I don’t understand is why the race would be
“very small” or why you would only be charged “slightly” more or less?

I guess if you're really worried about it, you could do a dance like:

do {
before = stolen
timer = CNTVCT_EL0
after = stolen
} while (before != after);

That will work as long as nothing in that loop requires something
that would cause `stolen` to jump. If there is such a guarantee,
then that’s even efficient, because in most cases the loop
would only run once, at the cost of one extra read and one test.

But I don't see the need to have such an accurate view of elapsed time
that the VCPU was scheduled. And of course at the moment (without this
series) the guest has no idea about time stolen by the host.

I’m certainly not arguing that exposing stolen time is a bad idea,
I’m only wondering if the proposed solution is racy, and if so, if
it is intentional.

If it’s indeed racy, the problem could be mitigated in a number of
ways

a) document your loop or something similar as being the recommended
way to avoid the race, and then ensure that the loop actually
will always work as intended. The upside is that it’s just a change in
some comments or documentation.

b) having a single interface that exposes multiple times. For example,
you could have a copy of CNTVCT_EL0 written alongside stolen time,
and then the scheduler could use that copy for its decision.


Thanks
Christophe
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux