virtio,pc,acpi: features, fixes
better number of queues for vhost smbios speed options acpi fixes Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAl9HqC0PHG1zdEByZWRo YXQuY29tAAoJECgfDbjSjVRprQgH/RGhdPuAFbclXkPNjKojv1XJXTSqQbzLgjAt D5R6lVGJlci7vgqJbBiNPFo7tjbXXIG5k1uVHPRluUQGdu0UR807wvPMObShlBQi FIhZnaLww2HRYg4qAb8NHz+2BoVJf2uQ+w4Qe+G4Oo9JIg8kYpyVdMwi1yp0q0Op cXuZ56oWPGBhODB7CUUJ2KI76mInGGkE7Y8FDArBfB7/fZrWnmUW9DDY7xiOGDWk ewvXVZIktYeSRMZKz03boB+0u+uBrkpr6qzmIp/BqjnwYCrwyUsGaFt2vvI1E1dY +NMh5rboZecRqV4z58BUDsHe1aQXZVeV37jyh9kqBRArKHK5XNA= =bE7D -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging virtio,pc,acpi: features, fixes better number of queues for vhost smbios speed options acpi fixes Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Thu 27 Aug 2020 13:33:49 BST # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: tests/bios-tables-test: add smbios cpu speed test hw/smbios: add options for type 4 max-speed and current-speed vhost-user-blk-pci: default num_queues to -smp N virtio-blk-pci: default num_queues to -smp N virtio-scsi-pci: default num_queues to -smp N virtio-scsi: introduce a constant for fixed virtqueues virtio-pci: add virtio_pci_optimal_num_queues() helper Introduce a new flag for i440fx to disable PCI hotplug on the root bus acpi: update expected DSDT files with _UID changes disassemble-aml: -o actually works arm/acpi: fix an out of spec _UID for PCI root i386/acpi: fix inconsistent QEMU/OVMF device paths acpi: allow DSDT changes Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
19591e9e09
@ -104,6 +104,24 @@ static void acpi_set_pci_info(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_pcihp_disable_root_bus(void)
|
||||
{
|
||||
static bool root_hp_disabled;
|
||||
PCIBus *bus;
|
||||
|
||||
if (root_hp_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
bus = find_i440fx();
|
||||
if (bus) {
|
||||
/* setting the hotplug handler to NULL makes the bus non-hotpluggable */
|
||||
qbus_set_hotplug_handler(BUS(bus), NULL);
|
||||
}
|
||||
root_hp_disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
|
||||
{
|
||||
AcpiPciHpFind *find = opaque;
|
||||
@ -209,8 +227,11 @@ static void acpi_pcihp_update(AcpiPciHpState *s)
|
||||
}
|
||||
}
|
||||
|
||||
void acpi_pcihp_reset(AcpiPciHpState *s)
|
||||
void acpi_pcihp_reset(AcpiPciHpState *s, bool acpihp_root_off)
|
||||
{
|
||||
if (acpihp_root_off) {
|
||||
acpi_pcihp_disable_root_bus();
|
||||
}
|
||||
acpi_set_pci_info();
|
||||
acpi_pcihp_update(s);
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ typedef struct PIIX4PMState {
|
||||
|
||||
AcpiPciHpState acpi_pci_hotplug;
|
||||
bool use_acpi_hotplug_bridge;
|
||||
bool use_acpi_root_pci_hotplug;
|
||||
|
||||
uint8_t disable_s3;
|
||||
uint8_t disable_s4;
|
||||
@ -324,7 +325,7 @@ static void piix4_pm_reset(DeviceState *dev)
|
||||
pci_conf[0x5B] = 0x02;
|
||||
}
|
||||
pm_io_space_update(s);
|
||||
acpi_pcihp_reset(&s->acpi_pci_hotplug);
|
||||
acpi_pcihp_reset(&s->acpi_pci_hotplug, !s->use_acpi_root_pci_hotplug);
|
||||
}
|
||||
|
||||
static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
|
||||
@ -635,6 +636,8 @@ static Property piix4_pm_properties[] = {
|
||||
DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
|
||||
DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
|
||||
use_acpi_hotplug_bridge, true),
|
||||
DEFINE_PROP_BOOL("acpi-root-pci-hotplug", PIIX4PMState,
|
||||
use_acpi_root_pci_hotplug, true),
|
||||
DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState,
|
||||
acpi_memory_hotplug.is_enabled, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
|
@ -170,7 +170,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
|
||||
aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03")));
|
||||
aml_append(dev, aml_name_decl("_SEG", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_BBN", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_string("PCI0")));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
|
||||
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
|
||||
|
||||
|
@ -420,6 +420,9 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->num_queues == VHOST_USER_BLK_AUTO_NUM_QUEUES) {
|
||||
s->num_queues = 1;
|
||||
}
|
||||
if (!s->num_queues || s->num_queues > VIRTIO_QUEUE_MAX) {
|
||||
error_setg(errp, "vhost-user-blk: invalid number of IO queues");
|
||||
return;
|
||||
@ -531,7 +534,8 @@ static const VMStateDescription vmstate_vhost_user_blk = {
|
||||
|
||||
static Property vhost_user_blk_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev", VHostUserBlk, chardev),
|
||||
DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues, 1),
|
||||
DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues,
|
||||
VHOST_USER_BLK_AUTO_NUM_QUEUES),
|
||||
DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
|
||||
DEFINE_PROP_BIT("config-wce", VHostUserBlk, config_wce, 0, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
|
@ -1147,6 +1147,9 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
|
||||
error_setg(errp, "Device needs media, but drive is empty");
|
||||
return;
|
||||
}
|
||||
if (conf->num_queues == VIRTIO_BLK_AUTO_NUM_QUEUES) {
|
||||
conf->num_queues = 1;
|
||||
}
|
||||
if (!conf->num_queues) {
|
||||
error_setg(errp, "num-queues property must be larger than 0");
|
||||
return;
|
||||
@ -1281,7 +1284,8 @@ static Property virtio_blk_properties[] = {
|
||||
#endif
|
||||
DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
|
||||
true),
|
||||
DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues, 1),
|
||||
DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues,
|
||||
VIRTIO_BLK_AUTO_NUM_QUEUES),
|
||||
DEFINE_PROP_UINT16("queue-size", VirtIOBlock, conf.queue_size, 256),
|
||||
DEFINE_PROP_BOOL("seg-max-adjust", VirtIOBlock, conf.seg_max_adjust, true),
|
||||
DEFINE_PROP_LINK("iothread", VirtIOBlock, conf.iothread, TYPE_IOTHREAD,
|
||||
|
@ -28,7 +28,13 @@
|
||||
#include "hw/mem/nvdimm.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
||||
GlobalProperty hw_compat_5_1[] = {};
|
||||
GlobalProperty hw_compat_5_1[] = {
|
||||
{ "vhost-scsi", "num_queues", "1"},
|
||||
{ "vhost-user-blk", "num-queues", "1"},
|
||||
{ "vhost-user-scsi", "num_queues", "1"},
|
||||
{ "virtio-blk-device", "num-queues", "1"},
|
||||
{ "virtio-scsi-device", "num_queues", "1"},
|
||||
};
|
||||
const size_t hw_compat_5_1_len = G_N_ELEMENTS(hw_compat_5_1);
|
||||
|
||||
GlobalProperty hw_compat_5_0[] = {
|
||||
|
@ -1497,7 +1497,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
dev = aml_device("PCI0");
|
||||
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
|
||||
aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(1)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(0)));
|
||||
aml_append(sb_scope, dev);
|
||||
aml_append(dsdt, sb_scope);
|
||||
|
||||
@ -1512,7 +1512,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
|
||||
aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
|
||||
aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(1)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(0)));
|
||||
aml_append(dev, build_q35_osc_method());
|
||||
aml_append(sb_scope, dev);
|
||||
aml_append(dsdt, sb_scope);
|
||||
|
@ -270,7 +270,8 @@ static Property vhost_scsi_properties[] = {
|
||||
DEFINE_PROP_STRING("vhostfd", VirtIOSCSICommon, conf.vhostfd),
|
||||
DEFINE_PROP_STRING("wwpn", VirtIOSCSICommon, conf.wwpn),
|
||||
DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
|
||||
DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues, 1),
|
||||
DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues,
|
||||
VIRTIO_SCSI_AUTO_NUM_QUEUES),
|
||||
DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSICommon, conf.virtqueue_size,
|
||||
128),
|
||||
DEFINE_PROP_BOOL("seg_max_adjust", VirtIOSCSICommon, conf.seg_max_adjust,
|
||||
|
@ -114,7 +114,7 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
|
||||
goto free_virtio;
|
||||
}
|
||||
|
||||
vsc->dev.nvqs = 2 + vs->conf.num_queues;
|
||||
vsc->dev.nvqs = VIRTIO_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
|
||||
vsc->dev.vqs = g_new0(struct vhost_virtqueue, vsc->dev.nvqs);
|
||||
vsc->dev.vq_index = 0;
|
||||
vsc->dev.backend_features = 0;
|
||||
@ -162,7 +162,8 @@ static void vhost_user_scsi_unrealize(DeviceState *dev)
|
||||
static Property vhost_user_scsi_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev", VirtIOSCSICommon, conf.chardev),
|
||||
DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
|
||||
DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues, 1),
|
||||
DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues,
|
||||
VIRTIO_SCSI_AUTO_NUM_QUEUES),
|
||||
DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSICommon, conf.virtqueue_size,
|
||||
128),
|
||||
DEFINE_PROP_UINT32("max_sectors", VirtIOSCSICommon, conf.max_sectors,
|
||||
|
@ -191,7 +191,7 @@ static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
|
||||
VirtIOSCSIReq *req = sreq->hba_private;
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev);
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
|
||||
uint32_t n = virtio_get_queue_index(req->vq) - 2;
|
||||
uint32_t n = virtio_get_queue_index(req->vq) - VIRTIO_SCSI_VQ_NUM_FIXED;
|
||||
|
||||
assert(n < vs->conf.num_queues);
|
||||
qemu_put_be32s(f, &n);
|
||||
@ -891,11 +891,15 @@ void virtio_scsi_common_realize(DeviceState *dev,
|
||||
virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI,
|
||||
sizeof(VirtIOSCSIConfig));
|
||||
|
||||
if (s->conf.num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
|
||||
s->conf.num_queues = 1;
|
||||
}
|
||||
if (s->conf.num_queues == 0 ||
|
||||
s->conf.num_queues > VIRTIO_QUEUE_MAX - 2) {
|
||||
s->conf.num_queues > VIRTIO_QUEUE_MAX - VIRTIO_SCSI_VQ_NUM_FIXED) {
|
||||
error_setg(errp, "Invalid number of queues (= %" PRIu32 "), "
|
||||
"must be a positive integer less than %d.",
|
||||
s->conf.num_queues, VIRTIO_QUEUE_MAX - 2);
|
||||
s->conf.num_queues,
|
||||
VIRTIO_QUEUE_MAX - VIRTIO_SCSI_VQ_NUM_FIXED);
|
||||
virtio_cleanup(vdev);
|
||||
return;
|
||||
}
|
||||
@ -963,7 +967,8 @@ static void virtio_scsi_device_unrealize(DeviceState *dev)
|
||||
}
|
||||
|
||||
static Property virtio_scsi_properties[] = {
|
||||
DEFINE_PROP_UINT32("num_queues", VirtIOSCSI, parent_obj.conf.num_queues, 1),
|
||||
DEFINE_PROP_UINT32("num_queues", VirtIOSCSI, parent_obj.conf.num_queues,
|
||||
VIRTIO_SCSI_AUTO_NUM_QUEUES),
|
||||
DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSI,
|
||||
parent_obj.conf.virtqueue_size, 256),
|
||||
DEFINE_PROP_BOOL("seg_max_adjust", VirtIOSCSI,
|
||||
|
@ -92,9 +92,21 @@ static struct {
|
||||
const char *manufacturer, *version, *serial, *asset, *sku;
|
||||
} type3;
|
||||
|
||||
/*
|
||||
* SVVP requires max_speed and current_speed to be set and not being
|
||||
* 0 which counts as unknown (SMBIOS 3.1.0/Table 21). Set the
|
||||
* default value to 2000MHz as we did before.
|
||||
*/
|
||||
#define DEFAULT_CPU_SPEED 2000
|
||||
|
||||
static struct {
|
||||
const char *sock_pfx, *manufacturer, *version, *serial, *asset, *part;
|
||||
} type4;
|
||||
uint64_t max_speed;
|
||||
uint64_t current_speed;
|
||||
} type4 = {
|
||||
.max_speed = DEFAULT_CPU_SPEED,
|
||||
.current_speed = DEFAULT_CPU_SPEED
|
||||
};
|
||||
|
||||
static struct {
|
||||
size_t nvalues;
|
||||
@ -272,6 +284,14 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
|
||||
.name = "version",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "version number",
|
||||
},{
|
||||
.name = "max-speed",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "max speed in MHz",
|
||||
},{
|
||||
.name = "current-speed",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "speed at system boot in MHz",
|
||||
},{
|
||||
.name = "serial",
|
||||
.type = QEMU_OPT_STRING,
|
||||
@ -586,9 +606,8 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance)
|
||||
SMBIOS_TABLE_SET_STR(4, processor_version_str, type4.version);
|
||||
t->voltage = 0;
|
||||
t->external_clock = cpu_to_le16(0); /* Unknown */
|
||||
/* SVVP requires max_speed and current_speed to not be unknown. */
|
||||
t->max_speed = cpu_to_le16(2000); /* 2000 MHz */
|
||||
t->current_speed = cpu_to_le16(2000); /* 2000 MHz */
|
||||
t->max_speed = cpu_to_le16(type4.max_speed);
|
||||
t->current_speed = cpu_to_le16(type4.current_speed);
|
||||
t->status = 0x41; /* Socket populated, CPU enabled */
|
||||
t->processor_upgrade = 0x01; /* Other */
|
||||
t->l1_cache_handle = cpu_to_le16(0xFFFF); /* N/A */
|
||||
@ -1116,6 +1135,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
save_opt(&type4.serial, opts, "serial");
|
||||
save_opt(&type4.asset, opts, "asset");
|
||||
save_opt(&type4.part, opts, "part");
|
||||
type4.max_speed = qemu_opt_get_number(opts, "max-speed",
|
||||
DEFAULT_CPU_SPEED);
|
||||
type4.current_speed = qemu_opt_get_number(opts, "current-speed",
|
||||
DEFAULT_CPU_SPEED);
|
||||
if (type4.max_speed > UINT16_MAX ||
|
||||
type4.current_speed > UINT16_MAX) {
|
||||
error_setg(errp, "SMBIOS CPU speed is too large (> %d)",
|
||||
UINT16_MAX);
|
||||
}
|
||||
return;
|
||||
case 11:
|
||||
if (!qemu_opts_validate(opts, qemu_smbios_type11_opts, errp)) {
|
||||
|
@ -47,10 +47,15 @@ static void vhost_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
{
|
||||
VHostSCSIPCI *dev = VHOST_SCSI_PCI(vpci_dev);
|
||||
DeviceState *vdev = DEVICE(&dev->vdev);
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
||||
VirtIOSCSIConf *conf = &dev->vdev.parent_obj.parent_obj.conf;
|
||||
|
||||
if (conf->num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
|
||||
conf->num_queues =
|
||||
virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
|
||||
}
|
||||
|
||||
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
|
||||
vpci_dev->nvectors = vs->conf.num_queues + 3;
|
||||
vpci_dev->nvectors = conf->num_queues + VIRTIO_SCSI_VQ_NUM_FIXED + 1;
|
||||
}
|
||||
|
||||
qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
|
||||
|
@ -54,6 +54,10 @@ static void vhost_user_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
VHostUserBlkPCI *dev = VHOST_USER_BLK_PCI(vpci_dev);
|
||||
DeviceState *vdev = DEVICE(&dev->vdev);
|
||||
|
||||
if (dev->vdev.num_queues == VHOST_USER_BLK_AUTO_NUM_QUEUES) {
|
||||
dev->vdev.num_queues = virtio_pci_optimal_num_queues(0);
|
||||
}
|
||||
|
||||
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
|
||||
vpci_dev->nvectors = dev->vdev.num_queues + 1;
|
||||
}
|
||||
|
@ -53,10 +53,15 @@ static void vhost_user_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
{
|
||||
VHostUserSCSIPCI *dev = VHOST_USER_SCSI_PCI(vpci_dev);
|
||||
DeviceState *vdev = DEVICE(&dev->vdev);
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
||||
VirtIOSCSIConf *conf = &dev->vdev.parent_obj.parent_obj.conf;
|
||||
|
||||
if (conf->num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
|
||||
conf->num_queues =
|
||||
virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
|
||||
}
|
||||
|
||||
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
|
||||
vpci_dev->nvectors = vs->conf.num_queues + 3;
|
||||
vpci_dev->nvectors = conf->num_queues + VIRTIO_SCSI_VQ_NUM_FIXED + 1;
|
||||
}
|
||||
|
||||
qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
|
||||
|
@ -50,9 +50,14 @@ static void virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
{
|
||||
VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(vpci_dev);
|
||||
DeviceState *vdev = DEVICE(&dev->vdev);
|
||||
VirtIOBlkConf *conf = &dev->vdev.conf;
|
||||
|
||||
if (conf->num_queues == VIRTIO_BLK_AUTO_NUM_QUEUES) {
|
||||
conf->num_queues = virtio_pci_optimal_num_queues(0);
|
||||
}
|
||||
|
||||
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
|
||||
vpci_dev->nvectors = dev->vdev.conf.num_queues + 1;
|
||||
vpci_dev->nvectors = conf->num_queues + 1;
|
||||
}
|
||||
|
||||
qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "exec/memop.h"
|
||||
#include "standard-headers/linux/virtio_pci.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "migration/qemu-file-types.h"
|
||||
#include "hw/pci/pci.h"
|
||||
@ -2058,6 +2059,37 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
|
||||
g_free(base_name);
|
||||
}
|
||||
|
||||
unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues)
|
||||
{
|
||||
/*
|
||||
* 1:1 vq to vCPU mapping is ideal because the same vCPU that submitted
|
||||
* virtqueue buffers can handle their completion. When a different vCPU
|
||||
* handles completion it may need to IPI the vCPU that submitted the
|
||||
* request and this adds overhead.
|
||||
*
|
||||
* Virtqueues consume guest RAM and MSI-X vectors. This is wasteful in
|
||||
* guests with very many vCPUs and a device that is only used by a few
|
||||
* vCPUs. Unfortunately optimizing that case requires manual pinning inside
|
||||
* the guest, so those users might as well manually set the number of
|
||||
* queues. There is no upper limit that can be applied automatically and
|
||||
* doing so arbitrarily would result in a sudden performance drop once the
|
||||
* threshold number of vCPUs is exceeded.
|
||||
*/
|
||||
unsigned num_queues = current_machine->smp.cpus;
|
||||
|
||||
/*
|
||||
* The maximum number of MSI-X vectors is PCI_MSIX_FLAGS_QSIZE + 1, but the
|
||||
* config change interrupt and the fixed virtqueues must be taken into
|
||||
* account too.
|
||||
*/
|
||||
num_queues = MIN(num_queues, PCI_MSIX_FLAGS_QSIZE - fixed_queues);
|
||||
|
||||
/*
|
||||
* There is a limit to how many virtqueues a device can have.
|
||||
*/
|
||||
return MIN(num_queues, VIRTIO_QUEUE_MAX - fixed_queues);
|
||||
}
|
||||
|
||||
/* virtio-pci-bus */
|
||||
|
||||
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
|
||||
|
@ -243,4 +243,13 @@ typedef struct VirtioPCIDeviceTypeInfo {
|
||||
/* Register virtio-pci type(s). @t must be static. */
|
||||
void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t);
|
||||
|
||||
/**
|
||||
* virtio_pci_optimal_num_queues:
|
||||
* @fixed_queues: number of queues that are always present
|
||||
*
|
||||
* Returns: The optimal number of queues for a multi-queue device, excluding
|
||||
* @fixed_queues.
|
||||
*/
|
||||
unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues);
|
||||
|
||||
#endif
|
||||
|
@ -46,12 +46,17 @@ static void virtio_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
{
|
||||
VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(vpci_dev);
|
||||
DeviceState *vdev = DEVICE(&dev->vdev);
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
||||
DeviceState *proxy = DEVICE(vpci_dev);
|
||||
VirtIOSCSIConf *conf = &dev->vdev.parent_obj.conf;
|
||||
char *bus_name;
|
||||
|
||||
if (conf->num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
|
||||
conf->num_queues =
|
||||
virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
|
||||
}
|
||||
|
||||
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
|
||||
vpci_dev->nvectors = vs->conf.num_queues + 3;
|
||||
vpci_dev->nvectors = conf->num_queues + VIRTIO_SCSI_VQ_NUM_FIXED + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -67,7 +67,7 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
Error **errp);
|
||||
|
||||
/* Called on reset */
|
||||
void acpi_pcihp_reset(AcpiPciHpState *s);
|
||||
void acpi_pcihp_reset(AcpiPciHpState *s, bool acpihp_root_off);
|
||||
|
||||
extern const VMStateDescription vmstate_acpi_pcihp_pci_status;
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#define VHOST_USER_BLK(obj) \
|
||||
OBJECT_CHECK(VHostUserBlk, (obj), TYPE_VHOST_USER_BLK)
|
||||
|
||||
#define VHOST_USER_BLK_AUTO_NUM_QUEUES UINT16_MAX
|
||||
|
||||
typedef struct VHostUserBlk {
|
||||
VirtIODevice parent_obj;
|
||||
CharBackend chardev;
|
||||
|
@ -30,6 +30,8 @@ struct virtio_blk_inhdr
|
||||
unsigned char status;
|
||||
};
|
||||
|
||||
#define VIRTIO_BLK_AUTO_NUM_QUEUES UINT16_MAX
|
||||
|
||||
struct VirtIOBlkConf
|
||||
{
|
||||
BlockConf conf;
|
||||
|
@ -36,6 +36,11 @@
|
||||
#define VIRTIO_SCSI_MAX_TARGET 255
|
||||
#define VIRTIO_SCSI_MAX_LUN 16383
|
||||
|
||||
/* Number of virtqueues that are always present */
|
||||
#define VIRTIO_SCSI_VQ_NUM_FIXED 2
|
||||
|
||||
#define VIRTIO_SCSI_AUTO_NUM_QUEUES UINT32_MAX
|
||||
|
||||
typedef struct virtio_scsi_cmd_req VirtIOSCSICmdReq;
|
||||
typedef struct virtio_scsi_cmd_resp VirtIOSCSICmdResp;
|
||||
typedef struct virtio_scsi_ctrl_tmf_req VirtIOSCSICtrlTMFReq;
|
||||
|
@ -2294,7 +2294,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
|
||||
" [,sku=str]\n"
|
||||
" specify SMBIOS type 3 fields\n"
|
||||
"-smbios type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str]\n"
|
||||
" [,asset=str][,part=str]\n"
|
||||
" [,asset=str][,part=str][,max-speed=%d][,current-speed=%d]\n"
|
||||
" specify SMBIOS type 4 fields\n"
|
||||
"-smbios type=17[,loc_pfx=str][,bank=str][,manufacturer=str][,serial=str]\n"
|
||||
" [,asset=str][,part=str][,speed=%d]\n"
|
||||
|
@ -42,11 +42,16 @@ do
|
||||
else
|
||||
extra=""
|
||||
fi
|
||||
asl=${aml}.dsl
|
||||
if [[ "${outdir}" ]];
|
||||
then
|
||||
asl="${outdir}"/${machine}/${asl}
|
||||
# iasl strips an extension from prefix if there.
|
||||
# since we have some files with . in the name, the
|
||||
# last component gets interpreted as an extension:
|
||||
# add another extension to work around that.
|
||||
prefix="-p ${outdir}/${aml}.dsl"
|
||||
else
|
||||
prefix=""
|
||||
fi
|
||||
iasl -d -p ${asl} ${extra} ${aml}
|
||||
iasl ${extra} ${prefix} -d ${aml}
|
||||
done
|
||||
done
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -80,6 +80,8 @@ typedef struct {
|
||||
GArray *tables;
|
||||
uint32_t smbios_ep_addr;
|
||||
struct smbios_21_entry_point smbios_ep_table;
|
||||
uint16_t smbios_cpu_max_speed;
|
||||
uint16_t smbios_cpu_curr_speed;
|
||||
uint8_t *required_struct_types;
|
||||
int required_struct_types_len;
|
||||
QTestState *qts;
|
||||
@ -563,6 +565,31 @@ static inline bool smbios_single_instance(uint8_t type)
|
||||
}
|
||||
}
|
||||
|
||||
static bool smbios_cpu_test(test_data *data, uint32_t addr)
|
||||
{
|
||||
uint16_t expect_speed[2];
|
||||
uint16_t real;
|
||||
int offset[2];
|
||||
int i;
|
||||
|
||||
/* Check CPU speed for backward compatibility */
|
||||
offset[0] = offsetof(struct smbios_type_4, max_speed);
|
||||
offset[1] = offsetof(struct smbios_type_4, current_speed);
|
||||
expect_speed[0] = data->smbios_cpu_max_speed ? : 2000;
|
||||
expect_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
real = qtest_readw(data->qts, addr + offset[i]);
|
||||
if (real != expect_speed[i]) {
|
||||
fprintf(stderr, "Unexpected SMBIOS CPU speed: real %u expect %u\n",
|
||||
real, expect_speed[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void test_smbios_structs(test_data *data)
|
||||
{
|
||||
DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
|
||||
@ -585,6 +612,10 @@ static void test_smbios_structs(test_data *data)
|
||||
}
|
||||
set_bit(type, struct_bitmap);
|
||||
|
||||
if (type == 4) {
|
||||
g_assert(smbios_cpu_test(data, addr));
|
||||
}
|
||||
|
||||
/* seek to end of unformatted string area of this struct ("\0\0") */
|
||||
prv = crt = 1;
|
||||
while (prv || crt) {
|
||||
@ -719,6 +750,11 @@ static void test_acpi_q35_tcg(void)
|
||||
data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
|
||||
test_acpi_one(NULL, &data);
|
||||
free_test_data(&data);
|
||||
|
||||
data.smbios_cpu_max_speed = 3000;
|
||||
data.smbios_cpu_curr_speed = 2600;
|
||||
test_acpi_one("-smbios type=4,max-speed=3000,current-speed=2600", &data);
|
||||
free_test_data(&data);
|
||||
}
|
||||
|
||||
static void test_acpi_q35_tcg_bridge(void)
|
||||
@ -1084,6 +1120,12 @@ static void test_acpi_virt_tcg(void)
|
||||
|
||||
test_acpi_one("-cpu cortex-a57", &data);
|
||||
free_test_data(&data);
|
||||
|
||||
data.smbios_cpu_max_speed = 2900;
|
||||
data.smbios_cpu_curr_speed = 2700;
|
||||
test_acpi_one("-cpu cortex-a57 "
|
||||
"-smbios type=4,max-speed=2900,current-speed=2700", &data);
|
||||
free_test_data(&data);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
Loading…
Reference in New Issue
Block a user