From: Marc Zyngier <hidden> Date: 2017-01-29 11:54:31
On Fri, Jan 27 2017 at 01:04:52 AM, Jintack Lim [off-list ref] wrote:
quoted hunk
Make cntvoff per each timer context. This is helpful to abstract kvm
timer functions to work with timer context without considering timer
types (e.g. physical timer or virtual timer).
This also would pave the way for ever doing adjustments of the cntvoff
on a per-CPU basis if that should ever make sense.
Signed-off-by: Jintack Lim <redacted>
---
arch/arm/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_host.h | 4 ++--
include/kvm/arm_arch_timer.h | 8 +++-----
virt/kvm/arm/arch_timer.c | 26 ++++++++++++++++++++------
virt/kvm/arm/hyp/timer-sr.c | 3 +--
5 files changed, 29 insertions(+), 18 deletions(-)
@@ -60,9 +60,6 @@ struct kvm_arch {/* The last vcpu id that ran on each physical CPU */int__percpu*last_vcpu_ran;-/* Timer */-structarch_timer_kvmtimer;-/**Anythingthatisnotuseddirectlyfromassemblycodegoes*here.
@@ -75,6 +72,9 @@ struct kvm_arch {/* Stage-2 page table */pgd_t*pgd;+/* A lock to synchronize cntvoff among all vtimer context of vcpus */+spinlock_tcntvoff_lock;
Is there any condition where we need this to be a spinlock? I would have
thought that a mutex should have been enough, as this should only be
updated on migration or initialization. Not that it matters much in this
case, but I wondered if there is something I'm missing.
quoted hunk
+
/* Interrupt controller */
struct vgic_dist vgic;
int max_vcpus;
@@ -353,10 +354,23 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,return0;}+/* Make the updates of cntvoff for all vtimer contexts atomic */+staticvoidupdate_vtimer_cntvoff(structkvm_vcpu*vcpu,u64cntvoff)
Arguably, this acts on the VM itself and not a single vcpu. maybe you
should consider passing the struct kvm pointer to reflect this.
Maybe a comment indicating that we recompute CNTVOFF for all vcpus would
be welcome (this is not a change in semantics, but it was never obvious
in the existing code).
From: Christoffer Dall <hidden> Date: 2017-01-30 14:46:01
On Sun, Jan 29, 2017 at 11:54:05AM +0000, Marc Zyngier wrote:
On Fri, Jan 27 2017 at 01:04:52 AM, Jintack Lim [off-list ref] wrote:
quoted
Make cntvoff per each timer context. This is helpful to abstract kvm
timer functions to work with timer context without considering timer
types (e.g. physical timer or virtual timer).
This also would pave the way for ever doing adjustments of the cntvoff
on a per-CPU basis if that should ever make sense.
Signed-off-by: Jintack Lim <redacted>
---
arch/arm/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_host.h | 4 ++--
include/kvm/arm_arch_timer.h | 8 +++-----
virt/kvm/arm/arch_timer.c | 26 ++++++++++++++++++++------
virt/kvm/arm/hyp/timer-sr.c | 3 +--
5 files changed, 29 insertions(+), 18 deletions(-)
@@ -60,9 +60,6 @@ struct kvm_arch {/* The last vcpu id that ran on each physical CPU */int__percpu*last_vcpu_ran;-/* Timer */-structarch_timer_kvmtimer;-/**Anythingthatisnotuseddirectlyfromassemblycodegoes*here.
@@ -75,6 +72,9 @@ struct kvm_arch {/* Stage-2 page table */pgd_t*pgd;+/* A lock to synchronize cntvoff among all vtimer context of vcpus */+spinlock_tcntvoff_lock;
Is there any condition where we need this to be a spinlock? I would have
thought that a mutex should have been enough, as this should only be
updated on migration or initialization. Not that it matters much in this
case, but I wondered if there is something I'm missing.
I would think the critical section is small enough that a spinlock makes
sense, but what I don't think we need is to add the additional lock.
I think just taking the kvm->lock should be sufficient, which happens to
be a mutex, and while that may be a bit slower to take than the
spinlock, it's not in the critical path so let's just keep things
simple.
Perhaps this what Marc also meant.
quoted
+
/* Interrupt controller */
struct vgic_dist vgic;
int max_vcpus;
@@ -353,10 +354,23 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,return0;}+/* Make the updates of cntvoff for all vtimer contexts atomic */+staticvoidupdate_vtimer_cntvoff(structkvm_vcpu*vcpu,u64cntvoff)
Arguably, this acts on the VM itself and not a single vcpu. maybe you
should consider passing the struct kvm pointer to reflect this.
Maybe a comment indicating that we recompute CNTVOFF for all vcpus would
be welcome (this is not a change in semantics, but it was never obvious
in the existing code).
From: Marc Zyngier <hidden> Date: 2017-01-30 14:59:00
On 30/01/17 14:45, Christoffer Dall wrote:
On Sun, Jan 29, 2017 at 11:54:05AM +0000, Marc Zyngier wrote:
quoted
On Fri, Jan 27 2017 at 01:04:52 AM, Jintack Lim [off-list ref] wrote:
quoted
Make cntvoff per each timer context. This is helpful to abstract kvm
timer functions to work with timer context without considering timer
types (e.g. physical timer or virtual timer).
This also would pave the way for ever doing adjustments of the cntvoff
on a per-CPU basis if that should ever make sense.
Signed-off-by: Jintack Lim <redacted>
---
arch/arm/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_host.h | 4 ++--
include/kvm/arm_arch_timer.h | 8 +++-----
virt/kvm/arm/arch_timer.c | 26 ++++++++++++++++++++------
virt/kvm/arm/hyp/timer-sr.c | 3 +--
5 files changed, 29 insertions(+), 18 deletions(-)
@@ -60,9 +60,6 @@ struct kvm_arch {/* The last vcpu id that ran on each physical CPU */int__percpu*last_vcpu_ran;-/* Timer */-structarch_timer_kvmtimer;-/**Anythingthatisnotuseddirectlyfromassemblycodegoes*here.
@@ -75,6 +72,9 @@ struct kvm_arch {/* Stage-2 page table */pgd_t*pgd;+/* A lock to synchronize cntvoff among all vtimer context of vcpus */+spinlock_tcntvoff_lock;
Is there any condition where we need this to be a spinlock? I would have
thought that a mutex should have been enough, as this should only be
updated on migration or initialization. Not that it matters much in this
case, but I wondered if there is something I'm missing.
I would think the critical section is small enough that a spinlock makes
sense, but what I don't think we need is to add the additional lock.
I think just taking the kvm->lock should be sufficient, which happens to
be a mutex, and while that may be a bit slower to take than the
spinlock, it's not in the critical path so let's just keep things
simple.
Perhaps this what Marc also meant.
That would be the logical conclusion, assuming that we can sleep on this
path.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
On Mon, Jan 30, 2017 at 9:51 AM, Marc Zyngier [off-list ref] wrote:
On 30/01/17 14:45, Christoffer Dall wrote:
quoted
On Sun, Jan 29, 2017 at 11:54:05AM +0000, Marc Zyngier wrote:
quoted
On Fri, Jan 27 2017 at 01:04:52 AM, Jintack Lim [off-list ref] wrote:
quoted
Make cntvoff per each timer context. This is helpful to abstract kvm
timer functions to work with timer context without considering timer
types (e.g. physical timer or virtual timer).
This also would pave the way for ever doing adjustments of the cntvoff
on a per-CPU basis if that should ever make sense.
Signed-off-by: Jintack Lim <redacted>
---
arch/arm/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_host.h | 4 ++--
include/kvm/arm_arch_timer.h | 8 +++-----
virt/kvm/arm/arch_timer.c | 26 ++++++++++++++++++++------
virt/kvm/arm/hyp/timer-sr.c | 3 +--
5 files changed, 29 insertions(+), 18 deletions(-)
@@ -60,9 +60,6 @@ struct kvm_arch {/* The last vcpu id that ran on each physical CPU */int__percpu*last_vcpu_ran;-/* Timer */-structarch_timer_kvmtimer;-/**Anythingthatisnotuseddirectlyfromassemblycodegoes*here.
@@ -75,6 +72,9 @@ struct kvm_arch {/* Stage-2 page table */pgd_t*pgd;+/* A lock to synchronize cntvoff among all vtimer context of vcpus */+spinlock_tcntvoff_lock;
Is there any condition where we need this to be a spinlock? I would have
thought that a mutex should have been enough, as this should only be
updated on migration or initialization. Not that it matters much in this
case, but I wondered if there is something I'm missing.
I would think the critical section is small enough that a spinlock makes
sense, but what I don't think we need is to add the additional lock.
I think just taking the kvm->lock should be sufficient, which happens to
be a mutex, and while that may be a bit slower to take than the
spinlock, it's not in the critical path so let's just keep things
simple.
Perhaps this what Marc also meant.
That would be the logical conclusion, assuming that we can sleep on this
path.
All right. I'll take kvm->lock there.
Thanks,
Jintack
Thanks,
M.
--
Jazz is not dead. It just smells funny...
From: Marc Zyngier <hidden> Date: 2017-01-30 18:07:28
On 30/01/17 17:58, Jintack Lim wrote:
On Sun, Jan 29, 2017 at 6:54 AM, Marc Zyngier [off-list ref] wrote:
quoted
On Fri, Jan 27 2017 at 01:04:52 AM, Jintack Lim [off-list ref] wrote:
quoted
Make cntvoff per each timer context. This is helpful to abstract kvm
timer functions to work with timer context without considering timer
types (e.g. physical timer or virtual timer).
This also would pave the way for ever doing adjustments of the cntvoff
on a per-CPU basis if that should ever make sense.
Signed-off-by: Jintack Lim <redacted>
---
arch/arm/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_host.h | 4 ++--
include/kvm/arm_arch_timer.h | 8 +++-----
virt/kvm/arm/arch_timer.c | 26 ++++++++++++++++++++------
virt/kvm/arm/hyp/timer-sr.c | 3 +--
5 files changed, 29 insertions(+), 18 deletions(-)
@@ -60,9 +60,6 @@ struct kvm_arch {/* The last vcpu id that ran on each physical CPU */int__percpu*last_vcpu_ran;-/* Timer */-structarch_timer_kvmtimer;-/**Anythingthatisnotuseddirectlyfromassemblycodegoes*here.
@@ -75,6 +72,9 @@ struct kvm_arch {/* Stage-2 page table */pgd_t*pgd;+/* A lock to synchronize cntvoff among all vtimer context of vcpus */+spinlock_tcntvoff_lock;
Is there any condition where we need this to be a spinlock? I would have
thought that a mutex should have been enough, as this should only be
updated on migration or initialization. Not that it matters much in this
case, but I wondered if there is something I'm missing.
quoted
+
/* Interrupt controller */
struct vgic_dist vgic;
int max_vcpus;
@@ -353,10 +354,23 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,return0;}+/* Make the updates of cntvoff for all vtimer contexts atomic */+staticvoidupdate_vtimer_cntvoff(structkvm_vcpu*vcpu,u64cntvoff)
Arguably, this acts on the VM itself and not a single vcpu. maybe you
should consider passing the struct kvm pointer to reflect this.
Maybe a comment indicating that we recompute CNTVOFF for all vcpus would
be welcome (this is not a change in semantics, but it was never obvious
in the existing code).
I'll add a comment. In fact, I was told to make cntvoff synchronized
across all the vcpus, but I'm afraid that I understand why. Could you
explain me where this constraint comes from?
The virtual counter is the only one a guest can rely on (as the physical
one is disabled). So we must present to the guest a view of time that is
uniform across CPUs. If we allow CNTVOFF to vary across CPUs, time
starts fluctuating when we migrate a process from a vcpu to another, and
Linux gets *really* unhappy.
An easy fix for this is to make CNTVOFF a VM-global value, ensuring that
all the CPUs see the same counter values at the same time.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
On Sun, Jan 29, 2017 at 6:54 AM, Marc Zyngier [off-list ref] wrote:
On Fri, Jan 27 2017 at 01:04:52 AM, Jintack Lim [off-list ref] wrote:
quoted
Make cntvoff per each timer context. This is helpful to abstract kvm
timer functions to work with timer context without considering timer
types (e.g. physical timer or virtual timer).
This also would pave the way for ever doing adjustments of the cntvoff
on a per-CPU basis if that should ever make sense.
Signed-off-by: Jintack Lim <redacted>
---
arch/arm/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_host.h | 4 ++--
include/kvm/arm_arch_timer.h | 8 +++-----
virt/kvm/arm/arch_timer.c | 26 ++++++++++++++++++++------
virt/kvm/arm/hyp/timer-sr.c | 3 +--
5 files changed, 29 insertions(+), 18 deletions(-)
@@ -60,9 +60,6 @@ struct kvm_arch {/* The last vcpu id that ran on each physical CPU */int__percpu*last_vcpu_ran;-/* Timer */-structarch_timer_kvmtimer;-/**Anythingthatisnotuseddirectlyfromassemblycodegoes*here.
@@ -75,6 +72,9 @@ struct kvm_arch {/* Stage-2 page table */pgd_t*pgd;+/* A lock to synchronize cntvoff among all vtimer context of vcpus */+spinlock_tcntvoff_lock;
Is there any condition where we need this to be a spinlock? I would have
thought that a mutex should have been enough, as this should only be
updated on migration or initialization. Not that it matters much in this
case, but I wondered if there is something I'm missing.
quoted
+
/* Interrupt controller */
struct vgic_dist vgic;
int max_vcpus;
@@ -353,10 +354,23 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,return0;}+/* Make the updates of cntvoff for all vtimer contexts atomic */+staticvoidupdate_vtimer_cntvoff(structkvm_vcpu*vcpu,u64cntvoff)
Arguably, this acts on the VM itself and not a single vcpu. maybe you
should consider passing the struct kvm pointer to reflect this.
Maybe a comment indicating that we recompute CNTVOFF for all vcpus would
be welcome (this is not a change in semantics, but it was never obvious
in the existing code).
I'll add a comment. In fact, I was told to make cntvoff synchronized
across all the vcpus, but I'm afraid that I understand why. Could you
explain me where this constraint comes from?
On Mon, Jan 30, 2017 at 1:05 PM, Marc Zyngier [off-list ref] wrote:
On 30/01/17 17:58, Jintack Lim wrote:
quoted
On Sun, Jan 29, 2017 at 6:54 AM, Marc Zyngier [off-list ref] wrote:
quoted
On Fri, Jan 27 2017 at 01:04:52 AM, Jintack Lim [off-list ref] wrote:
quoted
Make cntvoff per each timer context. This is helpful to abstract kvm
timer functions to work with timer context without considering timer
types (e.g. physical timer or virtual timer).
This also would pave the way for ever doing adjustments of the cntvoff
on a per-CPU basis if that should ever make sense.
Signed-off-by: Jintack Lim <redacted>
---
arch/arm/include/asm/kvm_host.h | 6 +++---
arch/arm64/include/asm/kvm_host.h | 4 ++--
include/kvm/arm_arch_timer.h | 8 +++-----
virt/kvm/arm/arch_timer.c | 26 ++++++++++++++++++++------
virt/kvm/arm/hyp/timer-sr.c | 3 +--
5 files changed, 29 insertions(+), 18 deletions(-)
@@ -60,9 +60,6 @@ struct kvm_arch {/* The last vcpu id that ran on each physical CPU */int__percpu*last_vcpu_ran;-/* Timer */-structarch_timer_kvmtimer;-/**Anythingthatisnotuseddirectlyfromassemblycodegoes*here.
@@ -75,6 +72,9 @@ struct kvm_arch {/* Stage-2 page table */pgd_t*pgd;+/* A lock to synchronize cntvoff among all vtimer context of vcpus */+spinlock_tcntvoff_lock;
Is there any condition where we need this to be a spinlock? I would have
thought that a mutex should have been enough, as this should only be
updated on migration or initialization. Not that it matters much in this
case, but I wondered if there is something I'm missing.
quoted
+
/* Interrupt controller */
struct vgic_dist vgic;
int max_vcpus;
@@ -353,10 +354,23 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,return0;}+/* Make the updates of cntvoff for all vtimer contexts atomic */+staticvoidupdate_vtimer_cntvoff(structkvm_vcpu*vcpu,u64cntvoff)
Arguably, this acts on the VM itself and not a single vcpu. maybe you
should consider passing the struct kvm pointer to reflect this.
Maybe a comment indicating that we recompute CNTVOFF for all vcpus would
be welcome (this is not a change in semantics, but it was never obvious
in the existing code).
I'll add a comment. In fact, I was told to make cntvoff synchronized
across all the vcpus, but I'm afraid that I understand why. Could you
explain me where this constraint comes from?
The virtual counter is the only one a guest can rely on (as the physical
one is disabled). So we must present to the guest a view of time that is
uniform across CPUs. If we allow CNTVOFF to vary across CPUs, time
starts fluctuating when we migrate a process from a vcpu to another, and
Linux gets *really* unhappy.
Ah, that makes sense to me. Thanks a lot.
An easy fix for this is to make CNTVOFF a VM-global value, ensuring that
all the CPUs see the same counter values at the same time.
Thanks,
M.
--
Jazz is not dead. It just smells funny...