qdev: add IOThreadVirtQueueMappingList property type
virtio-blk and virtio-scsi devices will need a way to specify the mapping between IOThreads and virtqueues. At the moment all virtqueues are assigned to a single IOThread or the main loop. This single thread can be a CPU bottleneck, so it is necessary to allow finer-grained assignment to spread the load. Introduce DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST() so devices can take a parameter that maps virtqueues to IOThreads. The command-line syntax for this new property is as follows: --device '{"driver":"foo","iothread-vq-mapping":[{"iothread":"iothread0","vqs":[0,1,2]},...]}' IOThreads are specified by name and virtqueues are specified by 0-based index. It will be common to simply assign virtqueues round-robin across a set of IOThreads. A convenient syntax that does not require specifying individual virtqueue indices is available: --device '{"driver":"foo","iothread-vq-mapping":[{"iothread":"iothread0"},{"iothread":"iothread1"},...]}' Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-ID: <20231220134755.814917-4-stefanha@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
350147a871
commit
cf03a152c5
@ -18,6 +18,7 @@
|
|||||||
#include "qapi/qapi-types-block.h"
|
#include "qapi/qapi-types-block.h"
|
||||||
#include "qapi/qapi-types-machine.h"
|
#include "qapi/qapi-types-machine.h"
|
||||||
#include "qapi/qapi-types-migration.h"
|
#include "qapi/qapi-types-migration.h"
|
||||||
|
#include "qapi/qapi-visit-virtio.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qemu/ctype.h"
|
#include "qemu/ctype.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
@ -1160,3 +1161,48 @@ const PropertyInfo qdev_prop_cpus390entitlement = {
|
|||||||
.set = qdev_propinfo_set_enum,
|
.set = qdev_propinfo_set_enum,
|
||||||
.set_default_value = qdev_propinfo_set_default_value_enum,
|
.set_default_value = qdev_propinfo_set_default_value_enum,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* --- IOThreadVirtQueueMappingList --- */
|
||||||
|
|
||||||
|
static void get_iothread_vq_mapping_list(Object *obj, Visitor *v,
|
||||||
|
const char *name, void *opaque, Error **errp)
|
||||||
|
{
|
||||||
|
IOThreadVirtQueueMappingList **prop_ptr =
|
||||||
|
object_field_prop_ptr(obj, opaque);
|
||||||
|
|
||||||
|
visit_type_IOThreadVirtQueueMappingList(v, name, prop_ptr, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_iothread_vq_mapping_list(Object *obj, Visitor *v,
|
||||||
|
const char *name, void *opaque, Error **errp)
|
||||||
|
{
|
||||||
|
IOThreadVirtQueueMappingList **prop_ptr =
|
||||||
|
object_field_prop_ptr(obj, opaque);
|
||||||
|
IOThreadVirtQueueMappingList *list;
|
||||||
|
|
||||||
|
if (!visit_type_IOThreadVirtQueueMappingList(v, name, &list, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qapi_free_IOThreadVirtQueueMappingList(*prop_ptr);
|
||||||
|
*prop_ptr = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void release_iothread_vq_mapping_list(Object *obj,
|
||||||
|
const char *name, void *opaque)
|
||||||
|
{
|
||||||
|
IOThreadVirtQueueMappingList **prop_ptr =
|
||||||
|
object_field_prop_ptr(obj, opaque);
|
||||||
|
|
||||||
|
qapi_free_IOThreadVirtQueueMappingList(*prop_ptr);
|
||||||
|
*prop_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PropertyInfo qdev_prop_iothread_vq_mapping_list = {
|
||||||
|
.name = "IOThreadVirtQueueMappingList",
|
||||||
|
.description = "IOThread virtqueue mapping list [{\"iothread\":\"<id>\", "
|
||||||
|
"\"vqs\":[1,2,3,...]},...]",
|
||||||
|
.get = get_iothread_vq_mapping_list,
|
||||||
|
.set = set_iothread_vq_mapping_list,
|
||||||
|
.release = release_iothread_vq_mapping_list,
|
||||||
|
};
|
||||||
|
@ -24,6 +24,7 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar;
|
|||||||
extern const PropertyInfo qdev_prop_pcie_link_speed;
|
extern const PropertyInfo qdev_prop_pcie_link_speed;
|
||||||
extern const PropertyInfo qdev_prop_pcie_link_width;
|
extern const PropertyInfo qdev_prop_pcie_link_width;
|
||||||
extern const PropertyInfo qdev_prop_cpus390entitlement;
|
extern const PropertyInfo qdev_prop_cpus390entitlement;
|
||||||
|
extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
|
||||||
|
|
||||||
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
|
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
|
||||||
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
|
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
|
||||||
@ -82,4 +83,8 @@ extern const PropertyInfo qdev_prop_cpus390entitlement;
|
|||||||
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_cpus390entitlement, \
|
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_cpus390entitlement, \
|
||||||
CpuS390Entitlement)
|
CpuS390Entitlement)
|
||||||
|
|
||||||
|
#define DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST(_name, _state, _field) \
|
||||||
|
DEFINE_PROP(_name, _state, _field, qdev_prop_iothread_vq_mapping_list, \
|
||||||
|
IOThreadVirtQueueMappingList *)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -928,3 +928,32 @@
|
|||||||
'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
|
'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
|
||||||
'returns': 'VirtioQueueElement',
|
'returns': 'VirtioQueueElement',
|
||||||
'features': [ 'unstable' ] }
|
'features': [ 'unstable' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @IOThreadVirtQueueMapping:
|
||||||
|
#
|
||||||
|
# Describes the subset of virtqueues assigned to an IOThread.
|
||||||
|
#
|
||||||
|
# @iothread: the id of IOThread object
|
||||||
|
#
|
||||||
|
# @vqs: an optional array of virtqueue indices that will be handled by this
|
||||||
|
# IOThread. When absent, virtqueues are assigned round-robin across all
|
||||||
|
# IOThreadVirtQueueMappings provided. Either all IOThreadVirtQueueMappings
|
||||||
|
# must have @vqs or none of them must have it.
|
||||||
|
#
|
||||||
|
# Since: 9.0
|
||||||
|
##
|
||||||
|
|
||||||
|
{ 'struct': 'IOThreadVirtQueueMapping',
|
||||||
|
'data': { 'iothread': 'str', '*vqs': ['uint16'] } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @DummyVirtioForceArrays:
|
||||||
|
#
|
||||||
|
# Not used by QMP; hack to let us use IOThreadVirtQueueMappingList internally
|
||||||
|
#
|
||||||
|
# Since: 9.0
|
||||||
|
##
|
||||||
|
|
||||||
|
{ 'struct': 'DummyVirtioForceArrays',
|
||||||
|
'data': { 'unused-iothread-vq-mapping': ['IOThreadVirtQueueMapping'] } }
|
||||||
|
Loading…
Reference in New Issue
Block a user