Adds optional parameter virtio_scsi_queues to kvm options. Option is ignored if set to "1" and the maximum number of queues is limited to "8". Effectively it adds the attribute num_queues to virtio-scsi-pci controller.
Reviewed-by: Luka Blaskovic <[email protected]> Signed-off-by: Marko Sikiric <[email protected]> --- lib/hypervisor/hv_base.py | 6 +++++- lib/hypervisor/hv_kvm/__init__.py | 23 +++++++++++++++++++---- man/gnt-instance.rst | 7 +++++++ src/Ganeti/Constants.hs | 4 ++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py index 8aaa062..1efd782 100644 --- a/lib/hypervisor/hv_base.py +++ b/lib/hypervisor/hv_base.py @@ -121,7 +121,9 @@ _NET_PORT_CHECK = (lambda x: 0 < x < 65535, "invalid port number", # Check if number of queues is in safe range _VIRTIO_NET_QUEUES_CHECK = (lambda x: 0 < x < 9, "invalid number of queues", None, None) - +# Check in number of queues is in safe range +_VIRTIO_SCSI_QUEUES_CHECK = (lambda x: 0 < x < 9,"invalid number of queues", + None, None) # Check that an integer is non negative _NONNEGATIVE_INT_CHECK = (lambda x: x >= 0, "cannot be negative", None, None) @@ -136,6 +138,8 @@ REQ_NET_PORT_CHECK = (True, ) + _NET_PORT_CHECK OPT_NET_PORT_CHECK = (False, ) + _NET_PORT_CHECK REQ_VIRTIO_NET_QUEUES_CHECK = (True, ) + _VIRTIO_NET_QUEUES_CHECK OPT_VIRTIO_NET_QUEUES_CHECK = (False, ) + _VIRTIO_NET_QUEUES_CHECK +REQ_VIRTIO_SCSI_QUEUES_CHECK = (True, ) + _VIRTIO_SCSI_QUEUES_CHECK +OPT_VIRTIO_SCSI_QUEUES_CHECK = (False, ) + _VIRTIO_SCSI_QUEUES_CHECK REQ_CPU_MASK_CHECK = (True, ) + _CPU_MASK_CHECK OPT_CPU_MASK_CHECK = (False, ) + _CPU_MASK_CHECK REQ_MULTI_CPU_MASK_CHECK = (True, ) + _MULTI_CPU_MASK_CHECK diff --git a/lib/hypervisor/hv_kvm/__init__.py b/lib/hypervisor/hv_kvm/__init__.py index fa7f7b3..796d73e 100644 --- a/lib/hypervisor/hv_kvm/__init__.py +++ b/lib/hypervisor/hv_kvm/__init__.py @@ -478,6 +478,7 @@ class KVMHypervisor(hv_base.BaseHypervisor): hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES), constants.HV_VHOST_NET: hv_base.NO_CHECK, constants.HV_VIRTIO_NET_QUEUES: hv_base.OPT_VIRTIO_NET_QUEUES_CHECK, + constants.HV_VIRTIO_SCSI_QUEUES: hv_base.OPT_VIRTIO_SCSI_QUEUES_CHECK, constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK, constants.HV_KVM_USER_SHUTDOWN: hv_base.NO_CHECK, constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK, @@ -533,6 +534,9 @@ class KVMHypervisor(hv_base.BaseHypervisor): _DEVICE_DRIVER_SUPPORTED = \ staticmethod(lambda drv, devlist: re.compile(r"^name \"%s\"" % drv, re.M).search(devlist)) + _DEVICE_DRIVER_QUEUES = \ + staticmethod(lambda drv, devinfo: + re.compile(r"^%s\.num_queues" % drv, re.M).search(devinfo)) # match -drive.*boot=on|off on different lines, but in between accept only # dashes not preceeded by a new line (which would mean another option # different than -drive is starting) @@ -1205,10 +1209,21 @@ class KVMHypervisor(hv_base.BaseHypervisor): # In case a SCSI disk is given, QEMU adds # a SCSI contorller (LSI Logic / Symbios Logic 53c895a) # automatically. Here, we add it explicitly with the default id. - kvm_cmd.extend([ - "-device", - "%s,id=scsi" % hvp[constants.HV_KVM_SCSI_CONTROLLER_TYPE] - ]) + # Also multiqueue option is added if set and supported. + num_queues = hvp[constants.HV_VIRTIO_SCSI_QUEUES] + scsi_cont = hvp[constants.HV_KVM_SCSI_CONTROLLER_TYPE] + optlist = ("%s,id=scsi" % scsi_cont) + if num_queues > 1: + result = utils.RunCmd([kvm] + ["-device", "%s,?" % scsi_cont]) + if result.failed: + raise errors.HypervisorError("Unable to get KVM device options") + if self._DEVICE_DRIVER_QUEUES(scsi_cont, result.output): + optlist += (",num_queues=%d" % num_queues) + else: + raise errors.HypervisorError(\ + "Device driver does not support multiqueue") + + kvm_cmd.extend(["-device", optlist]) kvm_cmd.extend(["-balloon", "virtio"]) kvm_cmd.extend(["-daemonize"]) diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst index 7794df7..dec0c48 100644 --- a/man/gnt-instance.rst +++ b/man/gnt-instance.rst @@ -343,6 +343,13 @@ scsi\_controller\_type - megasas - virtio-scsi-pci +virtio\_scsi\_queues + Valid for the KVM hypervisor. + + This optional parameter enables each virtual CPU to have a separate + queue and interrupt to use without affecting other vCPUs. It adds + the attribute num\_queues to the SCSI controller if supported. It is + ignored if set to to 1 and the maximum number of queues is limited to ``8``. disk\_type Valid for the Xen HVM and KVM hypervisors. diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs index cb345d8..2cfbbd7 100644 --- a/src/Ganeti/Constants.hs +++ b/src/Ganeti/Constants.hs @@ -1821,6 +1821,8 @@ hvVhostNet = "vhost_net" hvVirtioNetQueues :: String hvVirtioNetQueues = "virtio_net_queues" +hvVirtioScsiQueues :: String +hvVirtioScsiQueues = "virtio_scsi_queues" hvVifScript :: String hvVifScript = "vif_script" @@ -1946,6 +1948,7 @@ hvsParameterTypes = Map.fromList , (hvVga, VTypeString) , (hvVhostNet, VTypeBool) , (hvVirtioNetQueues, VTypeInt) + , (hvVirtioScsiQueues, VTypeInt) , (hvVifScript, VTypeString) , (hvVifType, VTypeString) , (hvViridian, VTypeBool) @@ -4036,6 +4039,7 @@ hvcDefaults = , (hvKvmFlag, PyValueEx "") , (hvVhostNet, PyValueEx False) , (hvVirtioNetQueues, PyValueEx (1 :: Int)) + , (hvVirtioScsiQueues, PyValueEx (1 :: Int)) , (hvKvmUseChroot, PyValueEx False) , (hvKvmUserShutdown, PyValueEx False) , (hvMemPath, PyValueEx "") -- 2.5.0
