2021-11-16 16:35:04

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v2 0/6] KVM: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS and re-purpose it on x86

Changes since v1:
- PATCH6 for s390 added.
- On ARM64, do not make KVM_CAP_NR_VCPUS return value dependent on whether
it is a system-wide ioctl or a per-VM one [Marc Zyngier].

Original description:

This is a continuation of "KVM: x86: Drop arbitraty KVM_SOFT_MAX_VCPUS"
(https://lore.kernel.org/kvm/[email protected]/)
work.

1) Enforce KVM_CAP_NR_VCPUS <= KVM_CAP_MAX_VCPUS rule on all
architectures. [Sean Christopherson]
2) Make KVM_CAP_NR_VCPUS return num_online_cpus() and not an arbitrary
value of '710' on x86.

Everything but x86 was only 'eyeball tested', the change is trivial
but sorry in advance if I screwed up)

Vitaly Kuznetsov (6):
KVM: arm64: Cap KVM_CAP_NR_VCPUS by kvm_arm_default_max_vcpus()
KVM: MIPS: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS
KVM: PPC: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS
KVM: RISC-V: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS
KVM: s390: Cap KVM_CAP_NR_VCPUS by num_online_cpus()
KVM: x86: Drop arbitraty KVM_SOFT_MAX_VCPUS

arch/arm64/kvm/arm.c | 9 ++++++++-
arch/mips/kvm/mips.c | 2 +-
arch/powerpc/kvm/powerpc.c | 4 ++--
arch/riscv/kvm/vm.c | 2 +-
arch/s390/kvm/kvm-s390.c | 2 ++
arch/x86/include/asm/kvm_host.h | 1 -
arch/x86/kvm/x86.c | 2 +-
7 files changed, 15 insertions(+), 7 deletions(-)

--
2.33.1



2021-11-16 16:35:30

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v2 1/6] KVM: arm64: Cap KVM_CAP_NR_VCPUS by kvm_arm_default_max_vcpus()

Generally, it doesn't make sense to return the recommended maximum number
of vCPUs which exceeds the maximum possible number of vCPUs.

Note: ARM64 is special as the value returned by KVM_CAP_MAX_VCPUS differs
depending on whether it is a system-wide ioctl or a per-VM one. Previously,
KVM_CAP_NR_VCPUS didn't have this difference and it seems preferable to
keep the status quo. Cap KVM_CAP_NR_VCPUS by kvm_arm_default_max_vcpus()
which is what gets returned by system-wide KVM_CAP_MAX_VCPUS.

Signed-off-by: Vitaly Kuznetsov <[email protected]>
---
arch/arm64/kvm/arm.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 7838e9fb693e..0690c76def5d 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -223,7 +223,14 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = 1;
break;
case KVM_CAP_NR_VCPUS:
- r = num_online_cpus();
+ /*
+ * ARM64 treats KVM_CAP_NR_CPUS differently from all other
+ * architectures, as it does not always bound it to
+ * num_online_cpus(). It should not matter much because this
+ * is just an advisory value.
+ */
+ r = min_t(unsigned int, num_online_cpus(),
+ kvm_arm_default_max_vcpus());
break;
case KVM_CAP_MAX_VCPUS:
case KVM_CAP_MAX_VCPU_ID:
--
2.33.1


2021-11-16 16:35:38

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v2 2/6] KVM: MIPS: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS

It doesn't make sense to return the recommended maximum number of
vCPUs which exceeds the maximum possible number of vCPUs.

Signed-off-by: Vitaly Kuznetsov <[email protected]>
---
arch/mips/kvm/mips.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 562aa878b266..aa20d074d388 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -1067,7 +1067,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = 1;
break;
case KVM_CAP_NR_VCPUS:
- r = num_online_cpus();
+ r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
break;
case KVM_CAP_MAX_VCPUS:
r = KVM_MAX_VCPUS;
--
2.33.1


2021-11-16 16:35:52

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v2 3/6] KVM: PPC: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS

It doesn't make sense to return the recommended maximum number of
vCPUs which exceeds the maximum possible number of vCPUs.

Signed-off-by: Vitaly Kuznetsov <[email protected]>
---
arch/powerpc/kvm/powerpc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 8ab90ce8738f..ccac8d5686ff 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -641,9 +641,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
* implementations just count online CPUs.
*/
if (hv_enabled)
- r = num_present_cpus();
+ r = min_t(unsigned int, num_present_cpus(), KVM_MAX_VCPUS);
else
- r = num_online_cpus();
+ r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
break;
case KVM_CAP_MAX_VCPUS:
r = KVM_MAX_VCPUS;
--
2.33.1


2021-11-16 16:35:57

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v2 4/6] KVM: RISC-V: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS

It doesn't make sense to return the recommended maximum number of
vCPUs which exceeds the maximum possible number of vCPUs.

Signed-off-by: Vitaly Kuznetsov <[email protected]>
---
arch/riscv/kvm/vm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c
index 26399df15b63..fb18af34a4b5 100644
--- a/arch/riscv/kvm/vm.c
+++ b/arch/riscv/kvm/vm.c
@@ -74,7 +74,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = 1;
break;
case KVM_CAP_NR_VCPUS:
- r = num_online_cpus();
+ r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
break;
case KVM_CAP_MAX_VCPUS:
r = KVM_MAX_VCPUS;
--
2.33.1


2021-11-16 16:36:05

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v2 5/6] KVM: s390: Cap KVM_CAP_NR_VCPUS by num_online_cpus()

KVM_CAP_NR_VCPUS is a legacy advisory value which on other architectures
return num_online_cpus() caped by KVM_CAP_NR_VCPUS or something else
(ppc and arm64 are special cases). On s390, KVM_CAP_NR_VCPUS returns
the same as KVM_CAP_MAX_VCPUS and this may turn out to be a bad
'advice'. Switch s390 to returning caped num_online_cpus() too.

Acked-by: Christian Borntraeger <[email protected]>
Signed-off-by: Vitaly Kuznetsov <[email protected]>
---
arch/s390/kvm/kvm-s390.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 6a6dd5e1daf6..1cfe36f6432e 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -585,6 +585,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = KVM_MAX_VCPUS;
else if (sclp.has_esca && sclp.has_64bscao)
r = KVM_S390_ESCA_CPU_SLOTS;
+ if (ext == KVM_CAP_NR_VCPUS)
+ r = min_t(unsigned int, num_online_cpus(), r);
break;
case KVM_CAP_S390_COW:
r = MACHINE_HAS_ESOP;
--
2.33.1


2021-11-16 16:36:19

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v2 6/6] KVM: x86: Drop arbitraty KVM_SOFT_MAX_VCPUS

KVM_CAP_NR_VCPUS is used to get the "recommended" maximum number of
VCPUs and arm64/mips/riscv report num_online_cpus(). Powerpc reports
either num_online_cpus() or num_present_cpus(), s390 has multiple
constants depending on hardware features. On x86, KVM reports an
arbitrary value of '710' which is supposed to be the maximum tested
value but it's possible to test all KVM_MAX_VCPUS even when there are
less physical CPUs available.

Drop the arbitrary '710' value and return num_online_cpus() on x86 as
well. The recommendation will match other architectures and will mean
'no CPU overcommit'.

For reference, QEMU only queries KVM_CAP_NR_VCPUS to print a warning
when the requested vCPU number exceeds it. The static limit of '710'
is quite weird as smaller systems with just a few physical CPUs should
certainly "recommend" less.

Suggested-by: Eduardo Habkost <[email protected]>
Signed-off-by: Vitaly Kuznetsov <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 1 -
arch/x86/kvm/x86.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 88fce6ab4bbd..0232a00598f2 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -38,7 +38,6 @@
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS

#define KVM_MAX_VCPUS 1024
-#define KVM_SOFT_MAX_VCPUS 710

/*
* In x86, the VCPU ID corresponds to the APIC ID, and APIC IDs
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ac83d873d65b..18a00a7c23bc 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4137,7 +4137,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = !static_call(kvm_x86_cpu_has_accelerated_tpr)();
break;
case KVM_CAP_NR_VCPUS:
- r = KVM_SOFT_MAX_VCPUS;
+ r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
break;
case KVM_CAP_MAX_VCPUS:
r = KVM_MAX_VCPUS;
--
2.33.1


2021-11-17 05:02:33

by Anup Patel

[permalink] [raw]
Subject: Re: [PATCH v2 4/6] KVM: RISC-V: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS

On Tue, Nov 16, 2021 at 10:05 PM Vitaly Kuznetsov <[email protected]> wrote:
>
> It doesn't make sense to return the recommended maximum number of
> vCPUs which exceeds the maximum possible number of vCPUs.
>
> Signed-off-by: Vitaly Kuznetsov <[email protected]>

Looks good to me.

For KVM RISC-V:
Acked-by: Anup Patel <[email protected]>
Reviewed-by: Anup Patel <[email protected]>

Thanks,
Anup

> ---
> arch/riscv/kvm/vm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c
> index 26399df15b63..fb18af34a4b5 100644
> --- a/arch/riscv/kvm/vm.c
> +++ b/arch/riscv/kvm/vm.c
> @@ -74,7 +74,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> r = 1;
> break;
> case KVM_CAP_NR_VCPUS:
> - r = num_online_cpus();
> + r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
> break;
> case KVM_CAP_MAX_VCPUS:
> r = KVM_MAX_VCPUS;
> --
> 2.33.1
>

2021-11-17 07:34:06

by Christian Borntraeger

[permalink] [raw]
Subject: Re: [PATCH v2 5/6] KVM: s390: Cap KVM_CAP_NR_VCPUS by num_online_cpus()

Am 16.11.21 um 17:34 schrieb Vitaly Kuznetsov:
> KVM_CAP_NR_VCPUS is a legacy advisory value which on other architectures
> return num_online_cpus() caped by KVM_CAP_NR_VCPUS or something else
> (ppc and arm64 are special cases). On s390, KVM_CAP_NR_VCPUS returns
> the same as KVM_CAP_MAX_VCPUS and this may turn out to be a bad
> 'advice'. Switch s390 to returning caped num_online_cpus() too.
>
> Acked-by: Christian Borntraeger <[email protected]>

you can also add
Reviewed-by: Christian Borntraeger <[email protected]>

(yes I am changing my default address, but the other should continue to work)

> Signed-off-by: Vitaly Kuznetsov <[email protected]>
> ---
> arch/s390/kvm/kvm-s390.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index 6a6dd5e1daf6..1cfe36f6432e 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -585,6 +585,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> r = KVM_MAX_VCPUS;
> else if (sclp.has_esca && sclp.has_64bscao)
> r = KVM_S390_ESCA_CPU_SLOTS;
> + if (ext == KVM_CAP_NR_VCPUS)
> + r = min_t(unsigned int, num_online_cpus(), r);
> break;
> case KVM_CAP_S390_COW:
> r = MACHINE_HAS_ESOP;
>

2021-11-17 09:14:07

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH v2 1/6] KVM: arm64: Cap KVM_CAP_NR_VCPUS by kvm_arm_default_max_vcpus()

On Tue, 16 Nov 2021 16:34:38 +0000,
Vitaly Kuznetsov <[email protected]> wrote:
>
> Generally, it doesn't make sense to return the recommended maximum number
> of vCPUs which exceeds the maximum possible number of vCPUs.
>
> Note: ARM64 is special as the value returned by KVM_CAP_MAX_VCPUS differs
> depending on whether it is a system-wide ioctl or a per-VM one. Previously,
> KVM_CAP_NR_VCPUS didn't have this difference and it seems preferable to
> keep the status quo. Cap KVM_CAP_NR_VCPUS by kvm_arm_default_max_vcpus()
> which is what gets returned by system-wide KVM_CAP_MAX_VCPUS.
>
> Signed-off-by: Vitaly Kuznetsov <[email protected]>

Acked-by: Marc Zyngier <[email protected]>

M.

--
Without deviation from the norm, progress is not possible.

2021-11-17 12:08:06

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v2 1/6] KVM: arm64: Cap KVM_CAP_NR_VCPUS by kvm_arm_default_max_vcpus()

On 11/16/21 17:34, Vitaly Kuznetsov wrote:
> - r = num_online_cpus();
> + /*
> + * ARM64 treats KVM_CAP_NR_CPUS differently from all other
> + * architectures, as it does not always bound it to
> + * num_online_cpus(). It should not matter much because this
^^^^^^^^^^^^^^^^^^

KVM_CAP_MAX_VCPUS (sorry for the typo in my suggestion). I'll fix it
when applying.

Paolo

> + * is just an advisory value.
> + */
> + r = min_t(unsigned int, num_online_cpus(),
> + kvm_arm_default_max_vcpus());


2021-11-17 12:12:14

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v2 6/6] KVM: x86: Drop arbitraty KVM_SOFT_MAX_VCPUS

On 11/16/21 17:34, Vitaly Kuznetsov wrote:
> KVM_CAP_NR_VCPUS is used to get the "recommended" maximum number of
> VCPUs and arm64/mips/riscv report num_online_cpus(). Powerpc reports
> either num_online_cpus() or num_present_cpus(), s390 has multiple
> constants depending on hardware features. On x86, KVM reports an
> arbitrary value of '710' which is supposed to be the maximum tested
> value but it's possible to test all KVM_MAX_VCPUS even when there are
> less physical CPUs available.
>
> Drop the arbitrary '710' value and return num_online_cpus() on x86 as
> well. The recommendation will match other architectures and will mean
> 'no CPU overcommit'.
>
> For reference, QEMU only queries KVM_CAP_NR_VCPUS to print a warning
> when the requested vCPU number exceeds it. The static limit of '710'
> is quite weird as smaller systems with just a few physical CPUs should
> certainly "recommend" less.
>
> Suggested-by: Eduardo Habkost<[email protected]>
> Signed-off-by: Vitaly Kuznetsov<[email protected]>

Given that KVM_SOFT_MAX_VCPUS has already been dropped in 5.16, I
changed the commit message to

KVM: x86: Cap KVM_CAP_NR_VCPUS by KVM_CAP_MAX_VCPUS

It doesn't make sense to return the recommended maximum number of
vCPUs which exceeds the maximum possible number of vCPUs.

Paolo