Currently if a guest is live-migrated while it is actively using perf
counters, then after live-migrate it will notice that all counters would
suddenly start reporting 0s. This is due to the fact we are not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU registers
values but does not re-program the perf events so that the guest can seamlessly
use these counters even after live-migration like it was doing before
live-migration.
Instead there are two completely different code path between guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that the host pmu
events which were registered for the source instance and not present for
the destination instance. Thus passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary host pmu events
which are crucial for seamless guest experience across live migration.
In ordet to fix the situation, on first vcpu load we should restore
PMCR_EL0 in the same exact way like the guest was trying to access
these counters. And then we will also recreate the relevant host pmu
events.
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/pmu-emul.c | 10 ++++++++--
arch/arm64/kvm/pmu.c | 15 +++++++++++++++
include/kvm/arm_pmu.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
--
2.31.1
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-06-03 16:04:07
Hi Jinank,
On Thu, 03 Jun 2021 12:05:54 +0100,
Jinank Jain [off-list ref] wrote:
Currently if a guest is live-migrated while it is actively using perf
counters, then after live-migrate it will notice that all counters would
suddenly start reporting 0s. This is due to the fact we are not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU registers
values but does not re-program the perf events so that the guest can seamlessly
use these counters even after live-migration like it was doing before
live-migration.
Instead there are two completely different code path between guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that the host pmu
events which were registered for the source instance and not present for
the destination instance.
I can't parse this sentence. Do you mean "are not present"?
quoted hunk
Thus passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary host pmu events
which are crucial for seamless guest experience across live migration.
In ordet to fix the situation, on first vcpu load we should restore
PMCR_EL0 in the same exact way like the guest was trying to access
these counters. And then we will also recreate the relevant host pmu
events.
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/pmu-emul.c | 10 ++++++++--
arch/arm64/kvm/pmu.c | 15 +++++++++++++++
include/kvm/arm_pmu.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
@@ -408,6 +408,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)if(has_vhe())kvm_vcpu_load_sysregs_vhe(vcpu);kvm_arch_vcpu_load_fp(vcpu);+kvm_vcpu_pmu_restore(vcpu);
If this only needs to be run once per vcpu, why not trigger it from
kvm_arm_pmu_v3_enable(), which is also called once per vcpu?
This can done on the back of a request, saving most of the overhead
and not requiring any extra field. Essentially, something like the
(untested) patch below.
quoted hunk
kvm_vcpu_pmu_restore_guest(vcpu);
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
Why? There is no architectural guarantee that a counter resets to 0
without writing PMCR_EL0.C. And if you want the guest to continue
counting where it left off, resetting the counter is at best
counter-productive.
So I must be missing something...
kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0);
- if (val & ARMV8_PMU_PMCR_P) {
+ /*
+ * All the counters needs to reset in case of first vcpu load.
+ */
+ if (val & ARMV8_PMU_PMCR_P || !kvm_arm_pmu_v3_restored(vcpu)) {
Same thing here.
for_each_set_bit(i, &mask, 32)
kvm_pmu_set_counter_value(vcpu, i, 0);
}
The rest of the changes should be unnecessary with the patch below.
Thanks,
M.
From 1be188ab71867632a8c17384be6e55f47f42aa8b Mon Sep 17 00:00:00 2001
From: Marc Zyngier <maz@kernel.org>
Date: Thu, 3 Jun 2021 16:50:02 +0100
Subject: [PATCH] KVM: arm64: Restore PMU configuration on first run
Restoring a guest with an active virtual PMU results in no perf
counters being instanciated on the host side. Not quite what
you'd expect from a restore.
In order to fix this, force a writeback of PMCR_EL0 on the first
run of a vcpu (using a new request so that it happens once the
vcpu has been loaded). This will in turn create all the host-side
counters that were missing.
Reported-by: Jinank Jain <redacted>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 4 ++++
arch/arm64/kvm/pmu-emul.c | 3 +++
3 files changed, 8 insertions(+)
@@ -850,6 +850,9 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)return-EINVAL;}+/* One-off reload of the PMU on first run */+kvm_make_request(KVM_REQ_RELOAD_PMU,vcpu);+return0;}
--
2.30.2
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Thu, 2021-06-03 at 17:03 +0100, Marc Zyngier wrote:
CAUTION: This email originated from outside of the organization. Do
not click links or open attachments unless you can confirm the sender
and know the content is safe.
Hi Jinank,
On Thu, 03 Jun 2021 12:05:54 +0100,
Jinank Jain [off-list ref] wrote:
quoted
Currently if a guest is live-migrated while it is actively using
perf
counters, then after live-migrate it will notice that all counters
would
suddenly start reporting 0s. This is due to the fact we are not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using
KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU registers
values but does not re-program the perf events so that the guest
can seamlessly
use these counters even after live-migration like it was doing
before
live-migration.
Instead there are two completely different code path between guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that the
host pmu
events which were registered for the source instance and not
present for
the destination instance.
I can't parse this sentence. Do you mean "are not present"?
quoted
Thus passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary host pmu
events
which are crucial for seamless guest experience across live
migration.
In ordet to fix the situation, on first vcpu load we should restore
PMCR_EL0 in the same exact way like the guest was trying to access
these counters. And then we will also recreate the relevant host
pmu
events.
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/pmu-emul.c | 10 ++++++++--
arch/arm64/kvm/pmu.c | 15 +++++++++++++++
include/kvm/arm_pmu.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h
b/arch/arm64/include/asm/kvm_host.h
index 7cd7d5c8c4bc..2376ad3c2fc2 100644
int cpu)
if (has_vhe())
kvm_vcpu_load_sysregs_vhe(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
+ kvm_vcpu_pmu_restore(vcpu);
If this only needs to be run once per vcpu, why not trigger it from
kvm_arm_pmu_v3_enable(), which is also called once per vcpu?
This can done on the back of a request, saving most of the overhead
and not requiring any extra field. Essentially, something like the
(untested) patch below.
quoted
kvm_vcpu_pmu_restore_guest(vcpu);
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
*vcpu, u64 val)
kvm_pmu_disable_counter_mask(vcpu, mask);
}
- if (val & ARMV8_PMU_PMCR_C)
+ /*
+ * Cycle counter needs to reset in case of first vcpu load.
+ */
+ if (val & ARMV8_PMU_PMCR_C || !kvm_arm_pmu_v3_restored(vcpu))
Why? There is no architectural guarantee that a counter resets to 0
without writing PMCR_EL0.C. And if you want the guest to continue
counting where it left off, resetting the counter is at best
counter-productive.
Without this we would not be resetting PMU which is required for
creating host perf events. With the patch that you suggested we are
restoring PMCR_EL0 properly but still missing recreation of host perf
events. And without host perf events, guest would still zeros after
live migration. In my opinion we have two ways to fix it. We can fix it
inside the kernel or let userspace/VMM set those bits before restarting
the guest on the destination machine. What do you think?
quoted hunk
So I must be missing something...
quoted
kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX,
0);
- if (val & ARMV8_PMU_PMCR_P) {
+ /*
+ * All the counters needs to reset in case of first vcpu
load.
+ */
+ if (val & ARMV8_PMU_PMCR_P || !kvm_arm_pmu_v3_restored(vcpu))
{
Same thing here.
quoted
for_each_set_bit(i, &mask, 32)
kvm_pmu_set_counter_value(vcpu, i, 0);
}
The rest of the changes should be unnecessary with the patch below.
Thanks,
M.
From 1be188ab71867632a8c17384be6e55f47f42aa8b Mon Sep 17 00:00:00
2001
From: Marc Zyngier <maz@kernel.org>
Date: Thu, 3 Jun 2021 16:50:02 +0100
Subject: [PATCH] KVM: arm64: Restore PMU configuration on first run
Restoring a guest with an active virtual PMU results in no perf
counters being instanciated on the host side. Not quite what
you'd expect from a restore.
In order to fix this, force a writeback of PMCR_EL0 on the first
run of a vcpu (using a new request so that it happens once the
vcpu has been loaded). This will in turn create all the host-side
counters that were missing.
Reported-by: Jinank Jain <redacted>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 4 ++++
arch/arm64/kvm/pmu-emul.c | 3 +++
3 files changed, 8 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h
b/arch/arm64/include/asm/kvm_host.h
index 7cd7d5c8c4bc..6336b4309114 100644
@@ -850,6 +850,9 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)return-EINVAL;}+/* One-off reload of the PMU on first run */+kvm_make_request(KVM_REQ_RELOAD_PMU,vcpu);+return0;}--
2.30.2
--
Without deviation from the norm, progress is not possible.
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-06-07 16:47:58
On Mon, 07 Jun 2021 17:05:01 +0100,
"Jain, Jinank" [off-list ref] wrote:
On Thu, 2021-06-03 at 17:03 +0100, Marc Zyngier wrote:
quoted
Hi Jinank,
On Thu, 03 Jun 2021 12:05:54 +0100,
Jinank Jain [off-list ref] wrote:
quoted
Currently if a guest is live-migrated while it is actively using
perf
counters, then after live-migrate it will notice that all counters
would
suddenly start reporting 0s. This is due to the fact we are not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using
KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU registers
values but does not re-program the perf events so that the guest
can seamlessly
use these counters even after live-migration like it was doing
before
live-migration.
Instead there are two completely different code path between guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that the
host pmu
events which were registered for the source instance and not
present for
the destination instance.
I can't parse this sentence. Do you mean "are not present"?
quoted
Thus passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary host pmu
events
which are crucial for seamless guest experience across live
migration.
In ordet to fix the situation, on first vcpu load we should restore
PMCR_EL0 in the same exact way like the guest was trying to access
these counters. And then we will also recreate the relevant host
pmu
events.
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/pmu-emul.c | 10 ++++++++--
arch/arm64/kvm/pmu.c | 15 +++++++++++++++
include/kvm/arm_pmu.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h
b/arch/arm64/include/asm/kvm_host.h
index 7cd7d5c8c4bc..2376ad3c2fc2 100644
int cpu)
if (has_vhe())
kvm_vcpu_load_sysregs_vhe(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
+ kvm_vcpu_pmu_restore(vcpu);
If this only needs to be run once per vcpu, why not trigger it from
kvm_arm_pmu_v3_enable(), which is also called once per vcpu?
This can done on the back of a request, saving most of the overhead
and not requiring any extra field. Essentially, something like the
(untested) patch below.
quoted
kvm_vcpu_pmu_restore_guest(vcpu);
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
*vcpu, u64 val)
kvm_pmu_disable_counter_mask(vcpu, mask);
}
- if (val & ARMV8_PMU_PMCR_C)
+ /*
+ * Cycle counter needs to reset in case of first vcpu load.
+ */
+ if (val & ARMV8_PMU_PMCR_C || !kvm_arm_pmu_v3_restored(vcpu))
Why? There is no architectural guarantee that a counter resets to 0
without writing PMCR_EL0.C. And if you want the guest to continue
counting where it left off, resetting the counter is at best
counter-productive.
Without this we would not be resetting PMU which is required for
creating host perf events. With the patch that you suggested we are
restoring PMCR_EL0 properly but still missing recreation of host perf
events.
How? The request that gets set on the first vcpu run will call
kvm_pmu_handle_pmcr() -> kvm_pmu_enable_counter_mask() ->
kvm_pmu_create_perf_event(). What are we missing?
And without host perf events, guest would still zeros after live
migration. In my opinion we have two ways to fix it. We can fix it
inside the kernel or let userspace/VMM set those bits before
restarting the guest on the destination machine. What do you think?
I think either you're missing my point above, or I'm completely
missing yours. And I still don't understand why you want to zero the
counters that you have just restored. How does that help?
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Hi Marc.
On Mon, 2021-06-07 at 17:35 +0100, Marc Zyngier wrote:
CAUTION: This email originated from outside of the organization. Do
not click links or open attachments unless you can confirm the sender
and know the content is safe.
On Mon, 07 Jun 2021 17:05:01 +0100,
"Jain, Jinank" [off-list ref] wrote:
quoted
On Thu, 2021-06-03 at 17:03 +0100, Marc Zyngier wrote:
quoted
Hi Jinank,
On Thu, 03 Jun 2021 12:05:54 +0100,
Jinank Jain [off-list ref] wrote:
quoted
Currently if a guest is live-migrated while it is actively
using
perf
counters, then after live-migrate it will notice that all
counters
would
suddenly start reporting 0s. This is due to the fact we are not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using
KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU
registers
values but does not re-program the perf events so that the
guest
can seamlessly
use these counters even after live-migration like it was doing
before
live-migration.
Instead there are two completely different code path between
guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that the
host pmu
events which were registered for the source instance and not
present for
the destination instance.
I can't parse this sentence. Do you mean "are not present"?
quoted
Thus passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary host
pmu
events
which are crucial for seamless guest experience across live
migration.
In ordet to fix the situation, on first vcpu load we should
restore
PMCR_EL0 in the same exact way like the guest was trying to
access
these counters. And then we will also recreate the relevant
host
pmu
events.
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/pmu-emul.c | 10 ++++++++--
arch/arm64/kvm/pmu.c | 15 +++++++++++++++
include/kvm/arm_pmu.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h
b/arch/arm64/include/asm/kvm_host.h
index 7cd7d5c8c4bc..2376ad3c2fc2 100644
*vcpu,
int cpu)
if (has_vhe())
kvm_vcpu_load_sysregs_vhe(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
+ kvm_vcpu_pmu_restore(vcpu);
If this only needs to be run once per vcpu, why not trigger it
from
kvm_arm_pmu_v3_enable(), which is also called once per vcpu?
This can done on the back of a request, saving most of the
overhead
and not requiring any extra field. Essentially, something like
the
(untested) patch below.
quoted
kvm_vcpu_pmu_restore_guest(vcpu);
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
*vcpu, u64 val)
kvm_pmu_disable_counter_mask(vcpu, mask);
}
- if (val & ARMV8_PMU_PMCR_C)
+ /*
+ * Cycle counter needs to reset in case of first vcpu
load.
+ */
+ if (val & ARMV8_PMU_PMCR_C ||
!kvm_arm_pmu_v3_restored(vcpu))
Why? There is no architectural guarantee that a counter resets to
0
without writing PMCR_EL0.C. And if you want the guest to continue
counting where it left off, resetting the counter is at best
counter-productive.
Without this we would not be resetting PMU which is required for
creating host perf events. With the patch that you suggested we are
restoring PMCR_EL0 properly but still missing recreation of host
perf
events.
How? The request that gets set on the first vcpu run will call
kvm_pmu_handle_pmcr() -> kvm_pmu_enable_counter_mask() ->
kvm_pmu_create_perf_event(). What are we missing?
And without host perf events, guest would still zeros after live
migration. In my opinion we have two ways to fix it. We can fix it
inside the kernel or let userspace/VMM set those bits before
restarting the guest on the destination machine. What do you think?
I think either you're missing my point above, or I'm completely
missing yours. And I still don't understand why you want to zero the
counters that you have just restored. How does that help?
M.
--
Without deviation from the norm, progress is not possible.
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Currently if a guest is live-migrated while it is actively using perf
counters, then after live-migrate it will notice that all counters would
suddenly start reporting 0s. This is due to the fact we are not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU registers
values but does not re-program the perf events so that the guest can seamlessly
use these counters even after live-migration like it was doing before
live-migration.
Instead there are two completely different code path between guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that the host pmu
events which were registered for the source instance are not present for
the destination instance. Thus, passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary host pmu events
which are crucial for seamless guest experience across live migration.
In ordet to fix the situation, on first vcpu load we should restore
PMCR_EL0 in the same exact way like the guest was trying to access
these counters. And then we will also recreate the relevant host pmu
events.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 4 ++++
arch/arm64/kvm/pmu-emul.c | 3 +++
3 files changed, 8 insertions(+)
@@ -850,6 +850,9 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)return-EINVAL;}+/* One-off reload of the PMU on first run */+kvm_make_request(KVM_REQ_RELOAD_PMU,vcpu);+return0;}
--
2.31.1
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-06-08 08:18:52
On Mon, 07 Jun 2021 19:34:08 +0100,
"Jain, Jinank" [off-list ref] wrote:
Hi Marc.
On Mon, 2021-06-07 at 17:35 +0100, Marc Zyngier wrote:
quoted
CAUTION: This email originated from outside of the organization. Do
not click links or open attachments unless you can confirm the sender
and know the content is safe.
On Mon, 07 Jun 2021 17:05:01 +0100,
"Jain, Jinank" [off-list ref] wrote:
quoted
On Thu, 2021-06-03 at 17:03 +0100, Marc Zyngier wrote:
quoted
Hi Jinank,
On Thu, 03 Jun 2021 12:05:54 +0100,
Jinank Jain [off-list ref] wrote:
quoted
Currently if a guest is live-migrated while it is actively
using
perf
counters, then after live-migrate it will notice that all
counters
would
suddenly start reporting 0s. This is due to the fact we are not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using
KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU
registers
values but does not re-program the perf events so that the
guest
can seamlessly
use these counters even after live-migration like it was doing
before
live-migration.
Instead there are two completely different code path between
guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that the
host pmu
events which were registered for the source instance and not
present for
the destination instance.
I can't parse this sentence. Do you mean "are not present"?
quoted
Thus passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary host
pmu
events
which are crucial for seamless guest experience across live
migration.
In ordet to fix the situation, on first vcpu load we should
restore
PMCR_EL0 in the same exact way like the guest was trying to
access
these counters. And then we will also recreate the relevant
host
pmu
events.
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/pmu-emul.c | 10 ++++++++--
arch/arm64/kvm/pmu.c | 15 +++++++++++++++
include/kvm/arm_pmu.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h
b/arch/arm64/include/asm/kvm_host.h
index 7cd7d5c8c4bc..2376ad3c2fc2 100644
*vcpu,
int cpu)
if (has_vhe())
kvm_vcpu_load_sysregs_vhe(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
+ kvm_vcpu_pmu_restore(vcpu);
If this only needs to be run once per vcpu, why not trigger it
from
kvm_arm_pmu_v3_enable(), which is also called once per vcpu?
This can done on the back of a request, saving most of the
overhead
and not requiring any extra field. Essentially, something like
the
(untested) patch below.
quoted
kvm_vcpu_pmu_restore_guest(vcpu);
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
*vcpu, u64 val)
kvm_pmu_disable_counter_mask(vcpu, mask);
}
- if (val & ARMV8_PMU_PMCR_C)
+ /*
+ * Cycle counter needs to reset in case of first vcpu
load.
+ */
+ if (val & ARMV8_PMU_PMCR_C ||
!kvm_arm_pmu_v3_restored(vcpu))
Why? There is no architectural guarantee that a counter resets to
0
without writing PMCR_EL0.C. And if you want the guest to continue
counting where it left off, resetting the counter is at best
counter-productive.
Without this we would not be resetting PMU which is required for
creating host perf events. With the patch that you suggested we are
restoring PMCR_EL0 properly but still missing recreation of host
perf
events.
How? The request that gets set on the first vcpu run will call
kvm_pmu_handle_pmcr() -> kvm_pmu_enable_counter_mask() ->
kvm_pmu_create_perf_event(). What are we missing?
:-(
Please test whatever you send with an upstream kernel. Actually,
please *develop* on an upstream kernel. This will avoid this kind of
discussion where we talk past each other, and make it plain that your
production kernel is lacking all sorts of fixes.
Now, can you please state whether or not this patch fixes it for you
*on an upstream kernel*? I have no interest in results from a
production kernel.
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Tue, 2021-06-08 at 09:18 +0100, Marc Zyngier wrote:
CAUTION: This email originated from outside of the organization. Do
not click links or open attachments unless you can confirm the sender
and know the content is safe.
On Mon, 07 Jun 2021 19:34:08 +0100,
"Jain, Jinank" [off-list ref] wrote:
quoted
Hi Marc.
On Mon, 2021-06-07 at 17:35 +0100, Marc Zyngier wrote:
quoted
CAUTION: This email originated from outside of the organization.
Do
not click links or open attachments unless you can confirm the
sender
and know the content is safe.
On Mon, 07 Jun 2021 17:05:01 +0100,
"Jain, Jinank" [off-list ref] wrote:
quoted
On Thu, 2021-06-03 at 17:03 +0100, Marc Zyngier wrote:
quoted
Hi Jinank,
On Thu, 03 Jun 2021 12:05:54 +0100,
Jinank Jain [off-list ref] wrote:
quoted
Currently if a guest is live-migrated while it is actively
using
perf
counters, then after live-migrate it will notice that all
counters
would
suddenly start reporting 0s. This is due to the fact we are
not
re-creating the relevant perf events inside the kernel.
Usually on live-migration guest state is restored using
KVM_SET_ONE_REG
ioctl interface, which simply restores the value of PMU
registers
values but does not re-program the perf events so that the
guest
can seamlessly
use these counters even after live-migration like it was
doing
before
live-migration.
Instead there are two completely different code path
between
guest
accessing PMU registers and VMM restoring counters on
live-migration.
In case of KVM_SET_ONE_REG:
kvm_arm_set_reg()
...... kvm_arm_sys_reg_set_reg()
........... reg_from_user()
but in case when guest tries to access these counters:
handle_exit()
..... kvm_handle_sys_reg()
..........perform_access()
...............access_pmu_evcntr()
...................kvm_pmu_set_counter_value()
.......................kvm_pmu_create_perf_event()
The drawback of using the KVM_SET_ONE_REG interface is that
the
host pmu
events which were registered for the source instance and
not
present for
the destination instance.
I can't parse this sentence. Do you mean "are not present"?
quoted
Thus passively restoring PMCR_EL0 using
KVM_SET_ONE_REG interface would not create the necessary
host
pmu
events
which are crucial for seamless guest experience across live
migration.
In ordet to fix the situation, on first vcpu load we should
restore
PMCR_EL0 in the same exact way like the guest was trying to
access
these counters. And then we will also recreate the relevant
host
pmu
events.
Signed-off-by: Jinank Jain <redacted>
Cc: Alexander Graf (AWS) <redacted>
Cc: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Alexandru Elisei <redacted>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/pmu-emul.c | 10 ++++++++--
arch/arm64/kvm/pmu.c | 15 +++++++++++++++
include/kvm/arm_pmu.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h
b/arch/arm64/include/asm/kvm_host.h
index 7cd7d5c8c4bc..2376ad3c2fc2 100644
*vcpu,
int cpu)
if (has_vhe())
kvm_vcpu_load_sysregs_vhe(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
+ kvm_vcpu_pmu_restore(vcpu);
If this only needs to be run once per vcpu, why not trigger
it
from
kvm_arm_pmu_v3_enable(), which is also called once per vcpu?
This can done on the back of a request, saving most of the
overhead
and not requiring any extra field. Essentially, something
like
the
(untested) patch below.
quoted
kvm_vcpu_pmu_restore_guest(vcpu);
if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
diff --git a/arch/arm64/kvm/pmu-emul.c
b/arch/arm64/kvm/pmu-
emul.c
index fd167d4f4215..12a40f4b5f0d 100644
kvm_vcpu
*vcpu, u64 val)
kvm_pmu_disable_counter_mask(vcpu, mask);
}
- if (val & ARMV8_PMU_PMCR_C)
+ /*
+ * Cycle counter needs to reset in case of first vcpu
load.
+ */
+ if (val & ARMV8_PMU_PMCR_C ||
!kvm_arm_pmu_v3_restored(vcpu))
Why? There is no architectural guarantee that a counter
resets to
0
without writing PMCR_EL0.C. And if you want the guest to
continue
counting where it left off, resetting the counter is at best
counter-productive.
Without this we would not be resetting PMU which is required
for
creating host perf events. With the patch that you suggested we
are
restoring PMCR_EL0 properly but still missing recreation of
host
perf
events.
How? The request that gets set on the first vcpu run will call
kvm_pmu_handle_pmcr() -> kvm_pmu_enable_counter_mask() ->
kvm_pmu_create_perf_event(). What are we missing?
:-(
Please test whatever you send with an upstream kernel. Actually,
please *develop* on an upstream kernel. This will avoid this kind of
discussion where we talk past each other, and make it plain that your
production kernel is lacking all sorts of fixes.
Now, can you please state whether or not this patch fixes it for you
*on an upstream kernel*? I have no interest in results from a
production kernel.
M.
Really sorry for the noise and I can confirm that your suggested patch
fixes the problem for the upstream kernel i.e., if I live migrate a
guest which is actively using perf events then the guest can continue
using them even after live migration without interruption.
--
Without deviation from the norm, progress is not possible.
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel