virtinst: prefer cores when exposing topology to the guest

In real world silicon though it is rare to have high socket/die counts,
but common to have huge core counts.

Some OS will even refuse to use sockets over a certain count.

Thus we prefer to expose cores to the guest rather than sockets as the
default for missing fields.

This matches a recent change made in QEMU for new machine types

  commit 4a0af2930a4e4f64ce551152fdb4b9e7be106408
  Author: Yanan Wang <wangyanan55@huawei.com>
  Date:   Wed Sep 29 10:58:09 2021 +0800

    machine: Prefer cores over sockets in smp parsing since 6.2

Closes: https://github.com/virt-manager/virt-manager/issues/155
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2021-10-29 13:27:35 +01:00 committed by Cole Robinson
parent e1c8866163
commit 9a578e1ac5
3 changed files with 20 additions and 7 deletions

View File

@ -290,8 +290,10 @@ the guest will be able to hotplug up to MAX vcpus while the guest is running,
but will startup with VCPUS. but will startup with VCPUS.
CPU topology can additionally be specified with sockets, dies, cores, and threads. CPU topology can additionally be specified with sockets, dies, cores, and threads.
If values are omitted, the rest will be autofilled preferring sockets over If values are omitted, the rest will be autofilled preferring cores over sockets
cores over threads. over threads. Cores are preferred because this matches the characteristics of
modern real world silicon and thus a better fit for what guest OS will be
expecting to deal with.
'cpuset' sets which physical cpus the guest can use. ``CPUSET`` is a comma 'cpuset' sets which physical cpus the guest can use. ``CPUSET`` is a comma
separated list of numbers, which can also be specified in ranges or cpus separated list of numbers, which can also be specified in ranges or cpus

View File

@ -38,7 +38,7 @@ def test_misc_cpu_topology():
cpu = virtinst.DomainCpu(conn) cpu = virtinst.DomainCpu(conn)
cpu.topology.dies = "3" cpu.topology.dies = "3"
cpu.set_topology_defaults(9) cpu.set_topology_defaults(9)
assert get_top(cpu) == [3, 3, 1, 1] assert get_top(cpu) == [1, 3, 3, 1]
cpu = virtinst.DomainCpu(conn) cpu = virtinst.DomainCpu(conn)
cpu.topology.cores = "4" cpu.topology.cores = "4"
@ -48,7 +48,7 @@ def test_misc_cpu_topology():
cpu = virtinst.DomainCpu(conn) cpu = virtinst.DomainCpu(conn)
cpu.topology.threads = "3" cpu.topology.threads = "3"
cpu.set_topology_defaults(12) cpu.set_topology_defaults(12)
assert get_top(cpu) == [4, 1, 1, 3] assert get_top(cpu) == [1, 1, 4, 3]
cpu = virtinst.DomainCpu(conn) cpu = virtinst.DomainCpu(conn)
cpu.topology.threads = "3" cpu.topology.threads = "3"

View File

@ -29,15 +29,26 @@ class _CPUTopology(XMLBuilder):
# While `dies` is optional and defaults to 1 if omitted, # While `dies` is optional and defaults to 1 if omitted,
# `sockets`, `cores`, and `threads` are mandatory. # `sockets`, `cores`, and `threads` are mandatory.
def set_defaults_from_vcpus(self, vcpus): def set_defaults_from_vcpus(self, vcpus):
# The hierarchy is sockets > dies > cores > threads.
#
# In real world silicon though it is rare to have
# high socket/die counts, but common to have huge
# core counts.
#
# Some OS will even refuse to use sockets over a
# a certain count.
#
# Thus we prefer to expose cores to the guest rather
# than sockets as the default for missing fields
if not self.cores:
self.cores = vcpus // self.total_vcpus()
if not self.sockets: if not self.sockets:
self.sockets = vcpus // self.total_vcpus() self.sockets = vcpus // self.total_vcpus()
if not self.dies: if not self.dies:
self.dies = 1 self.dies = 1
if not self.cores:
self.cores = vcpus // self.total_vcpus()
if not self.threads: if not self.threads:
self.threads = vcpus // self.total_vcpus() self.threads = vcpus // self.total_vcpus()