Update patch with openeuler !232
Signed-off-by: imxcc <xingchaochao@huawei.com>
This commit is contained in:
parent
65b515392c
commit
8a7a7c9d07
BIN
BinDir.tar.gz
BIN
BinDir.tar.gz
Binary file not shown.
616
arm64-Add-the-cpufreq-device-to-show-cpufreq-info-to.patch
Normal file
616
arm64-Add-the-cpufreq-device-to-show-cpufreq-info-to.patch
Normal file
@ -0,0 +1,616 @@
|
||||
From e7e28e79988eb671051d0d2af0eb010314c83d41 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Tue, 8 Feb 2022 21:01:09 +0800
|
||||
Subject: [PATCH 24/24] arm64: Add the cpufreq device to show cpufreq info to
|
||||
guest
|
||||
|
||||
On ARM64 platform, cpu frequency is retrieved via ACPI CPPC.
|
||||
A virtual cpufreq device based on ACPI CPPC is created to
|
||||
present cpu frequency info to the guest.
|
||||
|
||||
The default frequency is set to host cpu nominal frequency,
|
||||
which is obtained from the host CPPC sysfs. Other performance
|
||||
data are set to the same value, since we don't support guest
|
||||
performance scaling here.
|
||||
|
||||
Performance counters are also not emulated and they simply
|
||||
return 1 if read, and guest should fallback to use desired
|
||||
performance value as the current performance.
|
||||
|
||||
Guest kernel version above 4.18 is required to make it work.
|
||||
|
||||
This series is backported from:
|
||||
https://patchwork.kernel.org/cover/11379943/
|
||||
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
---
|
||||
configs/devices/aarch64-softmmu/default.mak | 1 +
|
||||
hw/acpi/aml-build.c | 22 ++
|
||||
hw/acpi/cpufreq.c | 283 ++++++++++++++++++++
|
||||
hw/acpi/meson.build | 1 +
|
||||
hw/arm/virt-acpi-build.c | 77 +++++-
|
||||
hw/arm/virt.c | 13 +
|
||||
hw/char/Kconfig | 4 +
|
||||
include/hw/acpi/acpi-defs.h | 38 +++
|
||||
include/hw/acpi/aml-build.h | 3 +
|
||||
include/hw/arm/virt.h | 1 +
|
||||
tests/data/acpi/virt/DSDT | Bin 5196 -> 5669 bytes
|
||||
tests/data/acpi/virt/DSDT.memhp | Bin 6557 -> 7030 bytes
|
||||
tests/data/acpi/virt/DSDT.numamem | Bin 5196 -> 5669 bytes
|
||||
tests/data/acpi/virt/DSDT.pxb | Bin 7679 -> 8152 bytes
|
||||
14 files changed, 441 insertions(+), 2 deletions(-)
|
||||
create mode 100644 hw/acpi/cpufreq.c
|
||||
|
||||
diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak
|
||||
index cf43ac8da1..c7a710a0f1 100644
|
||||
--- a/configs/devices/aarch64-softmmu/default.mak
|
||||
+++ b/configs/devices/aarch64-softmmu/default.mak
|
||||
@@ -6,3 +6,4 @@ include ../arm-softmmu/default.mak
|
||||
CONFIG_XLNX_ZYNQMP_ARM=y
|
||||
CONFIG_XLNX_VERSAL=y
|
||||
CONFIG_SBSA_REF=y
|
||||
+CONFIG_CPUFREQ=y
|
||||
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
||||
index bebf49622b..c4edaafa4a 100644
|
||||
--- a/hw/acpi/aml-build.c
|
||||
+++ b/hw/acpi/aml-build.c
|
||||
@@ -1554,6 +1554,28 @@ Aml *aml_sleep(uint64_t msec)
|
||||
return var;
|
||||
}
|
||||
|
||||
+/* ACPI 5.0b: 6.4.3.7 Generic Register Descriptor */
|
||||
+Aml *aml_generic_register(AmlRegionSpace rs, uint8_t reg_width,
|
||||
+ uint8_t reg_offset, AmlAccessType type, uint64_t addr)
|
||||
+{
|
||||
+ int i;
|
||||
+ Aml *var = aml_alloc();
|
||||
+ build_append_byte(var->buf, 0x82); /* Generic Register Descriptor */
|
||||
+ build_append_byte(var->buf, 0x0C); /* Length, bits[7:0] value = 0x0C */
|
||||
+ build_append_byte(var->buf, 0); /* Length, bits[15:8] value = 0 */
|
||||
+ build_append_byte(var->buf, rs); /* Address Space ID */
|
||||
+ build_append_byte(var->buf, reg_width); /* Register Bit Width */
|
||||
+ build_append_byte(var->buf, reg_offset); /* Register Bit Offset */
|
||||
+ build_append_byte(var->buf, type); /* Access Size */
|
||||
+
|
||||
+ /* Register address */
|
||||
+ for (i = 0; i < 8; i++) {
|
||||
+ build_append_byte(var->buf, extract64(addr, i * 8, 8));
|
||||
+ }
|
||||
+
|
||||
+ return var;
|
||||
+}
|
||||
+
|
||||
static uint8_t Hex2Byte(const char *src)
|
||||
{
|
||||
int hi, lo;
|
||||
diff --git a/hw/acpi/cpufreq.c b/hw/acpi/cpufreq.c
|
||||
new file mode 100644
|
||||
index 0000000000..a84db490b3
|
||||
--- /dev/null
|
||||
+++ b/hw/acpi/cpufreq.c
|
||||
@@ -0,0 +1,283 @@
|
||||
+/*
|
||||
+ * ACPI CPPC register device
|
||||
+ *
|
||||
+ * Support for showing CPU frequency in guest OS.
|
||||
+ *
|
||||
+ * Copyright (c) 2019 HUAWEI TECHNOLOGIES CO.,LTD.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+
|
||||
+ * You should have received a copy of the GNU General Public License along
|
||||
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/sysbus.h"
|
||||
+#include "chardev/char.h"
|
||||
+#include "qemu/log.h"
|
||||
+#include "trace.h"
|
||||
+#include "qemu/option.h"
|
||||
+#include "sysemu/sysemu.h"
|
||||
+#include "hw/acpi/acpi-defs.h"
|
||||
+#include "qemu/cutils.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+#include "hw/boards.h"
|
||||
+
|
||||
+#define TYPE_CPUFREQ "cpufreq"
|
||||
+#define CPUFREQ(obj) OBJECT_CHECK(CpuhzState, (obj), TYPE_CPUFREQ)
|
||||
+#define NOMINAL_FREQ_FILE "/sys/devices/system/cpu/cpu0/acpi_cppc/nominal_freq"
|
||||
+#define CPU_MAX_FREQ_FILE "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"
|
||||
+#define HZ_MAX_LENGTH 1024
|
||||
+#define MAX_SUPPORT_SPACE 0x10000
|
||||
+
|
||||
+/*
|
||||
+ * Since Hi1616 will not support CPPC, we simply use its nominal frequency as
|
||||
+ * the default.
|
||||
+ */
|
||||
+#define DEFAULT_HZ 2400
|
||||
+
|
||||
+int cppc_regs_offset[CPPC_REG_COUNT] = {
|
||||
+ [HIGHEST_PERF] = 0,
|
||||
+ [NOMINAL_PERF] = 4,
|
||||
+ [LOW_NON_LINEAR_PERF] = 8,
|
||||
+ [LOWEST_PERF] = 12,
|
||||
+ [GUARANTEED_PERF] = 16,
|
||||
+ [DESIRED_PERF] = 20,
|
||||
+ [MIN_PERF] = -1,
|
||||
+ [MAX_PERF] = -1,
|
||||
+ [PERF_REDUC_TOLERANCE] = -1,
|
||||
+ [TIME_WINDOW] = -1,
|
||||
+ [CTR_WRAP_TIME] = -1,
|
||||
+ [REFERENCE_CTR] = 24,
|
||||
+ [DELIVERED_CTR] = 32,
|
||||
+ [PERF_LIMITED] = 40,
|
||||
+ [ENABLE] = -1,
|
||||
+ [AUTO_SEL_ENABLE] = -1,
|
||||
+ [AUTO_ACT_WINDOW] = -1,
|
||||
+ [ENERGY_PERF] = -1,
|
||||
+ [REFERENCE_PERF] = -1,
|
||||
+ [LOWEST_FREQ] = 44,
|
||||
+ [NOMINAL_FREQ] = 48,
|
||||
+};
|
||||
+
|
||||
+typedef struct CpuhzState {
|
||||
+ SysBusDevice parent_obj;
|
||||
+
|
||||
+ MemoryRegion iomem;
|
||||
+ uint32_t HighestPerformance;
|
||||
+ uint32_t NominalPerformance;
|
||||
+ uint32_t LowestNonlinearPerformance;
|
||||
+ uint32_t LowestPerformance;
|
||||
+ uint32_t GuaranteedPerformance;
|
||||
+ uint32_t DesiredPerformance;
|
||||
+ uint64_t ReferencePerformanceCounter;
|
||||
+ uint64_t DeliveredPerformanceCounter;
|
||||
+ uint32_t PerformanceLimited;
|
||||
+ uint32_t LowestFreq;
|
||||
+ uint32_t NominalFreq;
|
||||
+ uint32_t reg_size;
|
||||
+} CpuhzState;
|
||||
+
|
||||
+
|
||||
+static uint64_t cpufreq_read(void *opaque, hwaddr offset, unsigned size)
|
||||
+{
|
||||
+ CpuhzState *s = (CpuhzState *)opaque;
|
||||
+ uint64_t r;
|
||||
+ uint64_t n;
|
||||
+
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cpus = ms->smp.cpus;
|
||||
+
|
||||
+ if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) {
|
||||
+ warn_report("cpufreq_read: offset 0x%lx out of range", offset);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ n = offset % CPPC_REG_PER_CPU_STRIDE;
|
||||
+ switch (n) {
|
||||
+ case 0:
|
||||
+ r = s->HighestPerformance;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ r = s->NominalPerformance;
|
||||
+ break;
|
||||
+ case 8:
|
||||
+ r = s->LowestNonlinearPerformance;
|
||||
+ break;
|
||||
+ case 12:
|
||||
+ r = s->LowestPerformance;
|
||||
+ break;
|
||||
+ case 16:
|
||||
+ r = s->GuaranteedPerformance;
|
||||
+ break;
|
||||
+ case 20:
|
||||
+ r = s->DesiredPerformance;
|
||||
+ break;
|
||||
+ /*
|
||||
+ * We don't have real counters and it is hard to emulate, so always set the
|
||||
+ * counter value to 1 to rely on Linux to use the DesiredPerformance value
|
||||
+ * directly.
|
||||
+ */
|
||||
+ case 24:
|
||||
+ r = s->ReferencePerformanceCounter;
|
||||
+ break;
|
||||
+ /*
|
||||
+ * Guest may still access the register by 32bit; add the process to
|
||||
+ * eliminate unnecessary warnings.
|
||||
+ */
|
||||
+ case 28:
|
||||
+ r = s->ReferencePerformanceCounter >> 32;
|
||||
+ break;
|
||||
+ case 32:
|
||||
+ r = s->DeliveredPerformanceCounter;
|
||||
+ break;
|
||||
+ case 36:
|
||||
+ r = s->DeliveredPerformanceCounter >> 32;
|
||||
+ break;
|
||||
+
|
||||
+ case 40:
|
||||
+ r = s->PerformanceLimited;
|
||||
+ break;
|
||||
+ case 44:
|
||||
+ r = s->LowestFreq;
|
||||
+ break;
|
||||
+ case 48:
|
||||
+ r = s->NominalFreq;
|
||||
+ break;
|
||||
+ default:
|
||||
+ error_printf("cpufreq_read: Bad offset 0x%lx\n", offset);
|
||||
+ r = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static void cpufreq_write(void *opaque, hwaddr offset,
|
||||
+ uint64_t value, unsigned size)
|
||||
+{
|
||||
+ uint64_t n;
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cpus = ms->smp.cpus;
|
||||
+
|
||||
+ if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) {
|
||||
+ error_printf("cpufreq_write: offset 0x%lx out of range", offset);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ n = offset % CPPC_REG_PER_CPU_STRIDE;
|
||||
+
|
||||
+ switch (n) {
|
||||
+ case 20:
|
||||
+ break;
|
||||
+ default:
|
||||
+ error_printf("cpufreq_write: Bad offset 0x%lx\n", offset);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static uint32_t CPPC_Read(const char *hostpath)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char buffer[HZ_MAX_LENGTH] = { 0 };
|
||||
+ uint64_t hz;
|
||||
+ int len;
|
||||
+ const char *endptr = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ fd = qemu_open_old(hostpath, O_RDONLY);
|
||||
+ if (fd < 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ len = read(fd, buffer, HZ_MAX_LENGTH);
|
||||
+ qemu_close(fd);
|
||||
+ if (len <= 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ ret = qemu_strtoul(buffer, &endptr, 0, &hz);
|
||||
+ if (ret < 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return (uint32_t)hz;
|
||||
+}
|
||||
+
|
||||
+static const MemoryRegionOps cpufreq_ops = {
|
||||
+ .read = cpufreq_read,
|
||||
+ .write = cpufreq_write,
|
||||
+ .endianness = DEVICE_NATIVE_ENDIAN,
|
||||
+};
|
||||
+
|
||||
+static void hz_init(CpuhzState *s)
|
||||
+{
|
||||
+ uint32_t hz;
|
||||
+
|
||||
+ hz = CPPC_Read(NOMINAL_FREQ_FILE);
|
||||
+ if (hz == 0) {
|
||||
+ hz = CPPC_Read(CPU_MAX_FREQ_FILE);
|
||||
+ if (hz == 0) {
|
||||
+ hz = DEFAULT_HZ;
|
||||
+ } else {
|
||||
+ /* Value in CpuMaxFrequency is in KHz unit; convert to MHz */
|
||||
+ hz = hz / 1000;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ s->HighestPerformance = hz;
|
||||
+ s->NominalPerformance = hz;
|
||||
+ s->LowestNonlinearPerformance = hz;
|
||||
+ s->LowestPerformance = hz;
|
||||
+ s->GuaranteedPerformance = hz;
|
||||
+ s->DesiredPerformance = hz;
|
||||
+ s->ReferencePerformanceCounter = 1;
|
||||
+ s->DeliveredPerformanceCounter = 1;
|
||||
+ s->PerformanceLimited = 0;
|
||||
+ s->LowestFreq = hz;
|
||||
+ s->NominalFreq = hz;
|
||||
+}
|
||||
+
|
||||
+static void cpufreq_init(Object *obj)
|
||||
+{
|
||||
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
+ CpuhzState *s = CPUFREQ(obj);
|
||||
+
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cpus = ms->smp.cpus;
|
||||
+
|
||||
+ s->reg_size = smp_cpus * CPPC_REG_PER_CPU_STRIDE;
|
||||
+ if (s->reg_size > MAX_SUPPORT_SPACE) {
|
||||
+ error_report("Required space 0x%x excesses the max support 0x%x",
|
||||
+ s->reg_size, MAX_SUPPORT_SPACE);
|
||||
+ goto err_end;
|
||||
+ }
|
||||
+
|
||||
+ memory_region_init_io(&s->iomem, OBJECT(s), &cpufreq_ops, s, "cpufreq",
|
||||
+ s->reg_size);
|
||||
+ sysbus_init_mmio(sbd, &s->iomem);
|
||||
+ hz_init(s);
|
||||
+ return;
|
||||
+
|
||||
+err_end:
|
||||
+ /* Set desired perf register offset to -1 to indicate no support for CPPC */
|
||||
+ cppc_regs_offset[DESIRED_PERF] = -1;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo cpufreq_arm_info = {
|
||||
+ .name = TYPE_CPUFREQ,
|
||||
+ .parent = TYPE_SYS_BUS_DEVICE,
|
||||
+ .instance_size = sizeof(CpuhzState),
|
||||
+ .instance_init = cpufreq_init,
|
||||
+};
|
||||
+
|
||||
+static void cpufreq_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&cpufreq_arm_info);
|
||||
+}
|
||||
+
|
||||
+type_init(cpufreq_register_types)
|
||||
diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build
|
||||
index adf6347bc4..448ea6afb4 100644
|
||||
--- a/hw/acpi/meson.build
|
||||
+++ b/hw/acpi/meson.build
|
||||
@@ -25,6 +25,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_X86_ICH', if_true: files('ich9.c', 'tco.c'))
|
||||
acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c'))
|
||||
acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c'))
|
||||
acpi_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
|
||||
+acpi_ss.add(when: 'CONFIG_CPUFREQ', if_true: files('cpufreq.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c'))
|
||||
softmmu_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss)
|
||||
softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-stub.c', 'aml-build-stub.c',
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index 674f902652..1ca705654b 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -60,7 +60,68 @@
|
||||
|
||||
#define ACPI_BUILD_TABLE_SIZE 0x20000
|
||||
|
||||
-static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
|
||||
+static void acpi_dsdt_add_psd(Aml *dev, int cpus)
|
||||
+{
|
||||
+ Aml *pkg;
|
||||
+ Aml *sub;
|
||||
+
|
||||
+ sub = aml_package(5);
|
||||
+ aml_append(sub, aml_int(5));
|
||||
+ aml_append(sub, aml_int(0));
|
||||
+ /* Assume all vCPUs belong to the same domain */
|
||||
+ aml_append(sub, aml_int(0));
|
||||
+ /* SW_ANY: OSPM coordinate, initiate on any processor */
|
||||
+ aml_append(sub, aml_int(0xFD));
|
||||
+ aml_append(sub, aml_int(cpus));
|
||||
+
|
||||
+ pkg = aml_package(1);
|
||||
+ aml_append(pkg, sub);
|
||||
+
|
||||
+ aml_append(dev, aml_name_decl("_PSD", pkg));
|
||||
+}
|
||||
+
|
||||
+static void acpi_dsdt_add_cppc(Aml *dev, uint64_t cpu_base, int *regs_offset)
|
||||
+{
|
||||
+ Aml *cpc;
|
||||
+ int i;
|
||||
+
|
||||
+ /* Use version 3 of CPPC table from ACPI 6.3 */
|
||||
+ cpc = aml_package(23);
|
||||
+ aml_append(cpc, aml_int(23));
|
||||
+ aml_append(cpc, aml_int(3));
|
||||
+
|
||||
+ for (i = 0; i < CPPC_REG_COUNT; i++) {
|
||||
+ Aml *res;
|
||||
+ uint8_t reg_width;
|
||||
+ uint8_t acc_type;
|
||||
+ uint64_t addr;
|
||||
+
|
||||
+ if (regs_offset[i] == -1) {
|
||||
+ reg_width = 0;
|
||||
+ acc_type = AML_ANY_ACC;
|
||||
+ addr = 0;
|
||||
+ } else {
|
||||
+ addr = cpu_base + regs_offset[i];
|
||||
+ if (i == REFERENCE_CTR || i == DELIVERED_CTR) {
|
||||
+ reg_width = 64;
|
||||
+ acc_type = AML_QWORD_ACC;
|
||||
+ } else {
|
||||
+ reg_width = 32;
|
||||
+ acc_type = AML_DWORD_ACC;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ res = aml_resource_template();
|
||||
+ aml_append(res, aml_generic_register(AML_SYSTEM_MEMORY, reg_width, 0,
|
||||
+ acc_type, addr));
|
||||
+ aml_append(cpc, res);
|
||||
+ }
|
||||
+
|
||||
+ aml_append(dev, aml_name_decl("_CPC", cpc));
|
||||
+}
|
||||
+
|
||||
+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms,
|
||||
+ const MemMapEntry *cppc_memmap)
|
||||
{
|
||||
MachineState *ms = MACHINE(vms);
|
||||
uint16_t i;
|
||||
@@ -69,6 +130,18 @@ static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
|
||||
Aml *dev = aml_device("C%.03X", i);
|
||||
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
|
||||
+
|
||||
+ /*
|
||||
+ * Append _CPC and _PSD to support CPU frequence show
|
||||
+ * Check CPPC available by DESIRED_PERF register
|
||||
+ */
|
||||
+ if (cppc_regs_offset[DESIRED_PERF] != -1) {
|
||||
+ acpi_dsdt_add_cppc(dev,
|
||||
+ cppc_memmap->base + i * CPPC_REG_PER_CPU_STRIDE,
|
||||
+ cppc_regs_offset);
|
||||
+ acpi_dsdt_add_psd(dev, ms->smp.cpus);
|
||||
+ }
|
||||
+
|
||||
aml_append(scope, dev);
|
||||
}
|
||||
}
|
||||
@@ -858,7 +931,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
* the RTC ACPI device at all when using UEFI.
|
||||
*/
|
||||
scope = aml_scope("\\_SB");
|
||||
- acpi_dsdt_add_cpus(scope, vms);
|
||||
+ acpi_dsdt_add_cpus(scope, vms, &memmap[VIRT_CPUFREQ]);
|
||||
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
|
||||
(irqmap[VIRT_UART] + ARM_SPI_BASE));
|
||||
if (vmc->acpi_expose_flash) {
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 529c0d38b6..0538d258fa 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -154,6 +154,7 @@ static const MemMapEntry base_memmap[] = {
|
||||
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
|
||||
[VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
|
||||
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
|
||||
+ [VIRT_CPUFREQ] = { 0x0b000000, 0x00010000 },
|
||||
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
|
||||
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
|
||||
[VIRT_SECURE_MEM] = { 0x0e000000, 0x01000000 },
|
||||
@@ -931,6 +932,16 @@ static void create_uart(const VirtMachineState *vms, int uart,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
+static void create_cpufreq(const VirtMachineState *vms, MemoryRegion *mem)
|
||||
+{
|
||||
+ hwaddr base = vms->memmap[VIRT_CPUFREQ].base;
|
||||
+ DeviceState *dev = qdev_new("cpufreq");
|
||||
+ SysBusDevice *s = SYS_BUS_DEVICE(dev);
|
||||
+
|
||||
+ sysbus_realize_and_unref(s, &error_fatal);
|
||||
+ memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
|
||||
+}
|
||||
+
|
||||
static void create_rtc(const VirtMachineState *vms)
|
||||
{
|
||||
char *nodename;
|
||||
@@ -2190,6 +2201,8 @@ static void machvirt_init(MachineState *machine)
|
||||
|
||||
create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
|
||||
|
||||
+ create_cpufreq(vms, sysmem);
|
||||
+
|
||||
if (vms->secure) {
|
||||
create_secure_ram(vms, secure_sysmem, secure_tag_sysmem);
|
||||
create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
|
||||
diff --git a/hw/char/Kconfig b/hw/char/Kconfig
|
||||
index 6b6cf2fc1d..335a60c2c1 100644
|
||||
--- a/hw/char/Kconfig
|
||||
+++ b/hw/char/Kconfig
|
||||
@@ -71,3 +71,7 @@ config GOLDFISH_TTY
|
||||
|
||||
config SHAKTI_UART
|
||||
bool
|
||||
+
|
||||
+config CPUFREQ
|
||||
+ bool
|
||||
+ default y
|
||||
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
|
||||
index c97e8633ad..ab86583228 100644
|
||||
--- a/include/hw/acpi/acpi-defs.h
|
||||
+++ b/include/hw/acpi/acpi-defs.h
|
||||
@@ -92,4 +92,42 @@ typedef struct AcpiFadtData {
|
||||
#define ACPI_FADT_ARM_PSCI_COMPLIANT (1 << 0)
|
||||
#define ACPI_FADT_ARM_PSCI_USE_HVC (1 << 1)
|
||||
|
||||
+/*
|
||||
+ * CPPC register definition from kernel header
|
||||
+ * include/acpi/cppc_acpi.h
|
||||
+ * The last element is newly added for easy use
|
||||
+ */
|
||||
+enum cppc_regs {
|
||||
+ HIGHEST_PERF,
|
||||
+ NOMINAL_PERF,
|
||||
+ LOW_NON_LINEAR_PERF,
|
||||
+ LOWEST_PERF,
|
||||
+ GUARANTEED_PERF,
|
||||
+ DESIRED_PERF,
|
||||
+ MIN_PERF,
|
||||
+ MAX_PERF,
|
||||
+ PERF_REDUC_TOLERANCE,
|
||||
+ TIME_WINDOW,
|
||||
+ CTR_WRAP_TIME,
|
||||
+ REFERENCE_CTR,
|
||||
+ DELIVERED_CTR,
|
||||
+ PERF_LIMITED,
|
||||
+ ENABLE,
|
||||
+ AUTO_SEL_ENABLE,
|
||||
+ AUTO_ACT_WINDOW,
|
||||
+ ENERGY_PERF,
|
||||
+ REFERENCE_PERF,
|
||||
+ LOWEST_FREQ,
|
||||
+ NOMINAL_FREQ,
|
||||
+ CPPC_REG_COUNT,
|
||||
+};
|
||||
+
|
||||
+#define CPPC_REG_PER_CPU_STRIDE 0x40
|
||||
+
|
||||
+/*
|
||||
+ * Offset for each CPPC register; -1 for unavailable
|
||||
+ * The whole register space is unavailable if desired perf offset is -1.
|
||||
+ */
|
||||
+extern int cppc_regs_offset[CPPC_REG_COUNT];
|
||||
+
|
||||
#endif
|
||||
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
|
||||
index 8e8ad8029e..2e00d2e208 100644
|
||||
--- a/include/hw/acpi/aml-build.h
|
||||
+++ b/include/hw/acpi/aml-build.h
|
||||
@@ -429,6 +429,9 @@ Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
|
||||
uint8_t channel);
|
||||
Aml *aml_sleep(uint64_t msec);
|
||||
Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source);
|
||||
+Aml *aml_generic_register(AmlRegionSpace rs, uint8_t reg_width,
|
||||
+ uint8_t reg_offset, AmlAccessType type,
|
||||
+ uint64_t addr);
|
||||
|
||||
/* Block AML object primitives */
|
||||
Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index dc6b66ffc8..a4356cf736 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -70,6 +70,7 @@ enum {
|
||||
VIRT_GIC_REDIST,
|
||||
VIRT_SMMU,
|
||||
VIRT_UART,
|
||||
+ VIRT_CPUFREQ,
|
||||
VIRT_MMIO,
|
||||
VIRT_RTC,
|
||||
VIRT_FW_CFG,
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
113
hw-acpi-aml-build-Improve-scalability-of-PPTT-genera.patch
Normal file
113
hw-acpi-aml-build-Improve-scalability-of-PPTT-genera.patch
Normal file
@ -0,0 +1,113 @@
|
||||
From 66c935b435d90ef9c1ae4446c5edc07cbd8ba0ed Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Fri, 7 Jan 2022 16:32:29 +0800
|
||||
Subject: [PATCH 17/24] hw/acpi/aml-build: Improve scalability of PPTT
|
||||
generation
|
||||
|
||||
Use g_queue APIs to reduce the nested loops and code indentation
|
||||
with the processor hierarchy levels increasing. Consenquently,
|
||||
it's more scalable to add new topology level to build_pptt.
|
||||
|
||||
No functional change intended.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Message-id: 20220107083232.16256-4-wangyanan55@huawei.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
hw/acpi/aml-build.c | 50 +++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 32 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
||||
index b3b3310df3..6aaedca2e5 100644
|
||||
--- a/hw/acpi/aml-build.c
|
||||
+++ b/hw/acpi/aml-build.c
|
||||
@@ -2001,7 +2001,10 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
|
||||
void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
const char *oem_id, const char *oem_table_id)
|
||||
{
|
||||
- int pptt_start = table_data->len;
|
||||
+ GQueue *list = g_queue_new();
|
||||
+ guint pptt_start = table_data->len;
|
||||
+ guint parent_offset;
|
||||
+ guint length, i;
|
||||
int uid = 0;
|
||||
int socket;
|
||||
AcpiTable table = { .sig = "PPTT", .rev = 2,
|
||||
@@ -2010,9 +2013,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
acpi_table_begin(&table, table_data);
|
||||
|
||||
for (socket = 0; socket < ms->smp.sockets; socket++) {
|
||||
- uint32_t socket_offset = table_data->len - pptt_start;
|
||||
- int core;
|
||||
-
|
||||
+ g_queue_push_tail(list,
|
||||
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
||||
build_processor_hierarchy_node(
|
||||
table_data,
|
||||
/*
|
||||
@@ -2021,35 +2023,47 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
*/
|
||||
(1 << 0),
|
||||
0, socket, NULL, 0);
|
||||
+ }
|
||||
|
||||
- for (core = 0; core < ms->smp.cores; core++) {
|
||||
- uint32_t core_offset = table_data->len - pptt_start;
|
||||
- int thread;
|
||||
+ length = g_queue_get_length(list);
|
||||
+ for (i = 0; i < length; i++) {
|
||||
+ int core;
|
||||
|
||||
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
||||
+ for (core = 0; core < ms->smp.cores; core++) {
|
||||
if (ms->smp.threads > 1) {
|
||||
+ g_queue_push_tail(list,
|
||||
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
||||
build_processor_hierarchy_node(
|
||||
table_data,
|
||||
(0 << 0), /* not a physical package */
|
||||
- socket_offset, core, NULL, 0);
|
||||
-
|
||||
- for (thread = 0; thread < ms->smp.threads; thread++) {
|
||||
- build_processor_hierarchy_node(
|
||||
- table_data,
|
||||
- (1 << 1) | /* ACPI Processor ID valid */
|
||||
- (1 << 2) | /* Processor is a Thread */
|
||||
- (1 << 3), /* Node is a Leaf */
|
||||
- core_offset, uid++, NULL, 0);
|
||||
- }
|
||||
+ parent_offset, core, NULL, 0);
|
||||
} else {
|
||||
build_processor_hierarchy_node(
|
||||
table_data,
|
||||
(1 << 1) | /* ACPI Processor ID valid */
|
||||
(1 << 3), /* Node is a Leaf */
|
||||
- socket_offset, uid++, NULL, 0);
|
||||
+ parent_offset, uid++, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ length = g_queue_get_length(list);
|
||||
+ for (i = 0; i < length; i++) {
|
||||
+ int thread;
|
||||
+
|
||||
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
||||
+ for (thread = 0; thread < ms->smp.threads; thread++) {
|
||||
+ build_processor_hierarchy_node(
|
||||
+ table_data,
|
||||
+ (1 << 1) | /* ACPI Processor ID valid */
|
||||
+ (1 << 2) | /* Processor is a Thread */
|
||||
+ (1 << 3), /* Node is a Leaf */
|
||||
+ parent_offset, uid++, NULL, 0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ g_queue_free(list);
|
||||
acpi_table_end(linker, &table);
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
56
hw-acpi-aml-build-Support-cluster-level-in-PPTT-gene.patch
Normal file
56
hw-acpi-aml-build-Support-cluster-level-in-PPTT-gene.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 9c16924ba0a77c34246b69e8b1faee219f266445 Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Fri, 7 Jan 2022 16:32:31 +0800
|
||||
Subject: [PATCH 19/24] hw/acpi/aml-build: Support cluster level in PPTT
|
||||
generation
|
||||
|
||||
Support CPU cluster topology level in generation of ACPI
|
||||
Processor Properties Topology Table (PPTT).
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Message-id: 20220107083232.16256-6-wangyanan55@huawei.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
hw/acpi/aml-build.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
||||
index 6aaedca2e5..bb2cad63b5 100644
|
||||
--- a/hw/acpi/aml-build.c
|
||||
+++ b/hw/acpi/aml-build.c
|
||||
@@ -2001,6 +2001,7 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
|
||||
void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
const char *oem_id, const char *oem_table_id)
|
||||
{
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
GQueue *list = g_queue_new();
|
||||
guint pptt_start = table_data->len;
|
||||
guint parent_offset;
|
||||
@@ -2025,6 +2026,23 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
0, socket, NULL, 0);
|
||||
}
|
||||
|
||||
+ if (mc->smp_props.clusters_supported) {
|
||||
+ length = g_queue_get_length(list);
|
||||
+ for (i = 0; i < length; i++) {
|
||||
+ int cluster;
|
||||
+
|
||||
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
||||
+ for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
|
||||
+ g_queue_push_tail(list,
|
||||
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
||||
+ build_processor_hierarchy_node(
|
||||
+ table_data,
|
||||
+ (0 << 0), /* not a physical package */
|
||||
+ parent_offset, cluster, NULL, 0);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
length = g_queue_get_length(list);
|
||||
for (i = 0; i < length; i++) {
|
||||
int core;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
69
hw-arm-virt-Support-CPU-cluster-on-ARM-virt-machine.patch
Normal file
69
hw-arm-virt-Support-CPU-cluster-on-ARM-virt-machine.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From 1fab7ee365c8daccedd19d3a1be56babe36afcc6 Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Fri, 7 Jan 2022 16:32:27 +0800
|
||||
Subject: [PATCH 15/24] hw/arm/virt: Support CPU cluster on ARM virt machine
|
||||
|
||||
ARM64 machines like Kunpeng Family Server Chips have a level
|
||||
of hardware topology in which a group of CPU cores share L3
|
||||
cache tag or L2 cache. For example, Kunpeng 920 typically
|
||||
has 6 or 8 clusters in each NUMA node (also represent range
|
||||
of CPU die), and each cluster has 4 CPU cores. All clusters
|
||||
share L3 cache data, but CPU cores in each cluster share a
|
||||
local L3 tag.
|
||||
|
||||
Running a guest kernel with Cluster-Aware Scheduling on the
|
||||
Hosts which have physical clusters, if we can design a vCPU
|
||||
topology with cluster level for guest kernel and then have
|
||||
a dedicated vCPU pinning, the guest will gain scheduling
|
||||
performance improvement from cache affinity of CPU cluster.
|
||||
|
||||
So let's enable the support for this new parameter on ARM
|
||||
virt machines. After this patch, we can define a 4-level
|
||||
CPU hierarchy like: cpus=*,maxcpus=*,sockets=*,clusters=*,
|
||||
cores=*,threads=*.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Message-id: 20220107083232.16256-2-wangyanan55@huawei.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
hw/arm/virt.c | 1 +
|
||||
qemu-options.hx | 10 ++++++++++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 3c972fdab0..6ca9cbe2cf 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -2704,6 +2704,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
hc->unplug_request = virt_machine_device_unplug_request_cb;
|
||||
hc->unplug = virt_machine_device_unplug_cb;
|
||||
mc->nvdimm_supported = true;
|
||||
+ mc->smp_props.clusters_supported = true;
|
||||
mc->auto_enable_numa_with_memhp = true;
|
||||
mc->auto_enable_numa_with_memdev = true;
|
||||
mc->default_ram_id = "mach-virt.ram";
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 0f26f7dad7..74d335e4c3 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -277,6 +277,16 @@ SRST
|
||||
|
||||
-smp 16,sockets=2,dies=2,cores=2,threads=2,maxcpus=16
|
||||
|
||||
+ The following sub-option defines a CPU topology hierarchy (2 sockets
|
||||
+ totally on the machine, 2 clusters per socket, 2 cores per cluster,
|
||||
+ 2 threads per core) for ARM virt machines which support sockets/clusters
|
||||
+ /cores/threads. Some members of the option can be omitted but their values
|
||||
+ will be automatically computed:
|
||||
+
|
||||
+ ::
|
||||
+
|
||||
+ -smp 16,sockets=2,clusters=2,cores=2,threads=2,maxcpus=16
|
||||
+
|
||||
Historically preference was given to the coarsest topology parameters
|
||||
when computing missing values (ie sockets preferred over cores, which
|
||||
were preferred over threads), however, this behaviour is considered
|
||||
--
|
||||
2.27.0
|
||||
|
||||
57
hw-arm-virt-Support-cluster-level-in-DT-cpu-map.patch
Normal file
57
hw-arm-virt-Support-cluster-level-in-DT-cpu-map.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 38d9ae59b9344f13198e6b4de03b04787bd6b89d Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Fri, 7 Jan 2022 16:32:28 +0800
|
||||
Subject: [PATCH 16/24] hw/arm/virt: Support cluster level in DT cpu-map
|
||||
|
||||
Support one cluster level between core and physical package in the
|
||||
cpu-map of Arm/virt devicetree. This is also consistent with Linux
|
||||
Doc "Documentation/devicetree/bindings/cpu/cpu-topology.txt".
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Message-id: 20220107083232.16256-3-wangyanan55@huawei.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
hw/arm/virt.c | 15 ++++++++-------
|
||||
1 file changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 6ca9cbe2cf..ddcb73f714 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -434,9 +434,8 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
* can contain several layers of clustering within a single physical
|
||||
* package and cluster nodes can be contained in parent cluster nodes.
|
||||
*
|
||||
- * Given that cluster is not yet supported in the vCPU topology,
|
||||
- * we currently generate one cluster node within each socket node
|
||||
- * by default.
|
||||
+ * Note: currently we only support one layer of clustering within
|
||||
+ * each physical package.
|
||||
*/
|
||||
qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
|
||||
|
||||
@@ -446,14 +445,16 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
|
||||
if (ms->smp.threads > 1) {
|
||||
map_path = g_strdup_printf(
|
||||
- "/cpus/cpu-map/socket%d/cluster0/core%d/thread%d",
|
||||
- cpu / (ms->smp.cores * ms->smp.threads),
|
||||
+ "/cpus/cpu-map/socket%d/cluster%d/core%d/thread%d",
|
||||
+ cpu / (ms->smp.clusters * ms->smp.cores * ms->smp.threads),
|
||||
+ (cpu / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters,
|
||||
(cpu / ms->smp.threads) % ms->smp.cores,
|
||||
cpu % ms->smp.threads);
|
||||
} else {
|
||||
map_path = g_strdup_printf(
|
||||
- "/cpus/cpu-map/socket%d/cluster0/core%d",
|
||||
- cpu / ms->smp.cores,
|
||||
+ "/cpus/cpu-map/socket%d/cluster%d/core%d",
|
||||
+ cpu / (ms->smp.clusters * ms->smp.cores),
|
||||
+ (cpu / ms->smp.cores) % ms->smp.clusters,
|
||||
cpu % ms->smp.cores);
|
||||
}
|
||||
qemu_fdt_add_path(ms->fdt, map_path);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
353
hw-arm64-add-vcpu-cache-info-support.patch
Normal file
353
hw-arm64-add-vcpu-cache-info-support.patch
Normal file
@ -0,0 +1,353 @@
|
||||
From c5cd762bb7513b6df07e26f4eb619dccbd1918b7 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Tue, 8 Feb 2022 11:31:15 +0800
|
||||
Subject: [PATCH 23/24] hw/arm64: add vcpu cache info support
|
||||
|
||||
Support VCPU Cache info by dtb and PPTT table, including L1, L2 and L3 Cache.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Honghao <honghao5@huawei.com>
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
---
|
||||
hw/acpi/aml-build.c | 158 ++++++++++++++++++++++++++++++++++++
|
||||
hw/arm/virt.c | 72 ++++++++++++++++
|
||||
include/hw/acpi/aml-build.h | 47 +++++++++++
|
||||
tests/data/acpi/virt/PPTT | Bin 96 -> 208 bytes
|
||||
4 files changed, 277 insertions(+)
|
||||
|
||||
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
||||
index bb2cad63b5..bebf49622b 100644
|
||||
--- a/hw/acpi/aml-build.c
|
||||
+++ b/hw/acpi/aml-build.c
|
||||
@@ -1994,6 +1994,163 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef __aarch64__
|
||||
+/*
|
||||
+ * ACPI spec, Revision 6.3
|
||||
+ * 5.2.29.2 Cache Type Structure (Type 1)
|
||||
+ */
|
||||
+static void build_cache_hierarchy_node(GArray *tbl, uint32_t next_level,
|
||||
+ uint32_t cache_type)
|
||||
+{
|
||||
+ build_append_byte(tbl, 1);
|
||||
+ build_append_byte(tbl, 24);
|
||||
+ build_append_int_noprefix(tbl, 0, 2);
|
||||
+ build_append_int_noprefix(tbl, 127, 4);
|
||||
+ build_append_int_noprefix(tbl, next_level, 4);
|
||||
+
|
||||
+ switch (cache_type) {
|
||||
+ case ARM_L1D_CACHE: /* L1 dcache info */
|
||||
+ build_append_int_noprefix(tbl, ARM_L1DCACHE_SIZE, 4);
|
||||
+ build_append_int_noprefix(tbl, ARM_L1DCACHE_SETS, 4);
|
||||
+ build_append_byte(tbl, ARM_L1DCACHE_ASSOCIATIVITY);
|
||||
+ build_append_byte(tbl, ARM_L1DCACHE_ATTRIBUTES);
|
||||
+ build_append_int_noprefix(tbl, ARM_L1DCACHE_LINE_SIZE, 2);
|
||||
+ break;
|
||||
+ case ARM_L1I_CACHE: /* L1 icache info */
|
||||
+ build_append_int_noprefix(tbl, ARM_L1ICACHE_SIZE, 4);
|
||||
+ build_append_int_noprefix(tbl, ARM_L1ICACHE_SETS, 4);
|
||||
+ build_append_byte(tbl, ARM_L1ICACHE_ASSOCIATIVITY);
|
||||
+ build_append_byte(tbl, ARM_L1ICACHE_ATTRIBUTES);
|
||||
+ build_append_int_noprefix(tbl, ARM_L1ICACHE_LINE_SIZE, 2);
|
||||
+ break;
|
||||
+ case ARM_L2_CACHE: /* L2 cache info */
|
||||
+ build_append_int_noprefix(tbl, ARM_L2CACHE_SIZE, 4);
|
||||
+ build_append_int_noprefix(tbl, ARM_L2CACHE_SETS, 4);
|
||||
+ build_append_byte(tbl, ARM_L2CACHE_ASSOCIATIVITY);
|
||||
+ build_append_byte(tbl, ARM_L2CACHE_ATTRIBUTES);
|
||||
+ build_append_int_noprefix(tbl, ARM_L2CACHE_LINE_SIZE, 2);
|
||||
+ break;
|
||||
+ case ARM_L3_CACHE: /* L3 cache info */
|
||||
+ build_append_int_noprefix(tbl, ARM_L3CACHE_SIZE, 4);
|
||||
+ build_append_int_noprefix(tbl, ARM_L3CACHE_SETS, 4);
|
||||
+ build_append_byte(tbl, ARM_L3CACHE_ASSOCIATIVITY);
|
||||
+ build_append_byte(tbl, ARM_L3CACHE_ATTRIBUTES);
|
||||
+ build_append_int_noprefix(tbl, ARM_L3CACHE_LINE_SIZE, 2);
|
||||
+ break;
|
||||
+ default:
|
||||
+ build_append_int_noprefix(tbl, 0, 4);
|
||||
+ build_append_int_noprefix(tbl, 0, 4);
|
||||
+ build_append_byte(tbl, 0);
|
||||
+ build_append_byte(tbl, 0);
|
||||
+ build_append_int_noprefix(tbl, 0, 2);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * ACPI spec, Revision 6.3
|
||||
+ * 5.2.29 Processor Properties Topology Table (PPTT)
|
||||
+ */
|
||||
+void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
+ const char *oem_id, const char *oem_table_id)
|
||||
+{
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
+ GQueue *list = g_queue_new();
|
||||
+ guint pptt_start = table_data->len;
|
||||
+ guint parent_offset;
|
||||
+ guint length, i;
|
||||
+ int uid = 0;
|
||||
+ int socket;
|
||||
+ AcpiTable table = { .sig = "PPTT", .rev = 2,
|
||||
+ .oem_id = oem_id, .oem_table_id = oem_table_id };
|
||||
+
|
||||
+ acpi_table_begin(&table, table_data);
|
||||
+
|
||||
+ for (socket = 0; socket < ms->smp.sockets; socket++) {
|
||||
+ uint32_t l3_cache_offset = table_data->len - pptt_start;
|
||||
+ build_cache_hierarchy_node(table_data, 0, ARM_L3_CACHE);
|
||||
+
|
||||
+ g_queue_push_tail(list,
|
||||
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
||||
+ build_processor_hierarchy_node(
|
||||
+ table_data,
|
||||
+ /*
|
||||
+ * Physical package - represents the boundary
|
||||
+ * of a physical package
|
||||
+ */
|
||||
+ (1 << 0),
|
||||
+ 0, socket, &l3_cache_offset, 1);
|
||||
+ }
|
||||
+
|
||||
+ if (mc->smp_props.clusters_supported) {
|
||||
+ length = g_queue_get_length(list);
|
||||
+ for (i = 0; i < length; i++) {
|
||||
+ int cluster;
|
||||
+
|
||||
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
||||
+ for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
|
||||
+ g_queue_push_tail(list,
|
||||
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
||||
+ build_processor_hierarchy_node(
|
||||
+ table_data,
|
||||
+ (0 << 0), /* not a physical package */
|
||||
+ parent_offset, cluster, NULL, 0);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ length = g_queue_get_length(list);
|
||||
+ for (i = 0; i < length; i++) {
|
||||
+ int core;
|
||||
+
|
||||
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
||||
+ for (core = 0; core < ms->smp.cores; core++) {
|
||||
+ uint32_t priv_rsrc[3] = {};
|
||||
+ priv_rsrc[0] = table_data->len - pptt_start; /* L2 cache offset */
|
||||
+ build_cache_hierarchy_node(table_data, 0, ARM_L2_CACHE);
|
||||
+
|
||||
+ priv_rsrc[1] = table_data->len - pptt_start; /* L1 dcache offset */
|
||||
+ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1D_CACHE);
|
||||
+
|
||||
+ priv_rsrc[2] = table_data->len - pptt_start; /* L1 icache offset */
|
||||
+ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1I_CACHE);
|
||||
+
|
||||
+ if (ms->smp.threads > 1) {
|
||||
+ g_queue_push_tail(list,
|
||||
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
||||
+ build_processor_hierarchy_node(
|
||||
+ table_data,
|
||||
+ (0 << 0), /* not a physical package */
|
||||
+ parent_offset, core, priv_rsrc, 3);
|
||||
+ } else {
|
||||
+ build_processor_hierarchy_node(
|
||||
+ table_data,
|
||||
+ (1 << 1) | /* ACPI Processor ID valid */
|
||||
+ (1 << 3), /* Node is a Leaf */
|
||||
+ parent_offset, uid++, priv_rsrc, 3);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ length = g_queue_get_length(list);
|
||||
+ for (i = 0; i < length; i++) {
|
||||
+ int thread;
|
||||
+
|
||||
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
||||
+ for (thread = 0; thread < ms->smp.threads; thread++) {
|
||||
+ build_processor_hierarchy_node(
|
||||
+ table_data,
|
||||
+ (1 << 1) | /* ACPI Processor ID valid */
|
||||
+ (1 << 2) | /* Processor is a Thread */
|
||||
+ (1 << 3), /* Node is a Leaf */
|
||||
+ parent_offset, uid++, NULL, 0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ g_queue_free(list);
|
||||
+ acpi_table_end(linker, &table);
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
/*
|
||||
* ACPI spec, Revision 6.3
|
||||
* 5.2.29 Processor Properties Topology Table (PPTT)
|
||||
@@ -2084,6 +2241,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
g_queue_free(list);
|
||||
acpi_table_end(linker, &table);
|
||||
}
|
||||
+#endif
|
||||
|
||||
/* build rev1/rev3/rev5.1 FADT */
|
||||
void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index ddcb73f714..529c0d38b6 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -350,6 +350,72 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
|
||||
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
|
||||
}
|
||||
|
||||
+static void fdt_add_l3cache_nodes(const VirtMachineState *vms)
|
||||
+{
|
||||
+ int i;
|
||||
+ const MachineState *ms = MACHINE(vms);
|
||||
+ int cpus_per_socket = ms->smp.clusters * ms->smp.cores * ms->smp.threads;
|
||||
+ int sockets = (ms->smp.cpus + cpus_per_socket - 1) / cpus_per_socket;
|
||||
+
|
||||
+ for (i = 0; i < sockets; i++) {
|
||||
+ char *nodename = g_strdup_printf("/cpus/l3-cache%d", i);
|
||||
+
|
||||
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache");
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "cache-unified", "true");
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-level", 3);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x2000000);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 128);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 2048);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
||||
+ qemu_fdt_alloc_phandle(ms->fdt));
|
||||
+ g_free(nodename);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void fdt_add_l2cache_nodes(const VirtMachineState *vms)
|
||||
+{
|
||||
+ const MachineState *ms = MACHINE(vms);
|
||||
+ int cpus_per_socket = ms->smp.clusters * ms->smp.cores * ms->smp.threads;
|
||||
+ int cpu;
|
||||
+
|
||||
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
||||
+ char *next_path = g_strdup_printf("/cpus/l3-cache%d",
|
||||
+ cpu / cpus_per_socket);
|
||||
+ char *nodename = g_strdup_printf("/cpus/l2-cache%d", cpu);
|
||||
+
|
||||
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache");
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x80000);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 64);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 1024);
|
||||
+ qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache",
|
||||
+ next_path);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
||||
+ qemu_fdt_alloc_phandle(ms->fdt));
|
||||
+
|
||||
+ g_free(next_path);
|
||||
+ g_free(nodename);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void fdt_add_l1cache_prop(const VirtMachineState *vms,
|
||||
+ char *nodename, int cpu)
|
||||
+{
|
||||
+ const MachineState *ms = MACHINE(vms);
|
||||
+ char *cachename = g_strdup_printf("/cpus/l2-cache%d", cpu);
|
||||
+
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-size", 0x10000);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-line-size", 64);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-sets", 256);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-size", 0x10000);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-line-size", 64);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-sets", 256);
|
||||
+ qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache",
|
||||
+ cachename);
|
||||
+ g_free(cachename);
|
||||
+}
|
||||
+
|
||||
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
{
|
||||
int cpu;
|
||||
@@ -384,6 +450,11 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", addr_cells);
|
||||
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
|
||||
|
||||
+ if (!vmc->no_cpu_topology) {
|
||||
+ fdt_add_l3cache_nodes(vms);
|
||||
+ fdt_add_l2cache_nodes(vms);
|
||||
+ }
|
||||
+
|
||||
for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
|
||||
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
|
||||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
|
||||
@@ -413,6 +484,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
}
|
||||
|
||||
if (!vmc->no_cpu_topology) {
|
||||
+ fdt_add_l1cache_prop(vms, nodename, cpu);
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
||||
qemu_fdt_alloc_phandle(ms->fdt));
|
||||
}
|
||||
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
|
||||
index 8346003a22..8e8ad8029e 100644
|
||||
--- a/include/hw/acpi/aml-build.h
|
||||
+++ b/include/hw/acpi/aml-build.h
|
||||
@@ -221,6 +221,53 @@ struct AcpiBuildTables {
|
||||
BIOSLinker *linker;
|
||||
} AcpiBuildTables;
|
||||
|
||||
+#ifdef __aarch64__
|
||||
+/* Definitions of the hardcoded cache info*/
|
||||
+
|
||||
+typedef enum {
|
||||
+ ARM_L1D_CACHE,
|
||||
+ ARM_L1I_CACHE,
|
||||
+ ARM_L2_CACHE,
|
||||
+ ARM_L3_CACHE
|
||||
+} ArmCacheType;
|
||||
+
|
||||
+/* L1 data cache: */
|
||||
+#define ARM_L1DCACHE_SIZE 65536
|
||||
+#define ARM_L1DCACHE_SETS 256
|
||||
+#define ARM_L1DCACHE_ASSOCIATIVITY 4
|
||||
+#define ARM_L1DCACHE_ATTRIBUTES 2
|
||||
+#define ARM_L1DCACHE_LINE_SIZE 64
|
||||
+
|
||||
+/* L1 instruction cache: */
|
||||
+#define ARM_L1ICACHE_SIZE 65536
|
||||
+#define ARM_L1ICACHE_SETS 256
|
||||
+#define ARM_L1ICACHE_ASSOCIATIVITY 4
|
||||
+#define ARM_L1ICACHE_ATTRIBUTES 4
|
||||
+#define ARM_L1ICACHE_LINE_SIZE 64
|
||||
+
|
||||
+/* Level 2 unified cache: */
|
||||
+#define ARM_L2CACHE_SIZE 524288
|
||||
+#define ARM_L2CACHE_SETS 1024
|
||||
+#define ARM_L2CACHE_ASSOCIATIVITY 8
|
||||
+#define ARM_L2CACHE_ATTRIBUTES 10
|
||||
+#define ARM_L2CACHE_LINE_SIZE 64
|
||||
+
|
||||
+/* Level 3 unified cache: */
|
||||
+#define ARM_L3CACHE_SIZE 33554432
|
||||
+#define ARM_L3CACHE_SETS 2048
|
||||
+#define ARM_L3CACHE_ASSOCIATIVITY 15
|
||||
+#define ARM_L3CACHE_ATTRIBUTES 10
|
||||
+#define ARM_L3CACHE_LINE_SIZE 128
|
||||
+
|
||||
+struct offset_status {
|
||||
+ uint32_t parent;
|
||||
+ uint32_t l2_offset;
|
||||
+ uint32_t l1d_offset;
|
||||
+ uint32_t l1i_offset;
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
typedef
|
||||
struct CrsRangeEntry {
|
||||
uint64_t base;
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
114
hw-core-Rename-smp_parse-machine_parse_smp_config.patch
Normal file
114
hw-core-Rename-smp_parse-machine_parse_smp_config.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From 2ce1daae407033e689a559b7346523b18651ee0a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Thu, 11 Nov 2021 10:21:23 +0100
|
||||
Subject: [PATCH 09/24] hw/core: Rename smp_parse() ->
|
||||
machine_parse_smp_config()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
All methods related to MachineState are prefixed with "machine_".
|
||||
smp_parse() does not need to be an exception. Rename it and
|
||||
const'ify the SMPConfiguration argument, since it doesn't need
|
||||
to be modified.
|
||||
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Tested-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211216132015.815493-9-philmd@redhat.com>
|
||||
---
|
||||
hw/core/machine-smp.c | 6 ++++--
|
||||
hw/core/machine.c | 2 +-
|
||||
include/hw/boards.h | 3 ++-
|
||||
tests/unit/test-smp-parse.c | 8 ++++----
|
||||
4 files changed, 11 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
|
||||
index 116a0cbbfa..2cbfd57429 100644
|
||||
--- a/hw/core/machine-smp.c
|
||||
+++ b/hw/core/machine-smp.c
|
||||
@@ -44,7 +44,8 @@ static char *cpu_hierarchy_to_string(MachineState *ms)
|
||||
}
|
||||
|
||||
/*
|
||||
- * smp_parse - Generic function used to parse the given SMP configuration
|
||||
+ * machine_parse_smp_config: Generic function used to parse the given
|
||||
+ * SMP configuration
|
||||
*
|
||||
* Any missing parameter in "cpus/maxcpus/sockets/cores/threads" will be
|
||||
* automatically computed based on the provided ones.
|
||||
@@ -63,7 +64,8 @@ static char *cpu_hierarchy_to_string(MachineState *ms)
|
||||
* introduced topology members which are likely to be target specific should
|
||||
* be directly set as 1 if they are omitted (e.g. dies for PC since 4.1).
|
||||
*/
|
||||
-void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
|
||||
+void machine_parse_smp_config(MachineState *ms,
|
||||
+ const SMPConfiguration *config, Error **errp)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
unsigned cpus = config->has_cpus ? config->cpus : 0;
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index 53a99abc56..3993c534b9 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -761,7 +761,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name,
|
||||
return;
|
||||
}
|
||||
|
||||
- smp_parse(ms, config, errp);
|
||||
+ machine_parse_smp_config(ms, config, errp);
|
||||
}
|
||||
|
||||
static void machine_class_init(ObjectClass *oc, void *data)
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index 9c1c190104..7597cec440 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -34,7 +34,8 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
|
||||
void machine_set_cpu_numa_node(MachineState *machine,
|
||||
const CpuInstanceProperties *props,
|
||||
Error **errp);
|
||||
-void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp);
|
||||
+void machine_parse_smp_config(MachineState *ms,
|
||||
+ const SMPConfiguration *config, Error **errp);
|
||||
|
||||
/**
|
||||
* machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index 0f98c9509e..b6df8137fc 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -337,7 +337,7 @@ static const struct SMPTestData data_with_dies_invalid[] = {
|
||||
},
|
||||
};
|
||||
|
||||
-static char *smp_config_to_string(SMPConfiguration *config)
|
||||
+static char *smp_config_to_string(const SMPConfiguration *config)
|
||||
{
|
||||
return g_strdup_printf(
|
||||
"(SMPConfiguration) {\n"
|
||||
@@ -371,7 +371,7 @@ static char *cpu_topology_to_string(const CpuTopology *topo)
|
||||
topo->cores, topo->threads, topo->max_cpus);
|
||||
}
|
||||
|
||||
-static void check_parse(MachineState *ms, SMPConfiguration *config,
|
||||
+static void check_parse(MachineState *ms, const SMPConfiguration *config,
|
||||
const CpuTopology *expect_topo, const char *expect_err,
|
||||
bool is_valid)
|
||||
{
|
||||
@@ -380,8 +380,8 @@ static void check_parse(MachineState *ms, SMPConfiguration *config,
|
||||
g_autofree char *output_topo_str = NULL;
|
||||
Error *err = NULL;
|
||||
|
||||
- /* call the generic parser smp_parse() */
|
||||
- smp_parse(ms, config, &err);
|
||||
+ /* call the generic parser */
|
||||
+ machine_parse_smp_config(ms, config, &err);
|
||||
|
||||
output_topo_str = cpu_topology_to_string(&ms->smp);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
283
hw-core-machine-Introduce-CPU-cluster-topology-suppo.patch
Normal file
283
hw-core-machine-Introduce-CPU-cluster-topology-suppo.patch
Normal file
@ -0,0 +1,283 @@
|
||||
From bf4a20a82bd4804842dd2960db30e0be7ecb2d32 Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Tue, 28 Dec 2021 17:22:09 +0800
|
||||
Subject: [PATCH 11/24] hw/core/machine: Introduce CPU cluster topology support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The new Cluster-Aware Scheduling support has landed in Linux 5.16,
|
||||
which has been proved to benefit the scheduling performance (e.g.
|
||||
load balance and wake_affine strategy) on both x86_64 and AArch64.
|
||||
|
||||
So now in Linux 5.16 we have four-level arch-neutral CPU topology
|
||||
definition like below and a new scheduler level for clusters.
|
||||
struct cpu_topology {
|
||||
int thread_id;
|
||||
int core_id;
|
||||
int cluster_id;
|
||||
int package_id;
|
||||
int llc_id;
|
||||
cpumask_t thread_sibling;
|
||||
cpumask_t core_sibling;
|
||||
cpumask_t cluster_sibling;
|
||||
cpumask_t llc_sibling;
|
||||
}
|
||||
|
||||
A cluster generally means a group of CPU cores which share L2 cache
|
||||
or other mid-level resources, and it is the shared resources that
|
||||
is used to improve scheduler's behavior. From the point of view of
|
||||
the size range, it's between CPU die and CPU core. For example, on
|
||||
some ARM64 Kunpeng servers, we have 6 clusters in each NUMA node,
|
||||
and 4 CPU cores in each cluster. The 4 CPU cores share a separate
|
||||
L2 cache and a L3 cache tag, which brings cache affinity advantage.
|
||||
|
||||
In virtualization, on the Hosts which have pClusters (physical
|
||||
clusters), if we can design a vCPU topology with cluster level for
|
||||
guest kernel and have a dedicated vCPU pinning. A Cluster-Aware
|
||||
Guest kernel can also make use of the cache affinity of CPU clusters
|
||||
to gain similar scheduling performance.
|
||||
|
||||
This patch adds infrastructure for CPU cluster level topology
|
||||
configuration and parsing, so that the user can specify cluster
|
||||
parameter if their machines support it.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Message-Id: <20211228092221.21068-3-wangyanan55@huawei.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
[PMD: Added '(since 7.0)' to @clusters in qapi/machine.json]
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
---
|
||||
hw/core/machine-smp.c | 26 +++++++++++++++++++-------
|
||||
hw/core/machine.c | 3 +++
|
||||
include/hw/boards.h | 6 +++++-
|
||||
qapi/machine.json | 5 ++++-
|
||||
qemu-options.hx | 7 ++++---
|
||||
softmmu/vl.c | 3 +++
|
||||
6 files changed, 38 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
|
||||
index 2cbfd57429..b39ed21e65 100644
|
||||
--- a/hw/core/machine-smp.c
|
||||
+++ b/hw/core/machine-smp.c
|
||||
@@ -37,6 +37,10 @@ static char *cpu_hierarchy_to_string(MachineState *ms)
|
||||
g_string_append_printf(s, " * dies (%u)", ms->smp.dies);
|
||||
}
|
||||
|
||||
+ if (mc->smp_props.clusters_supported) {
|
||||
+ g_string_append_printf(s, " * clusters (%u)", ms->smp.clusters);
|
||||
+ }
|
||||
+
|
||||
g_string_append_printf(s, " * cores (%u)", ms->smp.cores);
|
||||
g_string_append_printf(s, " * threads (%u)", ms->smp.threads);
|
||||
|
||||
@@ -71,6 +75,7 @@ void machine_parse_smp_config(MachineState *ms,
|
||||
unsigned cpus = config->has_cpus ? config->cpus : 0;
|
||||
unsigned sockets = config->has_sockets ? config->sockets : 0;
|
||||
unsigned dies = config->has_dies ? config->dies : 0;
|
||||
+ unsigned clusters = config->has_clusters ? config->clusters : 0;
|
||||
unsigned cores = config->has_cores ? config->cores : 0;
|
||||
unsigned threads = config->has_threads ? config->threads : 0;
|
||||
unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
|
||||
@@ -82,6 +87,7 @@ void machine_parse_smp_config(MachineState *ms,
|
||||
if ((config->has_cpus && config->cpus == 0) ||
|
||||
(config->has_sockets && config->sockets == 0) ||
|
||||
(config->has_dies && config->dies == 0) ||
|
||||
+ (config->has_clusters && config->clusters == 0) ||
|
||||
(config->has_cores && config->cores == 0) ||
|
||||
(config->has_threads && config->threads == 0) ||
|
||||
(config->has_maxcpus && config->maxcpus == 0)) {
|
||||
@@ -97,8 +103,13 @@ void machine_parse_smp_config(MachineState *ms,
|
||||
error_setg(errp, "dies not supported by this machine's CPU topology");
|
||||
return;
|
||||
}
|
||||
+ if (!mc->smp_props.clusters_supported && clusters > 1) {
|
||||
+ error_setg(errp, "clusters not supported by this machine's CPU topology");
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
dies = dies > 0 ? dies : 1;
|
||||
+ clusters = clusters > 0 ? clusters : 1;
|
||||
|
||||
/* compute missing values based on the provided ones */
|
||||
if (cpus == 0 && maxcpus == 0) {
|
||||
@@ -113,41 +124,42 @@ void machine_parse_smp_config(MachineState *ms,
|
||||
if (sockets == 0) {
|
||||
cores = cores > 0 ? cores : 1;
|
||||
threads = threads > 0 ? threads : 1;
|
||||
- sockets = maxcpus / (dies * cores * threads);
|
||||
+ sockets = maxcpus / (dies * clusters * cores * threads);
|
||||
} else if (cores == 0) {
|
||||
threads = threads > 0 ? threads : 1;
|
||||
- cores = maxcpus / (sockets * dies * threads);
|
||||
+ cores = maxcpus / (sockets * dies * clusters * threads);
|
||||
}
|
||||
} else {
|
||||
/* prefer cores over sockets since 6.2 */
|
||||
if (cores == 0) {
|
||||
sockets = sockets > 0 ? sockets : 1;
|
||||
threads = threads > 0 ? threads : 1;
|
||||
- cores = maxcpus / (sockets * dies * threads);
|
||||
+ cores = maxcpus / (sockets * dies * clusters * threads);
|
||||
} else if (sockets == 0) {
|
||||
threads = threads > 0 ? threads : 1;
|
||||
- sockets = maxcpus / (dies * cores * threads);
|
||||
+ sockets = maxcpus / (dies * clusters * cores * threads);
|
||||
}
|
||||
}
|
||||
|
||||
/* try to calculate omitted threads at last */
|
||||
if (threads == 0) {
|
||||
- threads = maxcpus / (sockets * dies * cores);
|
||||
+ threads = maxcpus / (sockets * dies * clusters * cores);
|
||||
}
|
||||
}
|
||||
|
||||
- maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads;
|
||||
+ maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * clusters * cores * threads;
|
||||
cpus = cpus > 0 ? cpus : maxcpus;
|
||||
|
||||
ms->smp.cpus = cpus;
|
||||
ms->smp.sockets = sockets;
|
||||
ms->smp.dies = dies;
|
||||
+ ms->smp.clusters = clusters;
|
||||
ms->smp.cores = cores;
|
||||
ms->smp.threads = threads;
|
||||
ms->smp.max_cpus = maxcpus;
|
||||
|
||||
/* sanity-check of the computed topology */
|
||||
- if (sockets * dies * cores * threads != maxcpus) {
|
||||
+ if (sockets * dies * clusters * cores * threads != maxcpus) {
|
||||
g_autofree char *topo_msg = cpu_hierarchy_to_string(ms);
|
||||
error_setg(errp, "Invalid CPU topology: "
|
||||
"product of the hierarchy must match maxcpus: "
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index 3993c534b9..a4a2df405f 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -742,10 +742,12 @@ static void machine_get_smp(Object *obj, Visitor *v, const char *name,
|
||||
.has_cpus = true, .cpus = ms->smp.cpus,
|
||||
.has_sockets = true, .sockets = ms->smp.sockets,
|
||||
.has_dies = true, .dies = ms->smp.dies,
|
||||
+ .has_clusters = true, .clusters = ms->smp.clusters,
|
||||
.has_cores = true, .cores = ms->smp.cores,
|
||||
.has_threads = true, .threads = ms->smp.threads,
|
||||
.has_maxcpus = true, .maxcpus = ms->smp.max_cpus,
|
||||
};
|
||||
+
|
||||
if (!visit_type_SMPConfiguration(v, name, &config, &error_abort)) {
|
||||
return;
|
||||
}
|
||||
@@ -932,6 +934,7 @@ static void machine_initfn(Object *obj)
|
||||
ms->smp.max_cpus = mc->default_cpus;
|
||||
ms->smp.sockets = 1;
|
||||
ms->smp.dies = 1;
|
||||
+ ms->smp.clusters = 1;
|
||||
ms->smp.cores = 1;
|
||||
ms->smp.threads = 1;
|
||||
}
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index 7597cec440..f49a2578ea 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -129,10 +129,12 @@ typedef struct {
|
||||
* SMPCompatProps:
|
||||
* @prefer_sockets - whether sockets are preferred over cores in smp parsing
|
||||
* @dies_supported - whether dies are supported by the machine
|
||||
+ * @clusters_supported - whether clusters are supported by the machine
|
||||
*/
|
||||
typedef struct {
|
||||
bool prefer_sockets;
|
||||
bool dies_supported;
|
||||
+ bool clusters_supported;
|
||||
} SMPCompatProps;
|
||||
|
||||
/**
|
||||
@@ -299,7 +301,8 @@ typedef struct DeviceMemoryState {
|
||||
* @cpus: the number of present logical processors on the machine
|
||||
* @sockets: the number of sockets on the machine
|
||||
* @dies: the number of dies in one socket
|
||||
- * @cores: the number of cores in one die
|
||||
+ * @clusters: the number of clusters in one die
|
||||
+ * @cores: the number of cores in one cluster
|
||||
* @threads: the number of threads in one core
|
||||
* @max_cpus: the maximum number of logical processors on the machine
|
||||
*/
|
||||
@@ -307,6 +310,7 @@ typedef struct CpuTopology {
|
||||
unsigned int cpus;
|
||||
unsigned int sockets;
|
||||
unsigned int dies;
|
||||
+ unsigned int clusters;
|
||||
unsigned int cores;
|
||||
unsigned int threads;
|
||||
unsigned int max_cpus;
|
||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||
index f1839acf20..8faa51074e 100644
|
||||
--- a/qapi/machine.json
|
||||
+++ b/qapi/machine.json
|
||||
@@ -1396,7 +1396,9 @@
|
||||
#
|
||||
# @dies: number of dies per socket in the CPU topology
|
||||
#
|
||||
-# @cores: number of cores per die in the CPU topology
|
||||
+# @clusters: number of clusters per die in the CPU topology (since 7.0)
|
||||
+#
|
||||
+# @cores: number of cores per cluster in the CPU topology
|
||||
#
|
||||
# @threads: number of threads per core in the CPU topology
|
||||
#
|
||||
@@ -1408,6 +1410,7 @@
|
||||
'*cpus': 'int',
|
||||
'*sockets': 'int',
|
||||
'*dies': 'int',
|
||||
+ '*clusters': 'int',
|
||||
'*cores': 'int',
|
||||
'*threads': 'int',
|
||||
'*maxcpus': 'int' } }
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 7a59db7764..0f26f7dad7 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -206,13 +206,14 @@ SRST
|
||||
ERST
|
||||
|
||||
DEF("smp", HAS_ARG, QEMU_OPTION_smp,
|
||||
- "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n"
|
||||
+ "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]\n"
|
||||
" set the number of initial CPUs to 'n' [default=1]\n"
|
||||
" maxcpus= maximum number of total CPUs, including\n"
|
||||
" offline CPUs for hotplug, etc\n"
|
||||
" sockets= number of sockets on the machine board\n"
|
||||
" dies= number of dies in one socket\n"
|
||||
- " cores= number of cores in one die\n"
|
||||
+ " clusters= number of clusters in one die\n"
|
||||
+ " cores= number of cores in one cluster\n"
|
||||
" threads= number of threads in one core\n"
|
||||
"Note: Different machines may have different subsets of the CPU topology\n"
|
||||
" parameters supported, so the actual meaning of the supported parameters\n"
|
||||
@@ -228,7 +229,7 @@ DEF("smp", HAS_ARG, QEMU_OPTION_smp,
|
||||
" must be set as 1 in the purpose of correct parsing.\n",
|
||||
QEMU_ARCH_ALL)
|
||||
SRST
|
||||
-``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]``
|
||||
+``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]``
|
||||
Simulate a SMP system with '\ ``n``\ ' CPUs initially present on
|
||||
the machine type board. On boards supporting CPU hotplug, the optional
|
||||
'\ ``maxcpus``\ ' parameter can be set to enable further CPUs to be
|
||||
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||
index 620a1f1367..d9e4c619d3 100644
|
||||
--- a/softmmu/vl.c
|
||||
+++ b/softmmu/vl.c
|
||||
@@ -726,6 +726,9 @@ static QemuOptsList qemu_smp_opts = {
|
||||
}, {
|
||||
.name = "dies",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
+ }, {
|
||||
+ .name = "clusters",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
}, {
|
||||
.name = "cores",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
35
qapi-machine.json-Fix-incorrect-description-for-die-.patch
Normal file
35
qapi-machine.json-Fix-incorrect-description-for-die-.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From b04e92ed13e49f666f62c8f3daa5746109caf17b Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Mon, 22 Nov 2021 11:26:51 +0800
|
||||
Subject: [PATCH 01/24] qapi/machine.json: Fix incorrect description for die-id
|
||||
|
||||
In terms of scope, die-id should mean "the die number within
|
||||
socket the CPU belongs to" instead of "the die number within
|
||||
node/board the CPU belongs to". Fix it to avoid confusing
|
||||
the Doc reader.
|
||||
|
||||
Fixes: 176d2cda0d ("i386/cpu: Consolidate die-id validity in smp context")
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-Id: <20211122032651.16064-1-wangyanan55@huawei.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
qapi/machine.json | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||
index 067e3f5378..f1839acf20 100644
|
||||
--- a/qapi/machine.json
|
||||
+++ b/qapi/machine.json
|
||||
@@ -867,7 +867,7 @@
|
||||
#
|
||||
# @node-id: NUMA node ID the CPU belongs to
|
||||
# @socket-id: socket number within node/board the CPU belongs to
|
||||
-# @die-id: die number within node/board the CPU belongs to (Since 4.1)
|
||||
+# @die-id: die number within socket the CPU belongs to (since 4.1)
|
||||
# @core-id: core number within die the CPU belongs to
|
||||
# @thread-id: thread number within core the CPU belongs to
|
||||
#
|
||||
--
|
||||
2.27.0
|
||||
|
||||
146
qemu-options-Improve-readability-of-SMP-related-Docs.patch
Normal file
146
qemu-options-Improve-readability-of-SMP-related-Docs.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From 07991b049fc9ebdb62c311eda1535ad4831625e5 Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Tue, 28 Dec 2021 17:22:08 +0800
|
||||
Subject: [PATCH 10/24] qemu-options: Improve readability of SMP related Docs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We have a description in qemu-options.hx for each CPU topology
|
||||
parameter to explain what it exactly means, and also an extra
|
||||
declaration for the target-specific one, e.g. "for PC only"
|
||||
when describing "dies", and "for PC, it's on one die" when
|
||||
describing "cores".
|
||||
|
||||
Now we are going to introduce one more non-generic parameter
|
||||
"clusters", it will make the Doc less readable and if we still
|
||||
continue to use the legacy way to describe it.
|
||||
|
||||
So let's at first make two tweaks of the Docs to improve the
|
||||
readability and also scalability:
|
||||
1) In the -help text: Delete the extra specific declaration and
|
||||
describe each topology parameter level by level. Then add a
|
||||
note to declare that different machines may support different
|
||||
subsets and the actual meaning of the supported parameters
|
||||
will vary accordingly.
|
||||
2) In the rST text: List all the sub-hierarchies currently
|
||||
supported in QEMU, and correspondingly give an example of
|
||||
-smp configuration for each of them.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211228092221.21068-2-wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
---
|
||||
qemu-options.hx | 76 ++++++++++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 59 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index ae2c6dbbfc..7a59db7764 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -207,14 +207,26 @@ ERST
|
||||
|
||||
DEF("smp", HAS_ARG, QEMU_OPTION_smp,
|
||||
"-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n"
|
||||
- " set the number of CPUs to 'n' [default=1]\n"
|
||||
+ " set the number of initial CPUs to 'n' [default=1]\n"
|
||||
" maxcpus= maximum number of total CPUs, including\n"
|
||||
" offline CPUs for hotplug, etc\n"
|
||||
- " sockets= number of discrete sockets in the system\n"
|
||||
- " dies= number of CPU dies on one socket (for PC only)\n"
|
||||
- " cores= number of CPU cores on one socket (for PC, it's on one die)\n"
|
||||
- " threads= number of threads on one CPU core\n",
|
||||
- QEMU_ARCH_ALL)
|
||||
+ " sockets= number of sockets on the machine board\n"
|
||||
+ " dies= number of dies in one socket\n"
|
||||
+ " cores= number of cores in one die\n"
|
||||
+ " threads= number of threads in one core\n"
|
||||
+ "Note: Different machines may have different subsets of the CPU topology\n"
|
||||
+ " parameters supported, so the actual meaning of the supported parameters\n"
|
||||
+ " will vary accordingly. For example, for a machine type that supports a\n"
|
||||
+ " three-level CPU hierarchy of sockets/cores/threads, the parameters will\n"
|
||||
+ " sequentially mean as below:\n"
|
||||
+ " sockets means the number of sockets on the machine board\n"
|
||||
+ " cores means the number of cores in one socket\n"
|
||||
+ " threads means the number of threads in one core\n"
|
||||
+ " For a particular machine type board, an expected CPU topology hierarchy\n"
|
||||
+ " can be defined through the supported sub-option. Unsupported parameters\n"
|
||||
+ " can also be provided in addition to the sub-option, but their values\n"
|
||||
+ " must be set as 1 in the purpose of correct parsing.\n",
|
||||
+ QEMU_ARCH_ALL)
|
||||
SRST
|
||||
``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]``
|
||||
Simulate a SMP system with '\ ``n``\ ' CPUs initially present on
|
||||
@@ -225,27 +237,57 @@ SRST
|
||||
initial CPU count will match the maximum number. When only one of them
|
||||
is given then the omitted one will be set to its counterpart's value.
|
||||
Both parameters may be specified, but the maximum number of CPUs must
|
||||
- be equal to or greater than the initial CPU count. Both parameters are
|
||||
- subject to an upper limit that is determined by the specific machine
|
||||
- type chosen.
|
||||
-
|
||||
- To control reporting of CPU topology information, the number of sockets,
|
||||
- dies per socket, cores per die, and threads per core can be specified.
|
||||
- The sum `` sockets * cores * dies * threads `` must be equal to the
|
||||
- maximum CPU count. CPU targets may only support a subset of the topology
|
||||
- parameters. Where a CPU target does not support use of a particular
|
||||
- topology parameter, its value should be assumed to be 1 for the purpose
|
||||
- of computing the CPU maximum count.
|
||||
+ be equal to or greater than the initial CPU count. Product of the
|
||||
+ CPU topology hierarchy must be equal to the maximum number of CPUs.
|
||||
+ Both parameters are subject to an upper limit that is determined by
|
||||
+ the specific machine type chosen.
|
||||
+
|
||||
+ To control reporting of CPU topology information, values of the topology
|
||||
+ parameters can be specified. Machines may only support a subset of the
|
||||
+ parameters and different machines may have different subsets supported
|
||||
+ which vary depending on capacity of the corresponding CPU targets. So
|
||||
+ for a particular machine type board, an expected topology hierarchy can
|
||||
+ be defined through the supported sub-option. Unsupported parameters can
|
||||
+ also be provided in addition to the sub-option, but their values must be
|
||||
+ set as 1 in the purpose of correct parsing.
|
||||
|
||||
Either the initial CPU count, or at least one of the topology parameters
|
||||
must be specified. The specified parameters must be greater than zero,
|
||||
explicit configuration like "cpus=0" is not allowed. Values for any
|
||||
omitted parameters will be computed from those which are given.
|
||||
+
|
||||
+ For example, the following sub-option defines a CPU topology hierarchy
|
||||
+ (2 sockets totally on the machine, 2 cores per socket, 2 threads per
|
||||
+ core) for a machine that only supports sockets/cores/threads.
|
||||
+ Some members of the option can be omitted but their values will be
|
||||
+ automatically computed:
|
||||
+
|
||||
+ ::
|
||||
+
|
||||
+ -smp 8,sockets=2,cores=2,threads=2,maxcpus=8
|
||||
+
|
||||
+ The following sub-option defines a CPU topology hierarchy (2 sockets
|
||||
+ totally on the machine, 2 dies per socket, 2 cores per die, 2 threads
|
||||
+ per core) for PC machines which support sockets/dies/cores/threads.
|
||||
+ Some members of the option can be omitted but their values will be
|
||||
+ automatically computed:
|
||||
+
|
||||
+ ::
|
||||
+
|
||||
+ -smp 16,sockets=2,dies=2,cores=2,threads=2,maxcpus=16
|
||||
+
|
||||
Historically preference was given to the coarsest topology parameters
|
||||
when computing missing values (ie sockets preferred over cores, which
|
||||
were preferred over threads), however, this behaviour is considered
|
||||
liable to change. Prior to 6.2 the preference was sockets over cores
|
||||
over threads. Since 6.2 the preference is cores over sockets over threads.
|
||||
+
|
||||
+ For example, the following option defines a machine board with 2 sockets
|
||||
+ of 1 core before 6.2 and 1 socket of 2 cores after 6.2:
|
||||
+
|
||||
+ ::
|
||||
+
|
||||
+ -smp 2
|
||||
ERST
|
||||
|
||||
DEF("numa", HAS_ARG, QEMU_OPTION_numa,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
55
qemu.spec
55
qemu.spec
@ -1,6 +1,6 @@
|
||||
Name: qemu
|
||||
Version: 6.2.0
|
||||
Release: 18
|
||||
Release: 19
|
||||
Epoch: 2
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
|
||||
@ -173,6 +173,30 @@ Patch0159: seabios-add-check-to-avoid-dereference-NULL-pointer.patch
|
||||
Patch0160: qemu-img-add-qemu-img-direct-create.patch
|
||||
Patch0161: log-Delete-redudant-qemu_log.patch
|
||||
Patch0162: bios-tables-test-Update-expected-q35-SSDT.dimmpxm-fi.patch
|
||||
Patch0163: qapi-machine.json-Fix-incorrect-description-for-die-.patch
|
||||
Patch0164: tests-unit-test-smp-parse-Pass-machine-type-as-argum.patch
|
||||
Patch0165: tests-unit-test-smp-parse-Split-the-generic-test-in-.patch
|
||||
Patch0166: tests-unit-test-smp-parse-Add-smp-with-dies-machine-.patch
|
||||
Patch0167: tests-unit-test-smp-parse-Add-smp-generic-invalid-ma.patch
|
||||
Patch0168: tests-unit-test-smp-parse-Add-smp-generic-valid-mach.patch
|
||||
Patch0169: tests-unit-test-smp-parse-Simplify-pointer-to-compou.patch
|
||||
Patch0170: tests-unit-test-smp-parse-Constify-some-pointer-stru.patch
|
||||
Patch0171: hw-core-Rename-smp_parse-machine_parse_smp_config.patch
|
||||
Patch0172: qemu-options-Improve-readability-of-SMP-related-Docs.patch
|
||||
Patch0173: hw-core-machine-Introduce-CPU-cluster-topology-suppo.patch
|
||||
Patch0174: tests-unit-test-smp-parse-Add-testcases-for-CPU-clus.patch
|
||||
Patch0175: tests-unit-test-smp-parse-No-need-to-explicitly-zero.patch
|
||||
Patch0176: tests-unit-test-smp-parse-Keep-default-MIN-MAX-CPUs-.patch
|
||||
Patch0177: hw-arm-virt-Support-CPU-cluster-on-ARM-virt-machine.patch
|
||||
Patch0178: hw-arm-virt-Support-cluster-level-in-DT-cpu-map.patch
|
||||
Patch0179: hw-acpi-aml-build-Improve-scalability-of-PPTT-genera.patch
|
||||
Patch0180: tests-acpi-bios-tables-test-Allow-changes-to-virt-PP.patch
|
||||
Patch0181: hw-acpi-aml-build-Support-cluster-level-in-PPTT-gene.patch
|
||||
Patch0182: tests-acpi-bios-table-test-Update-expected-virt-PPTT.patch
|
||||
Patch0183: softmmu-device_tree-Silence-compiler-warning-with-en.patch
|
||||
Patch0184: softmmu-device_tree-Remove-redundant-pointer-assignm.patch
|
||||
Patch0185: hw-arm64-add-vcpu-cache-info-support.patch
|
||||
Patch0186: arm64-Add-the-cpufreq-device-to-show-cpufreq-info-to.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: gcc
|
||||
@ -620,6 +644,35 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Feb 17 2022 imxcc <xingchaochao@huawei.com>
|
||||
- qapi/machine.json: Fix incorrect description for die-id
|
||||
- tests/unit/test-smp-parse: Pass machine type as
|
||||
- tests/unit/test-smp-parse: Split the 'generic' test in
|
||||
- tests/unit/test-smp-parse: Add 'smp-with-dies' machine
|
||||
- tests/unit/test-smp-parse: Add 'smp-generic-invalid'
|
||||
- tests/unit/test-smp-parse: Add 'smp-generic-valid'
|
||||
- tests/unit/test-smp-parse: Simplify pointer to compound
|
||||
- tests/unit/test-smp-parse: Constify some pointer/struct
|
||||
- hw/core: Rename smp_parse() ->
|
||||
- qemu-options: Improve readability of SMP related Docs
|
||||
- hw/core/machine: Introduce CPU cluster topology support
|
||||
- tests/unit/test-smp-parse: Add testcases for CPU
|
||||
- tests/unit/test-smp-parse: No need to explicitly zero
|
||||
- tests/unit/test-smp-parse: Keep default MIN/MAX CPUs in
|
||||
- hw/arm/virt: Support CPU cluster on ARM virt machine
|
||||
- hw/arm/virt: Support cluster level in DT cpu-map
|
||||
- hw/acpi/aml-build: Improve scalability of PPTT
|
||||
- tests/acpi/bios-tables-test: Allow changes to virt/PPTT
|
||||
- hw/acpi/aml-build: Support cluster level in PPTT
|
||||
- tests/acpi/bios-table-test: Update expected virt/PPTT
|
||||
- update BinDir
|
||||
- softmmu/device_tree: Silence compiler warning with
|
||||
- softmmu/device_tree: Remove redundant pointer
|
||||
- hw/arm64: add vcpu cache info support
|
||||
- update BinDir
|
||||
- arm64: Add the cpufreq device to show cpufreq info to
|
||||
- update BinDir
|
||||
|
||||
* Thu Feb 17 2022 imxcc <xingchaochao@huawei.com>
|
||||
- bios-tables-test: Update expected q35/SSDT.dimmpxm file
|
||||
- spec: add BinDir
|
||||
|
||||
58
softmmu-device_tree-Remove-redundant-pointer-assignm.patch
Normal file
58
softmmu-device_tree-Remove-redundant-pointer-assignm.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From ebf1ac6c0ead3d6fbc32466028c286588333c1ea Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Tue, 11 Jan 2022 11:27:58 +0800
|
||||
Subject: [PATCH 22/24] softmmu/device_tree: Remove redundant pointer
|
||||
assignment
|
||||
|
||||
The pointer assignment "const char *p = path;" in function
|
||||
qemu_fdt_add_path is unnecessary. Let's remove it and just
|
||||
use the "path" passed in. No functional change.
|
||||
|
||||
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-id: 20220111032758.27804-1-wangyanan55@huawei.com
|
||||
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
|
||||
---
|
||||
softmmu/device_tree.c | 9 ++++-----
|
||||
1 file changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
|
||||
index 9e96f5ecd5..8897c79ea4 100644
|
||||
--- a/softmmu/device_tree.c
|
||||
+++ b/softmmu/device_tree.c
|
||||
@@ -556,7 +556,6 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
|
||||
int qemu_fdt_add_path(void *fdt, const char *path)
|
||||
{
|
||||
const char *name;
|
||||
- const char *p = path;
|
||||
int namelen, retval;
|
||||
int parent = 0;
|
||||
|
||||
@@ -565,9 +564,9 @@ int qemu_fdt_add_path(void *fdt, const char *path)
|
||||
}
|
||||
|
||||
do {
|
||||
- name = p + 1;
|
||||
- p = strchr(name, '/');
|
||||
- namelen = p != NULL ? p - name : strlen(name);
|
||||
+ name = path + 1;
|
||||
+ path = strchr(name, '/');
|
||||
+ namelen = path != NULL ? path - name : strlen(name);
|
||||
|
||||
retval = fdt_subnode_offset_namelen(fdt, parent, name, namelen);
|
||||
if (retval < 0 && retval != -FDT_ERR_NOTFOUND) {
|
||||
@@ -584,7 +583,7 @@ int qemu_fdt_add_path(void *fdt, const char *path)
|
||||
}
|
||||
|
||||
parent = retval;
|
||||
- } while (p);
|
||||
+ } while (path);
|
||||
|
||||
return retval;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
60
softmmu-device_tree-Silence-compiler-warning-with-en.patch
Normal file
60
softmmu-device_tree-Silence-compiler-warning-with-en.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From ecc0eb93e8856321ad940a85970f0db14ab9f146 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Fri, 7 Jan 2022 14:38:44 +0100
|
||||
Subject: [PATCH 21/24] softmmu/device_tree: Silence compiler warning with
|
||||
--enable-sanitizers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If I configure my build with --enable-sanitizers, my GCC (v8.5.0)
|
||||
complains:
|
||||
|
||||
.../softmmu/device_tree.c: In function ‘qemu_fdt_add_path’:
|
||||
.../softmmu/device_tree.c:560:18: error: ‘retval’ may be used uninitialized
|
||||
in this function [-Werror=maybe-uninitialized]
|
||||
int namelen, retval;
|
||||
^~~~~~
|
||||
|
||||
It's a false warning since the while loop is always executed at least
|
||||
once (p has to be non-NULL, otherwise the derefence in the if-statement
|
||||
earlier will crash). Thus let's switch to a do-while loop here instead
|
||||
to make the compiler happy in all cases.
|
||||
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Message-id: 20220107133844.145039-1-thuth@redhat.com
|
||||
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
|
||||
---
|
||||
softmmu/device_tree.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
|
||||
index 3965c834ca..9e96f5ecd5 100644
|
||||
--- a/softmmu/device_tree.c
|
||||
+++ b/softmmu/device_tree.c
|
||||
@@ -564,7 +564,7 @@ int qemu_fdt_add_path(void *fdt, const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- while (p) {
|
||||
+ do {
|
||||
name = p + 1;
|
||||
p = strchr(name, '/');
|
||||
namelen = p != NULL ? p - name : strlen(name);
|
||||
@@ -584,7 +584,7 @@ int qemu_fdt_add_path(void *fdt, const char *path)
|
||||
}
|
||||
|
||||
parent = retval;
|
||||
- }
|
||||
+ } while (p);
|
||||
|
||||
return retval;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
110
tests-acpi-bios-table-test-Update-expected-virt-PPTT.patch
Normal file
110
tests-acpi-bios-table-test-Update-expected-virt-PPTT.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From 6f89f06e686a61acf681038ac06732facc6e7b93 Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Fri, 7 Jan 2022 16:32:32 +0800
|
||||
Subject: [PATCH 20/24] tests/acpi/bios-table-test: Update expected virt/PPTT
|
||||
file
|
||||
|
||||
Run ./tests/data/acpi/rebuild-expected-aml.sh from build directory
|
||||
to update PPTT binary. Also empty bios-tables-test-allowed-diff.h.
|
||||
|
||||
The disassembled differences between actual and expected PPTT:
|
||||
|
||||
/*
|
||||
* Intel ACPI Component Architecture
|
||||
* AML/ASL+ Disassembler version 20200528 (64-bit version)
|
||||
* Copyright (c) 2000 - 2020 Intel Corporation
|
||||
*
|
||||
- * Disassembly of tests/data/acpi/virt/PPTT, Tue Jan 4 12:51:11 2022
|
||||
+ * Disassembly of /tmp/aml-2ZGOF1, Tue Jan 4 12:51:11 2022
|
||||
*
|
||||
* ACPI Data Table [PPTT]
|
||||
*
|
||||
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
|
||||
*/
|
||||
|
||||
[000h 0000 4] Signature : "PPTT" [Processor Properties Topology Table]
|
||||
-[004h 0004 4] Table Length : 0000004C
|
||||
+[004h 0004 4] Table Length : 00000060
|
||||
[008h 0008 1] Revision : 02
|
||||
-[009h 0009 1] Checksum : A8
|
||||
+[009h 0009 1] Checksum : 48
|
||||
[00Ah 0010 6] Oem ID : "BOCHS "
|
||||
[010h 0016 8] Oem Table ID : "BXPC "
|
||||
[018h 0024 4] Oem Revision : 00000001
|
||||
[01Ch 0028 4] Asl Compiler ID : "BXPC"
|
||||
[020h 0032 4] Asl Compiler Revision : 00000001
|
||||
|
||||
[024h 0036 1] Subtable Type : 00 [Processor Hierarchy Node]
|
||||
[025h 0037 1] Length : 14
|
||||
[026h 0038 2] Reserved : 0000
|
||||
[028h 0040 4] Flags (decoded below) : 00000001
|
||||
Physical package : 1
|
||||
ACPI Processor ID valid : 0
|
||||
Processor is a thread : 0
|
||||
Node is a leaf : 0
|
||||
Identical Implementation : 0
|
||||
[02Ch 0044 4] Parent : 00000000
|
||||
[030h 0048 4] ACPI Processor ID : 00000000
|
||||
[034h 0052 4] Private Resource Number : 00000000
|
||||
|
||||
[038h 0056 1] Subtable Type : 00 [Processor Hierarchy Node]
|
||||
[039h 0057 1] Length : 14
|
||||
[03Ah 0058 2] Reserved : 0000
|
||||
-[03Ch 0060 4] Flags (decoded below) : 0000000A
|
||||
+[03Ch 0060 4] Flags (decoded below) : 00000000
|
||||
Physical package : 0
|
||||
- ACPI Processor ID valid : 1
|
||||
+ ACPI Processor ID valid : 0
|
||||
Processor is a thread : 0
|
||||
- Node is a leaf : 1
|
||||
+ Node is a leaf : 0
|
||||
Identical Implementation : 0
|
||||
[040h 0064 4] Parent : 00000024
|
||||
[044h 0068 4] ACPI Processor ID : 00000000
|
||||
[048h 0072 4] Private Resource Number : 00000000
|
||||
|
||||
-Raw Table Data: Length 76 (0x4C)
|
||||
+[04Ch 0076 1] Subtable Type : 00 [Processor Hierarchy Node]
|
||||
+[04Dh 0077 1] Length : 14
|
||||
+[04Eh 0078 2] Reserved : 0000
|
||||
+[050h 0080 4] Flags (decoded below) : 0000000A
|
||||
+ Physical package : 0
|
||||
+ ACPI Processor ID valid : 1
|
||||
+ Processor is a thread : 0
|
||||
+ Node is a leaf : 1
|
||||
+ Identical Implementation : 0
|
||||
+[054h 0084 4] Parent : 00000038
|
||||
+[058h 0088 4] ACPI Processor ID : 00000000
|
||||
+[05Ch 0092 4] Private Resource Number : 00000000
|
||||
+
|
||||
+Raw Table Data: Length 96 (0x60)
|
||||
|
||||
- 0000: 50 50 54 54 4C 00 00 00 02 A8 42 4F 43 48 53 20 // PPTTL.....BOCHS
|
||||
+ 0000: 50 50 54 54 60 00 00 00 02 48 42 4F 43 48 53 20 // PPTT`....HBOCHS
|
||||
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
|
||||
0020: 01 00 00 00 00 14 00 00 01 00 00 00 00 00 00 00 // ................
|
||||
- 0030: 00 00 00 00 00 00 00 00 00 14 00 00 0A 00 00 00 // ................
|
||||
- 0040: 24 00 00 00 00 00 00 00 00 00 00 00 // $...........
|
||||
+ 0030: 00 00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 // ................
|
||||
+ 0040: 24 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 // $...............
|
||||
+ 0050: 0A 00 00 00 38 00 00 00 00 00 00 00 00 00 00 00 // ....8...........
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Ani Sinha <ani@anisinha.ca>
|
||||
Message-id: 20220107083232.16256-7-wangyanan55@huawei.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
tests/data/acpi/virt/PPTT | Bin 76 -> 96 bytes
|
||||
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
|
||||
2 files changed, 1 deletion(-)
|
||||
|
||||
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
index cb143a55a6..dfb8523c8b 100644
|
||||
--- a/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
@@ -1,2 +1 @@
|
||||
/* List of comma-separated changed AML files to ignore */
|
||||
-"tests/data/acpi/virt/PPTT",
|
||||
--
|
||||
2.27.0
|
||||
|
||||
27
tests-acpi-bios-tables-test-Allow-changes-to-virt-PP.patch
Normal file
27
tests-acpi-bios-tables-test-Allow-changes-to-virt-PP.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 225034a72c803b8e3819cec22bc6fb8bfc9e7366 Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Fri, 7 Jan 2022 16:32:30 +0800
|
||||
Subject: [PATCH 18/24] tests/acpi/bios-tables-test: Allow changes to virt/PPTT
|
||||
file
|
||||
|
||||
List test/data/acpi/virt/PPTT as the expected files allowed to
|
||||
be changed in tests/qtest/bios-tables-test-allowed-diff.h
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Acked-by: Ani Sinha <ani@anisinha.ca>
|
||||
Message-id: 20220107083232.16256-5-wangyanan55@huawei.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
tests/qtest/bios-tables-test-allowed-diff.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
index dfb8523c8b..cb143a55a6 100644
|
||||
--- a/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
@@ -1 +1,2 @@
|
||||
/* List of comma-separated changed AML files to ignore */
|
||||
+"tests/data/acpi/virt/PPTT",
|
||||
--
|
||||
2.27.0
|
||||
|
||||
87
tests-unit-test-smp-parse-Add-smp-generic-invalid-ma.patch
Normal file
87
tests-unit-test-smp-parse-Add-smp-generic-invalid-ma.patch
Normal file
@ -0,0 +1,87 @@
|
||||
From 9a98659dcb37c81e69f54d8f6cbe5116ceba5a36 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Mon, 15 Nov 2021 15:44:07 +0100
|
||||
Subject: [PATCH 05/24] tests/unit/test-smp-parse: Add 'smp-generic-invalid'
|
||||
machine type
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Avoid modifying the MachineClass internals by adding the
|
||||
'smp-generic-invalid' machine, which inherits from TYPE_MACHINE.
|
||||
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Message-Id: <20211216132015.815493-5-philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 25 ++++++++++++++++---------
|
||||
1 file changed, 16 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index f66cf7bb59..47e11089e2 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -487,6 +487,17 @@ static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
}
|
||||
|
||||
+static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ MachineClass *mc = MACHINE_CLASS(oc);
|
||||
+
|
||||
+ /* Force invalid min CPUs and max CPUs */
|
||||
+ mc->min_cpus = 2;
|
||||
+ mc->max_cpus = 511;
|
||||
+
|
||||
+ mc->smp_props.dies_supported = false;
|
||||
+}
|
||||
+
|
||||
static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
@@ -530,10 +541,6 @@ static void test_generic_invalid(const void *opaque)
|
||||
SMPTestData *data = &(SMPTestData){};
|
||||
int i;
|
||||
|
||||
- /* Force invalid min CPUs and max CPUs */
|
||||
- mc->min_cpus = 2;
|
||||
- mc->max_cpus = 511;
|
||||
-
|
||||
for (i = 0; i < ARRAY_SIZE(data_generic_invalid); i++) {
|
||||
*data = data_generic_invalid[i];
|
||||
unsupported_params_init(mc, data);
|
||||
@@ -541,10 +548,6 @@ static void test_generic_invalid(const void *opaque)
|
||||
smp_parse_test(ms, data, false);
|
||||
}
|
||||
|
||||
- /* Reset the supported min CPUs and max CPUs */
|
||||
- mc->min_cpus = MIN_CPUS;
|
||||
- mc->max_cpus = MAX_CPUS;
|
||||
-
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
@@ -606,6 +609,10 @@ static const TypeInfo smp_machine_types[] = {
|
||||
.class_init = machine_base_class_init,
|
||||
.class_size = sizeof(MachineClass),
|
||||
.instance_size = sizeof(MachineState),
|
||||
+ }, {
|
||||
+ .name = MACHINE_TYPE_NAME("smp-generic-invalid"),
|
||||
+ .parent = TYPE_MACHINE,
|
||||
+ .class_init = machine_generic_invalid_class_init,
|
||||
}, {
|
||||
.name = MACHINE_TYPE_NAME("smp-with-dies"),
|
||||
.parent = TYPE_MACHINE,
|
||||
@@ -625,7 +632,7 @@ int main(int argc, char *argv[])
|
||||
TYPE_MACHINE,
|
||||
test_generic_valid);
|
||||
g_test_add_data_func("/test-smp-parse/generic/invalid",
|
||||
- TYPE_MACHINE,
|
||||
+ MACHINE_TYPE_NAME("smp-generic-invalid"),
|
||||
test_generic_invalid);
|
||||
g_test_add_data_func("/test-smp-parse/with_dies",
|
||||
MACHINE_TYPE_NAME("smp-with-dies"),
|
||||
--
|
||||
2.27.0
|
||||
|
||||
75
tests-unit-test-smp-parse-Add-smp-generic-valid-mach.patch
Normal file
75
tests-unit-test-smp-parse-Add-smp-generic-valid-mach.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From c33c7dd51eebf5ae7b7ece1e829b0a5ffdcebfe1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Mon, 15 Nov 2021 15:49:59 +0100
|
||||
Subject: [PATCH 06/24] tests/unit/test-smp-parse: Add 'smp-generic-valid'
|
||||
machine type
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Keep the common TYPE_MACHINE class initialization in
|
||||
machine_base_class_init(), make it abstract, and move
|
||||
the non-common code to a new class: "smp-generic-valid".
|
||||
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Message-Id: <20211216132015.815493-6-philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index 47e11089e2..b20bf2c235 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -478,13 +478,19 @@ static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
+ mc->smp_props.prefer_sockets = true;
|
||||
+
|
||||
+ mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
+}
|
||||
+
|
||||
+static void machine_generic_valid_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ MachineClass *mc = MACHINE_CLASS(oc);
|
||||
+
|
||||
mc->min_cpus = MIN_CPUS;
|
||||
mc->max_cpus = MAX_CPUS;
|
||||
|
||||
- mc->smp_props.prefer_sockets = true;
|
||||
mc->smp_props.dies_supported = false;
|
||||
-
|
||||
- mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
}
|
||||
|
||||
static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
|
||||
@@ -606,9 +612,14 @@ static const TypeInfo smp_machine_types[] = {
|
||||
{
|
||||
.name = TYPE_MACHINE,
|
||||
.parent = TYPE_OBJECT,
|
||||
+ .abstract = true,
|
||||
.class_init = machine_base_class_init,
|
||||
.class_size = sizeof(MachineClass),
|
||||
.instance_size = sizeof(MachineState),
|
||||
+ }, {
|
||||
+ .name = MACHINE_TYPE_NAME("smp-generic-valid"),
|
||||
+ .parent = TYPE_MACHINE,
|
||||
+ .class_init = machine_generic_valid_class_init,
|
||||
}, {
|
||||
.name = MACHINE_TYPE_NAME("smp-generic-invalid"),
|
||||
.parent = TYPE_MACHINE,
|
||||
@@ -629,7 +640,7 @@ int main(int argc, char *argv[])
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
g_test_add_data_func("/test-smp-parse/generic/valid",
|
||||
- TYPE_MACHINE,
|
||||
+ MACHINE_TYPE_NAME("smp-generic-valid"),
|
||||
test_generic_valid);
|
||||
g_test_add_data_func("/test-smp-parse/generic/invalid",
|
||||
MACHINE_TYPE_NAME("smp-generic-invalid"),
|
||||
--
|
||||
2.27.0
|
||||
|
||||
85
tests-unit-test-smp-parse-Add-smp-with-dies-machine-.patch
Normal file
85
tests-unit-test-smp-parse-Add-smp-with-dies-machine-.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 4981e75623db6ca681d13719ffcf61b0cfac3edc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Mon, 15 Nov 2021 12:39:12 +0100
|
||||
Subject: [PATCH 04/24] tests/unit/test-smp-parse: Add 'smp-with-dies' machine
|
||||
type
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Avoid modifying the MachineClass internals by adding the
|
||||
'smp-with-dies' machine, which inherits from TYPE_MACHINE.
|
||||
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Tested-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211216132015.815493-4-philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 22 +++++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index 425ed6b6b9..f66cf7bb59 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -487,6 +487,16 @@ static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
}
|
||||
|
||||
+static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ MachineClass *mc = MACHINE_CLASS(oc);
|
||||
+
|
||||
+ mc->min_cpus = MIN_CPUS;
|
||||
+ mc->max_cpus = MAX_CPUS;
|
||||
+
|
||||
+ mc->smp_props.dies_supported = true;
|
||||
+}
|
||||
+
|
||||
static void test_generic_valid(const void *opaque)
|
||||
{
|
||||
const char *machine_type = opaque;
|
||||
@@ -548,9 +558,6 @@ static void test_with_dies(const void *opaque)
|
||||
unsigned int num_dies = 2;
|
||||
int i;
|
||||
|
||||
- /* Force the SMP compat properties */
|
||||
- mc->smp_props.dies_supported = true;
|
||||
-
|
||||
for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
|
||||
*data = data_generic_valid[i];
|
||||
unsupported_params_init(mc, data);
|
||||
@@ -588,9 +595,6 @@ static void test_with_dies(const void *opaque)
|
||||
smp_parse_test(ms, data, false);
|
||||
}
|
||||
|
||||
- /* Restore the SMP compat properties */
|
||||
- mc->smp_props.dies_supported = false;
|
||||
-
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
@@ -602,6 +606,10 @@ static const TypeInfo smp_machine_types[] = {
|
||||
.class_init = machine_base_class_init,
|
||||
.class_size = sizeof(MachineClass),
|
||||
.instance_size = sizeof(MachineState),
|
||||
+ }, {
|
||||
+ .name = MACHINE_TYPE_NAME("smp-with-dies"),
|
||||
+ .parent = TYPE_MACHINE,
|
||||
+ .class_init = machine_with_dies_class_init,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -620,7 +628,7 @@ int main(int argc, char *argv[])
|
||||
TYPE_MACHINE,
|
||||
test_generic_invalid);
|
||||
g_test_add_data_func("/test-smp-parse/with_dies",
|
||||
- TYPE_MACHINE,
|
||||
+ MACHINE_TYPE_NAME("smp-with-dies"),
|
||||
test_with_dies);
|
||||
|
||||
g_test_run();
|
||||
--
|
||||
2.27.0
|
||||
|
||||
254
tests-unit-test-smp-parse-Add-testcases-for-CPU-clus.patch
Normal file
254
tests-unit-test-smp-parse-Add-testcases-for-CPU-clus.patch
Normal file
@ -0,0 +1,254 @@
|
||||
From 5e8a39a560ea58308f66d47639c0d5d2e704997f Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Tue, 28 Dec 2021 17:22:11 +0800
|
||||
Subject: [PATCH 12/24] tests/unit/test-smp-parse: Add testcases for CPU
|
||||
clusters
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add testcases for parsing of the four-level CPU topology hierarchy,
|
||||
ie sockets/clusters/cores/threads, which will be supported on ARM
|
||||
virt machines.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211228092221.21068-5-wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 130 ++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 123 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index b6df8137fc..331719bbc4 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -61,6 +61,20 @@
|
||||
.has_maxcpus = hf, .maxcpus = f, \
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Currently a 4-level topology hierarchy is supported on ARM virt machines
|
||||
+ * -sockets/clusters/cores/threads
|
||||
+ */
|
||||
+#define SMP_CONFIG_WITH_CLUSTERS(ha, a, hb, b, hc, c, hd, d, he, e, hf, f) \
|
||||
+ { \
|
||||
+ .has_cpus = ha, .cpus = a, \
|
||||
+ .has_sockets = hb, .sockets = b, \
|
||||
+ .has_clusters = hc, .clusters = c, \
|
||||
+ .has_cores = hd, .cores = d, \
|
||||
+ .has_threads = he, .threads = e, \
|
||||
+ .has_maxcpus = hf, .maxcpus = f, \
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* @config - the given SMP configuration
|
||||
* @expect_prefer_sockets - the expected parsing result for the
|
||||
@@ -290,6 +304,10 @@ static const struct SMPTestData data_generic_invalid[] = {
|
||||
/* config: -smp 2,dies=2 */
|
||||
.config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0),
|
||||
.expect_error = "dies not supported by this machine's CPU topology",
|
||||
+ }, {
|
||||
+ /* config: -smp 2,clusters=2 */
|
||||
+ .config = SMP_CONFIG_WITH_CLUSTERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0),
|
||||
+ .expect_error = "clusters not supported by this machine's CPU topology",
|
||||
}, {
|
||||
/* config: -smp 8,sockets=2,cores=4,threads=2,maxcpus=8 */
|
||||
.config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8),
|
||||
@@ -337,20 +355,40 @@ static const struct SMPTestData data_with_dies_invalid[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct SMPTestData data_with_clusters_invalid[] = {
|
||||
+ {
|
||||
+ /* config: -smp 16,sockets=2,clusters=2,cores=4,threads=2,maxcpus=16 */
|
||||
+ .config = SMP_CONFIG_WITH_CLUSTERS(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16),
|
||||
+ .expect_error = "Invalid CPU topology: "
|
||||
+ "product of the hierarchy must match maxcpus: "
|
||||
+ "sockets (2) * clusters (2) * cores (4) * threads (2) "
|
||||
+ "!= maxcpus (16)",
|
||||
+ }, {
|
||||
+ /* config: -smp 34,sockets=2,clusters=2,cores=4,threads=2,maxcpus=32 */
|
||||
+ .config = SMP_CONFIG_WITH_CLUSTERS(T, 34, T, 2, T, 2, T, 4, T, 2, T, 32),
|
||||
+ .expect_error = "Invalid CPU topology: "
|
||||
+ "maxcpus must be equal to or greater than smp: "
|
||||
+ "sockets (2) * clusters (2) * cores (4) * threads (2) "
|
||||
+ "== maxcpus (32) < smp_cpus (34)",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static char *smp_config_to_string(const SMPConfiguration *config)
|
||||
{
|
||||
return g_strdup_printf(
|
||||
"(SMPConfiguration) {\n"
|
||||
- " .has_cpus = %5s, cpus = %" PRId64 ",\n"
|
||||
- " .has_sockets = %5s, sockets = %" PRId64 ",\n"
|
||||
- " .has_dies = %5s, dies = %" PRId64 ",\n"
|
||||
- " .has_cores = %5s, cores = %" PRId64 ",\n"
|
||||
- " .has_threads = %5s, threads = %" PRId64 ",\n"
|
||||
- " .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n"
|
||||
+ " .has_cpus = %5s, cpus = %" PRId64 ",\n"
|
||||
+ " .has_sockets = %5s, sockets = %" PRId64 ",\n"
|
||||
+ " .has_dies = %5s, dies = %" PRId64 ",\n"
|
||||
+ " .has_clusters = %5s, clusters = %" PRId64 ",\n"
|
||||
+ " .has_cores = %5s, cores = %" PRId64 ",\n"
|
||||
+ " .has_threads = %5s, threads = %" PRId64 ",\n"
|
||||
+ " .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n"
|
||||
"}",
|
||||
config->has_cpus ? "true" : "false", config->cpus,
|
||||
config->has_sockets ? "true" : "false", config->sockets,
|
||||
config->has_dies ? "true" : "false", config->dies,
|
||||
+ config->has_clusters ? "true" : "false", config->clusters,
|
||||
config->has_cores ? "true" : "false", config->cores,
|
||||
config->has_threads ? "true" : "false", config->threads,
|
||||
config->has_maxcpus ? "true" : "false", config->maxcpus);
|
||||
@@ -363,11 +401,12 @@ static char *cpu_topology_to_string(const CpuTopology *topo)
|
||||
" .cpus = %u,\n"
|
||||
" .sockets = %u,\n"
|
||||
" .dies = %u,\n"
|
||||
+ " .clusters = %u,\n"
|
||||
" .cores = %u,\n"
|
||||
" .threads = %u,\n"
|
||||
" .max_cpus = %u,\n"
|
||||
"}",
|
||||
- topo->cpus, topo->sockets, topo->dies,
|
||||
+ topo->cpus, topo->sockets, topo->dies, topo->clusters,
|
||||
topo->cores, topo->threads, topo->max_cpus);
|
||||
}
|
||||
|
||||
@@ -391,6 +430,7 @@ static void check_parse(MachineState *ms, const SMPConfiguration *config,
|
||||
(ms->smp.cpus == expect_topo->cpus) &&
|
||||
(ms->smp.sockets == expect_topo->sockets) &&
|
||||
(ms->smp.dies == expect_topo->dies) &&
|
||||
+ (ms->smp.clusters == expect_topo->clusters) &&
|
||||
(ms->smp.cores == expect_topo->cores) &&
|
||||
(ms->smp.threads == expect_topo->threads) &&
|
||||
(ms->smp.max_cpus == expect_topo->max_cpus)) {
|
||||
@@ -472,6 +512,11 @@ static void unsupported_params_init(const MachineClass *mc, SMPTestData *data)
|
||||
data->expect_prefer_sockets.dies = 1;
|
||||
data->expect_prefer_cores.dies = 1;
|
||||
}
|
||||
+
|
||||
+ if (!mc->smp_props.clusters_supported) {
|
||||
+ data->expect_prefer_sockets.clusters = 1;
|
||||
+ data->expect_prefer_cores.clusters = 1;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
@@ -491,6 +536,7 @@ static void machine_generic_valid_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = MAX_CPUS;
|
||||
|
||||
mc->smp_props.dies_supported = false;
|
||||
+ mc->smp_props.clusters_supported = false;
|
||||
}
|
||||
|
||||
static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
|
||||
@@ -502,6 +548,7 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = 511;
|
||||
|
||||
mc->smp_props.dies_supported = false;
|
||||
+ mc->smp_props.clusters_supported = false;
|
||||
}
|
||||
|
||||
static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
||||
@@ -512,6 +559,18 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = MAX_CPUS;
|
||||
|
||||
mc->smp_props.dies_supported = true;
|
||||
+ mc->smp_props.clusters_supported = false;
|
||||
+}
|
||||
+
|
||||
+static void machine_with_clusters_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ MachineClass *mc = MACHINE_CLASS(oc);
|
||||
+
|
||||
+ mc->min_cpus = MIN_CPUS;
|
||||
+ mc->max_cpus = MAX_CPUS;
|
||||
+
|
||||
+ mc->smp_props.clusters_supported = true;
|
||||
+ mc->smp_props.dies_supported = false;
|
||||
}
|
||||
|
||||
static void test_generic_valid(const void *opaque)
|
||||
@@ -607,6 +666,56 @@ static void test_with_dies(const void *opaque)
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
+static void test_with_clusters(const void *opaque)
|
||||
+{
|
||||
+ const char *machine_type = opaque;
|
||||
+ Object *obj = object_new(machine_type);
|
||||
+ MachineState *ms = MACHINE(obj);
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
|
||||
+ SMPTestData data = {};
|
||||
+ unsigned int num_clusters = 2;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
|
||||
+ data = data_generic_valid[i];
|
||||
+ unsupported_params_init(mc, &data);
|
||||
+
|
||||
+ /* when clusters parameter is omitted, it will be set as 1 */
|
||||
+ data.expect_prefer_sockets.clusters = 1;
|
||||
+ data.expect_prefer_cores.clusters = 1;
|
||||
+
|
||||
+ smp_parse_test(ms, &data, true);
|
||||
+
|
||||
+ /* when clusters parameter is specified */
|
||||
+ data.config.has_clusters = true;
|
||||
+ data.config.clusters = num_clusters;
|
||||
+ if (data.config.has_cpus) {
|
||||
+ data.config.cpus *= num_clusters;
|
||||
+ }
|
||||
+ if (data.config.has_maxcpus) {
|
||||
+ data.config.maxcpus *= num_clusters;
|
||||
+ }
|
||||
+
|
||||
+ data.expect_prefer_sockets.clusters = num_clusters;
|
||||
+ data.expect_prefer_sockets.cpus *= num_clusters;
|
||||
+ data.expect_prefer_sockets.max_cpus *= num_clusters;
|
||||
+ data.expect_prefer_cores.clusters = num_clusters;
|
||||
+ data.expect_prefer_cores.cpus *= num_clusters;
|
||||
+ data.expect_prefer_cores.max_cpus *= num_clusters;
|
||||
+
|
||||
+ smp_parse_test(ms, &data, true);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(data_with_clusters_invalid); i++) {
|
||||
+ data = data_with_clusters_invalid[i];
|
||||
+ unsupported_params_init(mc, &data);
|
||||
+
|
||||
+ smp_parse_test(ms, &data, false);
|
||||
+ }
|
||||
+
|
||||
+ object_unref(obj);
|
||||
+}
|
||||
+
|
||||
/* Type info of the tested machine */
|
||||
static const TypeInfo smp_machine_types[] = {
|
||||
{
|
||||
@@ -628,6 +737,10 @@ static const TypeInfo smp_machine_types[] = {
|
||||
.name = MACHINE_TYPE_NAME("smp-with-dies"),
|
||||
.parent = TYPE_MACHINE,
|
||||
.class_init = machine_with_dies_class_init,
|
||||
+ }, {
|
||||
+ .name = MACHINE_TYPE_NAME("smp-with-clusters"),
|
||||
+ .parent = TYPE_MACHINE,
|
||||
+ .class_init = machine_with_clusters_class_init,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -648,6 +761,9 @@ int main(int argc, char *argv[])
|
||||
g_test_add_data_func("/test-smp-parse/with_dies",
|
||||
MACHINE_TYPE_NAME("smp-with-dies"),
|
||||
test_with_dies);
|
||||
+ g_test_add_data_func("/test-smp-parse/with_clusters",
|
||||
+ MACHINE_TYPE_NAME("smp-with-clusters"),
|
||||
+ test_with_clusters);
|
||||
|
||||
g_test_run();
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
82
tests-unit-test-smp-parse-Constify-some-pointer-stru.patch
Normal file
82
tests-unit-test-smp-parse-Constify-some-pointer-stru.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From bcf4b802bd8971c0c5a255e606b15900cd47c6b6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Thu, 11 Nov 2021 10:23:06 +0100
|
||||
Subject: [PATCH 08/24] tests/unit/test-smp-parse: Constify some pointer/struct
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Declare structures const when we don't need to modify
|
||||
them at runtime.
|
||||
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Tested-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211216132015.815493-8-philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index 395929b66c..0f98c9509e 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -83,7 +83,7 @@ typedef struct SMPTestData {
|
||||
* then test the automatic calculation algorithm of the missing
|
||||
* values in the parser.
|
||||
*/
|
||||
-static struct SMPTestData data_generic_valid[] = {
|
||||
+static const struct SMPTestData data_generic_valid[] = {
|
||||
{
|
||||
/* config: no configuration provided
|
||||
* expect: cpus=1,sockets=1,cores=1,threads=1,maxcpus=1 */
|
||||
@@ -285,7 +285,7 @@ static struct SMPTestData data_generic_valid[] = {
|
||||
},
|
||||
};
|
||||
|
||||
-static struct SMPTestData data_generic_invalid[] = {
|
||||
+static const struct SMPTestData data_generic_invalid[] = {
|
||||
{
|
||||
/* config: -smp 2,dies=2 */
|
||||
.config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0),
|
||||
@@ -319,7 +319,7 @@ static struct SMPTestData data_generic_invalid[] = {
|
||||
},
|
||||
};
|
||||
|
||||
-static struct SMPTestData data_with_dies_invalid[] = {
|
||||
+static const struct SMPTestData data_with_dies_invalid[] = {
|
||||
{
|
||||
/* config: -smp 16,sockets=2,dies=2,cores=4,threads=2,maxcpus=16 */
|
||||
.config = SMP_CONFIG_WITH_DIES(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16),
|
||||
@@ -356,7 +356,7 @@ static char *smp_config_to_string(SMPConfiguration *config)
|
||||
config->has_maxcpus ? "true" : "false", config->maxcpus);
|
||||
}
|
||||
|
||||
-static char *cpu_topology_to_string(CpuTopology *topo)
|
||||
+static char *cpu_topology_to_string(const CpuTopology *topo)
|
||||
{
|
||||
return g_strdup_printf(
|
||||
"(CpuTopology) {\n"
|
||||
@@ -372,7 +372,7 @@ static char *cpu_topology_to_string(CpuTopology *topo)
|
||||
}
|
||||
|
||||
static void check_parse(MachineState *ms, SMPConfiguration *config,
|
||||
- CpuTopology *expect_topo, const char *expect_err,
|
||||
+ const CpuTopology *expect_topo, const char *expect_err,
|
||||
bool is_valid)
|
||||
{
|
||||
g_autofree char *config_str = smp_config_to_string(config);
|
||||
@@ -466,7 +466,7 @@ static void smp_parse_test(MachineState *ms, SMPTestData *data, bool is_valid)
|
||||
}
|
||||
|
||||
/* The parsed results of the unsupported parameters should be 1 */
|
||||
-static void unsupported_params_init(MachineClass *mc, SMPTestData *data)
|
||||
+static void unsupported_params_init(const MachineClass *mc, SMPTestData *data)
|
||||
{
|
||||
if (!mc->smp_props.dies_supported) {
|
||||
data->expect_prefer_sockets.dies = 1;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
76
tests-unit-test-smp-parse-Keep-default-MIN-MAX-CPUs-.patch
Normal file
76
tests-unit-test-smp-parse-Keep-default-MIN-MAX-CPUs-.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From 214511b1799b94cfd514a222d087bb888ed808ba Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Tue, 28 Dec 2021 17:22:13 +0800
|
||||
Subject: [PATCH 14/24] tests/unit/test-smp-parse: Keep default MIN/MAX CPUs in
|
||||
machine_base_class_init
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Most machine types in test-smp-parse will be OK to have the default
|
||||
MIN/MAX CPUs except "smp-generic-invalid", let's keep the default
|
||||
values in machine_base_class_init which will be inherited. And if
|
||||
we hope a different value for a specific machine, modify it in its
|
||||
own initialization function.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211228092221.21068-7-wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 16 ++--------------
|
||||
1 file changed, 2 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index 72d83d1bbc..fdc39a846c 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -523,15 +523,10 @@ static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
- mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
-}
|
||||
-
|
||||
-static void machine_generic_valid_class_init(ObjectClass *oc, void *data)
|
||||
-{
|
||||
- MachineClass *mc = MACHINE_CLASS(oc);
|
||||
-
|
||||
mc->min_cpus = MIN_CPUS;
|
||||
mc->max_cpus = MAX_CPUS;
|
||||
+
|
||||
+ mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
}
|
||||
|
||||
static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
|
||||
@@ -547,9 +542,6 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
- mc->min_cpus = MIN_CPUS;
|
||||
- mc->max_cpus = MAX_CPUS;
|
||||
-
|
||||
mc->smp_props.dies_supported = true;
|
||||
}
|
||||
|
||||
@@ -557,9 +549,6 @@ static void machine_with_clusters_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
- mc->min_cpus = MIN_CPUS;
|
||||
- mc->max_cpus = MAX_CPUS;
|
||||
-
|
||||
mc->smp_props.clusters_supported = true;
|
||||
}
|
||||
|
||||
@@ -718,7 +707,6 @@ static const TypeInfo smp_machine_types[] = {
|
||||
}, {
|
||||
.name = MACHINE_TYPE_NAME("smp-generic-valid"),
|
||||
.parent = TYPE_MACHINE,
|
||||
- .class_init = machine_generic_valid_class_init,
|
||||
}, {
|
||||
.name = MACHINE_TYPE_NAME("smp-generic-invalid"),
|
||||
.parent = TYPE_MACHINE,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
75
tests-unit-test-smp-parse-No-need-to-explicitly-zero.patch
Normal file
75
tests-unit-test-smp-parse-No-need-to-explicitly-zero.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 77bca7d51e99f8ba4d11635ff9f51615739f4d55 Mon Sep 17 00:00:00 2001
|
||||
From: Yanan Wang <wangyanan55@huawei.com>
|
||||
Date: Tue, 28 Dec 2021 17:22:12 +0800
|
||||
Subject: [PATCH 13/24] tests/unit/test-smp-parse: No need to explicitly zero
|
||||
MachineClass members
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The default value of the MachineClass members is 0, which
|
||||
means we don't have to explicitly zero them. Also the value
|
||||
of "mc->smp_props.prefer_sockets" will be taken care of by
|
||||
smp_parse_test(), we don't necessarily need the statement
|
||||
in machine_base_class_init() either.
|
||||
|
||||
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211228092221.21068-6-wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 10 ----------
|
||||
1 file changed, 10 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index 331719bbc4..72d83d1bbc 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -523,8 +523,6 @@ static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
- mc->smp_props.prefer_sockets = true;
|
||||
-
|
||||
mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
}
|
||||
|
||||
@@ -534,9 +532,6 @@ static void machine_generic_valid_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
mc->min_cpus = MIN_CPUS;
|
||||
mc->max_cpus = MAX_CPUS;
|
||||
-
|
||||
- mc->smp_props.dies_supported = false;
|
||||
- mc->smp_props.clusters_supported = false;
|
||||
}
|
||||
|
||||
static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
|
||||
@@ -546,9 +541,6 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
|
||||
/* Force invalid min CPUs and max CPUs */
|
||||
mc->min_cpus = 2;
|
||||
mc->max_cpus = 511;
|
||||
-
|
||||
- mc->smp_props.dies_supported = false;
|
||||
- mc->smp_props.clusters_supported = false;
|
||||
}
|
||||
|
||||
static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
||||
@@ -559,7 +551,6 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = MAX_CPUS;
|
||||
|
||||
mc->smp_props.dies_supported = true;
|
||||
- mc->smp_props.clusters_supported = false;
|
||||
}
|
||||
|
||||
static void machine_with_clusters_class_init(ObjectClass *oc, void *data)
|
||||
@@ -570,7 +561,6 @@ static void machine_with_clusters_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = MAX_CPUS;
|
||||
|
||||
mc->smp_props.clusters_supported = true;
|
||||
- mc->smp_props.dies_supported = false;
|
||||
}
|
||||
|
||||
static void test_generic_valid(const void *opaque)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
69
tests-unit-test-smp-parse-Pass-machine-type-as-argum.patch
Normal file
69
tests-unit-test-smp-parse-Pass-machine-type-as-argum.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From d8b2aee4fd6ccd8eb621522b647c392c1dd7955c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Mon, 15 Nov 2021 12:32:09 +0100
|
||||
Subject: [PATCH 02/24] tests/unit/test-smp-parse: Pass machine type as
|
||||
argument to tests
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use g_test_add_data_func() instead of g_test_add_func() so we can
|
||||
pass the machine type to the tests (we will soon have different
|
||||
machine types).
|
||||
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211216132015.815493-2-philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index b02450e25a..37c6b4981d 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -487,9 +487,10 @@ static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
}
|
||||
|
||||
-static void test_generic(void)
|
||||
+static void test_generic(const void *opaque)
|
||||
{
|
||||
- Object *obj = object_new(TYPE_MACHINE);
|
||||
+ const char *machine_type = opaque;
|
||||
+ Object *obj = object_new(machine_type);
|
||||
MachineState *ms = MACHINE(obj);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(obj);
|
||||
SMPTestData *data = &(SMPTestData){{ }};
|
||||
@@ -525,9 +526,10 @@ static void test_generic(void)
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
-static void test_with_dies(void)
|
||||
+static void test_with_dies(const void *opaque)
|
||||
{
|
||||
- Object *obj = object_new(TYPE_MACHINE);
|
||||
+ const char *machine_type = opaque;
|
||||
+ Object *obj = object_new(machine_type);
|
||||
MachineState *ms = MACHINE(obj);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(obj);
|
||||
SMPTestData *data = &(SMPTestData){{ }};
|
||||
@@ -599,8 +601,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
- g_test_add_func("/test-smp-parse/generic", test_generic);
|
||||
- g_test_add_func("/test-smp-parse/with_dies", test_with_dies);
|
||||
+ g_test_add_data_func("/test-smp-parse/generic",
|
||||
+ TYPE_MACHINE,
|
||||
+ test_generic);
|
||||
+ g_test_add_data_func("/test-smp-parse/with_dies",
|
||||
+ TYPE_MACHINE,
|
||||
+ test_with_dies);
|
||||
|
||||
g_test_run();
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
143
tests-unit-test-smp-parse-Simplify-pointer-to-compou.patch
Normal file
143
tests-unit-test-smp-parse-Simplify-pointer-to-compou.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From 964965721bbed1941bf77e5a748efc1274b7c289 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Thu, 11 Nov 2021 08:58:40 +0100
|
||||
Subject: [PATCH 07/24] tests/unit/test-smp-parse: Simplify pointer to compound
|
||||
literal use
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We can simply use a local variable (and pass its pointer) instead
|
||||
of a pointer to a compound literal.
|
||||
|
||||
Reviewed-by: Andrew Jones <drjones@redhat.com>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Tested-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211216132015.815493-7-philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 66 ++++++++++++++++++-------------------
|
||||
1 file changed, 33 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index b20bf2c235..395929b66c 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -520,19 +520,19 @@ static void test_generic_valid(const void *opaque)
|
||||
Object *obj = object_new(machine_type);
|
||||
MachineState *ms = MACHINE(obj);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(obj);
|
||||
- SMPTestData *data = &(SMPTestData){{ }};
|
||||
+ SMPTestData data = {};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
|
||||
- *data = data_generic_valid[i];
|
||||
- unsupported_params_init(mc, data);
|
||||
+ data = data_generic_valid[i];
|
||||
+ unsupported_params_init(mc, &data);
|
||||
|
||||
- smp_parse_test(ms, data, true);
|
||||
+ smp_parse_test(ms, &data, true);
|
||||
|
||||
/* Unsupported parameters can be provided with their values as 1 */
|
||||
- data->config.has_dies = true;
|
||||
- data->config.dies = 1;
|
||||
- smp_parse_test(ms, data, true);
|
||||
+ data.config.has_dies = true;
|
||||
+ data.config.dies = 1;
|
||||
+ smp_parse_test(ms, &data, true);
|
||||
}
|
||||
|
||||
object_unref(obj);
|
||||
@@ -544,14 +544,14 @@ static void test_generic_invalid(const void *opaque)
|
||||
Object *obj = object_new(machine_type);
|
||||
MachineState *ms = MACHINE(obj);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(obj);
|
||||
- SMPTestData *data = &(SMPTestData){};
|
||||
+ SMPTestData data = {};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(data_generic_invalid); i++) {
|
||||
- *data = data_generic_invalid[i];
|
||||
- unsupported_params_init(mc, data);
|
||||
+ data = data_generic_invalid[i];
|
||||
+ unsupported_params_init(mc, &data);
|
||||
|
||||
- smp_parse_test(ms, data, false);
|
||||
+ smp_parse_test(ms, &data, false);
|
||||
}
|
||||
|
||||
object_unref(obj);
|
||||
@@ -563,45 +563,45 @@ static void test_with_dies(const void *opaque)
|
||||
Object *obj = object_new(machine_type);
|
||||
MachineState *ms = MACHINE(obj);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(obj);
|
||||
- SMPTestData *data = &(SMPTestData){{ }};
|
||||
+ SMPTestData data = {};
|
||||
unsigned int num_dies = 2;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
|
||||
- *data = data_generic_valid[i];
|
||||
- unsupported_params_init(mc, data);
|
||||
+ data = data_generic_valid[i];
|
||||
+ unsupported_params_init(mc, &data);
|
||||
|
||||
/* when dies parameter is omitted, it will be set as 1 */
|
||||
- data->expect_prefer_sockets.dies = 1;
|
||||
- data->expect_prefer_cores.dies = 1;
|
||||
+ data.expect_prefer_sockets.dies = 1;
|
||||
+ data.expect_prefer_cores.dies = 1;
|
||||
|
||||
- smp_parse_test(ms, data, true);
|
||||
+ smp_parse_test(ms, &data, true);
|
||||
|
||||
/* when dies parameter is specified */
|
||||
- data->config.has_dies = true;
|
||||
- data->config.dies = num_dies;
|
||||
- if (data->config.has_cpus) {
|
||||
- data->config.cpus *= num_dies;
|
||||
+ data.config.has_dies = true;
|
||||
+ data.config.dies = num_dies;
|
||||
+ if (data.config.has_cpus) {
|
||||
+ data.config.cpus *= num_dies;
|
||||
}
|
||||
- if (data->config.has_maxcpus) {
|
||||
- data->config.maxcpus *= num_dies;
|
||||
+ if (data.config.has_maxcpus) {
|
||||
+ data.config.maxcpus *= num_dies;
|
||||
}
|
||||
|
||||
- data->expect_prefer_sockets.dies = num_dies;
|
||||
- data->expect_prefer_sockets.cpus *= num_dies;
|
||||
- data->expect_prefer_sockets.max_cpus *= num_dies;
|
||||
- data->expect_prefer_cores.dies = num_dies;
|
||||
- data->expect_prefer_cores.cpus *= num_dies;
|
||||
- data->expect_prefer_cores.max_cpus *= num_dies;
|
||||
+ data.expect_prefer_sockets.dies = num_dies;
|
||||
+ data.expect_prefer_sockets.cpus *= num_dies;
|
||||
+ data.expect_prefer_sockets.max_cpus *= num_dies;
|
||||
+ data.expect_prefer_cores.dies = num_dies;
|
||||
+ data.expect_prefer_cores.cpus *= num_dies;
|
||||
+ data.expect_prefer_cores.max_cpus *= num_dies;
|
||||
|
||||
- smp_parse_test(ms, data, true);
|
||||
+ smp_parse_test(ms, &data, true);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(data_with_dies_invalid); i++) {
|
||||
- *data = data_with_dies_invalid[i];
|
||||
- unsupported_params_init(mc, data);
|
||||
+ data = data_with_dies_invalid[i];
|
||||
+ unsupported_params_init(mc, &data);
|
||||
|
||||
- smp_parse_test(ms, data, false);
|
||||
+ smp_parse_test(ms, &data, false);
|
||||
}
|
||||
|
||||
object_unref(obj);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
71
tests-unit-test-smp-parse-Split-the-generic-test-in-.patch
Normal file
71
tests-unit-test-smp-parse-Split-the-generic-test-in-.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From fad259cf9996dbc4001cb94ec3c846d649401027 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Mon, 15 Nov 2021 12:35:43 +0100
|
||||
Subject: [PATCH 03/24] tests/unit/test-smp-parse: Split the 'generic' test in
|
||||
valid / invalid
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Split the 'generic' test in two tests: 'valid' and 'invalid'.
|
||||
This will allow us to remove the hack which modifies the
|
||||
MachineClass internal state.
|
||||
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Message-Id: <20211216132015.815493-3-philmd@redhat.com>
|
||||
---
|
||||
tests/unit/test-smp-parse.c | 21 ++++++++++++++++++---
|
||||
1 file changed, 18 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
|
||||
index 37c6b4981d..425ed6b6b9 100644
|
||||
--- a/tests/unit/test-smp-parse.c
|
||||
+++ b/tests/unit/test-smp-parse.c
|
||||
@@ -487,7 +487,7 @@ static void machine_base_class_init(ObjectClass *oc, void *data)
|
||||
mc->name = g_strdup(SMP_MACHINE_NAME);
|
||||
}
|
||||
|
||||
-static void test_generic(const void *opaque)
|
||||
+static void test_generic_valid(const void *opaque)
|
||||
{
|
||||
const char *machine_type = opaque;
|
||||
Object *obj = object_new(machine_type);
|
||||
@@ -508,6 +508,18 @@ static void test_generic(const void *opaque)
|
||||
smp_parse_test(ms, data, true);
|
||||
}
|
||||
|
||||
+ object_unref(obj);
|
||||
+}
|
||||
+
|
||||
+static void test_generic_invalid(const void *opaque)
|
||||
+{
|
||||
+ const char *machine_type = opaque;
|
||||
+ Object *obj = object_new(machine_type);
|
||||
+ MachineState *ms = MACHINE(obj);
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
|
||||
+ SMPTestData *data = &(SMPTestData){};
|
||||
+ int i;
|
||||
+
|
||||
/* Force invalid min CPUs and max CPUs */
|
||||
mc->min_cpus = 2;
|
||||
mc->max_cpus = 511;
|
||||
@@ -601,9 +613,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
- g_test_add_data_func("/test-smp-parse/generic",
|
||||
+ g_test_add_data_func("/test-smp-parse/generic/valid",
|
||||
+ TYPE_MACHINE,
|
||||
+ test_generic_valid);
|
||||
+ g_test_add_data_func("/test-smp-parse/generic/invalid",
|
||||
TYPE_MACHINE,
|
||||
- test_generic);
|
||||
+ test_generic_invalid);
|
||||
g_test_add_data_func("/test-smp-parse/with_dies",
|
||||
TYPE_MACHINE,
|
||||
test_with_dies);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user