qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Yanan Wang <wangyanan55@huawei.com>
To: Peter Maydell <peter.maydell@linaro.org>,
	Andrew Jones <drjones@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	Igor Mammedov <imammedo@redhat.com>,
	Shannon Zhao <shannon.zhaosl@gmail.com>,
	Alistair Francis <alistair.francis@wdc.com>,
	David Gibson <david@gibson.dropbear.id.au>,
	<qemu-devel@nongnu.org>, <qemu-arm@nongnu.org>
Cc: Barry Song <song.bao.hua@hisilicon.com>,
	Yanan Wang <wangyanan55@huawei.com>,
	prime.zeng@hisilicon.com, wanghaibin.wang@huawei.com,
	yuzenghui@huawei.com, yangyicong@huawei.com,
	zhukeqian1@huawei.com
Subject: [RFC PATCH v4 2/7] hw/arm/virt: Add separate -smp parsing function for ARM machines
Date: Tue, 22 Jun 2021 17:34:08 +0800	[thread overview]
Message-ID: <20210622093413.13360-3-wangyanan55@huawei.com> (raw)
In-Reply-To: <20210622093413.13360-1-wangyanan55@huawei.com>

Add an ARM-specific -smp parsing function named virt_smp_parse.
When support for exposing cpu topology to the guest is disabled,
this function shares the same logic with smp_parse(). While when
the support is enabled, an accurate virtual cpu topology is very
important, so we require that cpus/sockets/cores/threads must be
given, while maxcpus is optional.

Given that ARM cpu hotplug is not supported yet, a configuration
with "maxcpus > cpus" is meaningless, so if exposure is turned on
we also explicitly enforce that maxcpus must be equal to smp cpus
if specified, until cpu hotplug is available.

Given that the virtual cpu topology exposure support may come
to different architectures in the future, a new structure member
"bool expose_cpu_topology" is also added to MachineState to
record whether the feature is supported & enabled.

Suggested-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
---
 hw/arm/virt.c       | 113 ++++++++++++++++++++++++++++++++++++++++++++
 include/hw/boards.h |   1 +
 2 files changed, 114 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4b96f06014..f29d796f3f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -77,6 +77,8 @@
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/char/pl011.h"
 #include "qemu/guest-random.h"
+#include "qapi/qmp/qerror.h"
+#include "sysemu/replay.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
     static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -2584,6 +2586,116 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
     return fixed_ipa ? 0 : requested_pa_size;
 }
 
+/*
+ * virt_smp_parse - Parses the -smp command line for ARM machines.
+ *
+ * When support for exposing cpu topology to the guest is disabled,
+ * this function shares the same parsing logic with smp_parse().
+ * While when the exposure is enabled, an accurate virtual cpu topology
+ * is important, so we required that cpus/sockets/cores/threads must be
+ * provided, while maxcpus can be optional.
+ */
+static void virt_smp_parse(MachineState *ms, QemuOpts *opts)
+{
+    if (opts) {
+        unsigned cpus = qemu_opt_get_number(opts, "cpus", 0);
+        unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
+        unsigned cores = qemu_opt_get_number(opts, "cores", 0);
+        unsigned threads = qemu_opt_get_number(opts, "threads", 0);
+        unsigned maxcpus = qemu_opt_get_number(opts, "maxcpus", 0);
+        bool expose = qemu_opt_get_bool(opts, "expose", false);
+
+        if (expose) {
+            if (cpus == 0) {
+                error_report("expose=on: cpus must be specified");
+                exit(1);
+            }
+            if (sockets == 0) {
+                error_report("expose=on: sockets must be specified");
+                exit(1);
+            }
+            if (cores == 0) {
+                error_report("expose=on: cores must be specified");
+                exit(1);
+            }
+            if (threads == 0) {
+                error_report("expose=on: threads must be specified");
+                exit(1);
+            }
+        } else {
+            /*
+             * An accurate cpu topology configuration is not required in this
+             * case, so we compute the missing values preferring sockets over
+             * cores over threads.
+             */
+            if (cpus == 0 || sockets == 0) {
+                cores = cores > 0 ? cores : 1;
+                threads = threads > 0 ? threads : 1;
+                if (cpus == 0) {
+                    sockets = sockets > 0 ? sockets : 1;
+                    cpus = cores * threads * sockets;
+                } else {
+                    maxcpus = maxcpus > 0 ? maxcpus : cpus;
+                    sockets = maxcpus / (cores * threads);
+                }
+            } else if (cores == 0) {
+                threads = threads > 0 ? threads : 1;
+                cores = cpus / (sockets * threads);
+                cores = cores > 0 ? cores : 1;
+            } else if (threads == 0) {
+                threads = cpus / (cores * sockets);
+                threads = threads > 0 ? threads : 1;
+            }
+        }
+
+        maxcpus = maxcpus > 0 ? maxcpus : cpus;
+
+        if (sockets * cores * threads < cpus) {
+            error_report("cpu topology: "
+                         "sockets (%u) * cores (%u) * threads (%u) < "
+                         "smp_cpus (%u)",
+                         sockets, cores, threads, cpus);
+            exit(1);
+        }
+
+        if (maxcpus < cpus) {
+            error_report("maxcpus must be equal to or greater than smp");
+            exit(1);
+        }
+
+        if (sockets * cores * threads != maxcpus) {
+            error_report("Invalid CPU topology: "
+                         "sockets (%u) * cores (%u) * threads (%u) "
+                         "!= maxcpus (%u)",
+                         sockets, cores, threads, maxcpus);
+            exit(1);
+        }
+
+        /*
+         * Given that cpu hotplug is not supported yet, require that maxcpus
+         * must be equal to smp cpus if we are going to expose cpu topology
+         * to the guest.
+         */
+        if (expose == true && maxcpus != cpus) {
+            error_report("cpu hotplug is not supported yet, maxcpus must be"
+                         "equal to smp");
+        }
+
+        ms->smp.cpus = cpus;
+        ms->smp.sockets = sockets;
+        ms->smp.cores = cores;
+        ms->smp.threads = threads;
+        ms->smp.max_cpus = maxcpus;
+        ms->expose_cpu_topology = expose;
+    }
+
+    if (ms->smp.cpus > 1) {
+        Error *blocker = NULL;
+        error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
+        replay_add_blocker(blocker);
+    }
+}
+
 static void virt_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -2611,6 +2723,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
     mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
     mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
+    mc->smp_parse = virt_smp_parse;
     mc->kvm_type = virt_kvm_type;
     assert(!mc->get_hotplug_handler);
     mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3d55d2bd62..54accc810a 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -332,6 +332,7 @@ struct MachineState {
     AccelState *accelerator;
     CPUArchIdList *possible_cpus;
     CpuTopology smp;
+    bool expose_cpu_topology;
     struct NVDIMMState *nvdimms_state;
     struct NumaState *numa_state;
 };
-- 
2.23.0



  parent reply	other threads:[~2021-06-22  9:36 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-22  9:34 [RFC PATCH v4 0/7] hw/arm/virt: Introduce cpu topology support Yanan Wang
2021-06-22  9:34 ` [RFC PATCH v4 1/7] vl: Add expose=on|off option support in -smp command line Yanan Wang
2021-06-22  9:34 ` Yanan Wang [this message]
2021-06-22  9:34 ` [RFC PATCH v4 3/7] machine: disallow -smp expose=on for non-ARM machines Yanan Wang
2021-06-22  9:34 ` [RFC PATCH v4 4/7] device_tree: Add qemu_fdt_add_path Yanan Wang
2021-06-22  9:34 ` [RFC PATCH v4 5/7] hw/arm/virt: Add cpu-map to device tree Yanan Wang
2021-06-22  9:34 ` [RFC PATCH v4 6/7] hw/acpi/aml-build: Add Processor hierarchy node structure Yanan Wang
2021-06-22  9:34 ` [RFC PATCH v4 7/7] hw/acpi/aml-build: Generate PPTT table Yanan Wang
2021-06-22 10:18 ` [RFC PATCH v4 0/7] hw/arm/virt: Introduce cpu topology support Daniel P. Berrangé
2021-06-22 11:46   ` Andrew Jones
2021-06-22 12:31     ` wangyanan (Y)
2021-06-22 12:41       ` Daniel P. Berrangé
2021-06-22 14:04         ` wangyanan (Y)
2021-06-22 14:10           ` Daniel P. Berrangé
2021-06-22 14:15             ` Peter Maydell
2021-06-22 14:28               ` Daniel P. Berrangé
2021-06-28 11:14                 ` wangyanan (Y)
2021-06-28 11:31                   ` Daniel P. Berrangé
2021-06-28 11:53                     ` wangyanan (Y)
2021-06-22 14:29             ` Andrew Jones
2021-06-22 15:15               ` Daniel P. Berrangé
2021-06-22 15:40               ` Igor Mammedov
2021-06-22 17:08                 ` Andrew Jones
2021-06-22 17:14                 ` Daniel P. Berrangé
2021-06-22 17:29                   ` Andrew Jones
2021-06-22 17:39                     ` Daniel P. Berrangé
2021-06-28  8:43                       ` wangyanan (Y)
2021-06-28  8:58                         ` Andrew Jones
2021-06-28 10:48                           ` wangyanan (Y)
2021-06-30  6:36                           ` wangyanan (Y)
2021-06-30  8:30                             ` Andrew Jones
2021-06-30  9:37                               ` wangyanan (Y)
2021-06-30 11:56                                 ` Andrew Jones
2021-07-01  6:15                                   ` wangyanan (Y)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210622093413.13360-3-wangyanan55@huawei.com \
    --to=wangyanan55@huawei.com \
    --cc=alistair.francis@wdc.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=drjones@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=prime.zeng@hisilicon.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=shannon.zhaosl@gmail.com \
    --cc=song.bao.hua@hisilicon.com \
    --cc=wanghaibin.wang@huawei.com \
    --cc=yangyicong@huawei.com \
    --cc=yuzenghui@huawei.com \
    --cc=zhukeqian1@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).