diff --git a/nova/tests/unit/virt/libvirt/test_vif.py b/nova/tests/unit/virt/libvirt/test_vif.py index 729b62098f4c..5d211864e646 100644 --- a/nova/tests/unit/virt/libvirt/test_vif.py +++ b/nova/tests/unit/virt/libvirt/test_vif.py @@ -937,6 +937,7 @@ class LibvirtVifTestCase(test.NoDBTestCase): instance.uuid = '46a4308b-e75a-4f90-a34a-650c86ca18b2' instance.project_id = 'b168ea26fa0c49c1a84e1566d9565fa5' instance.display_name = 'instance1' + instance.image_meta = objects.ImageMeta.from_dict({'properties': {}}) with mock.patch.object(utils, 'execute') as execute: d.plug(instance, self.vif_vrouter) execute.assert_has_calls([ @@ -958,6 +959,36 @@ class LibvirtVifTestCase(test.NoDBTestCase): '--tx_vlan_id=-1 ' '--rx_vlan_id=-1', run_as_root=True)]) + @mock.patch('nova.network.linux_net.create_tap_dev') + def test_plug_vrouter_with_details_multiqueue(self, mock_create_tap_dev): + d = vif.LibvirtGenericVIFDriver() + instance = mock.Mock() + instance.name = 'instance-name' + instance.uuid = '46a4308b-e75a-4f90-a34a-650c86ca18b2' + instance.project_id = 'b168ea26fa0c49c1a84e1566d9565fa5' + instance.display_name = 'instance1' + instance.image_meta = objects.ImageMeta.from_dict({ + 'properties': {'hw_vif_multiqueue_enabled': True}}) + instance.flavor.vcpus = 2 + with mock.patch.object(utils, 'execute') as execute: + d.plug(instance, self.vif_vrouter) + mock_create_tap_dev.assert_called_once_with('tap-xxx-yyy-zzz', + multiqueue=True) + execute.assert_called_once_with( + 'vrouter-port-control', + '--oper=add --uuid=vif-xxx-yyy-zzz ' + '--instance_uuid=46a4308b-e75a-4f90-a34a-650c86ca18b2 ' + '--vn_uuid=network-id-xxx-yyy-zzz ' + '--vm_project_uuid=b168ea26fa0c49c1a84e1566d9565fa5 ' + '--ip_address=0.0.0.0 ' + '--ipv6_address=None ' + '--vm_name=instance1 ' + '--mac=ca:fe:de:ad:be:ef ' + '--tap_name=tap-xxx-yyy-zzz ' + '--port_type=NovaVMPort ' + '--tx_vlan_id=-1 ' + '--rx_vlan_id=-1', run_as_root=True) + def test_ivs_ethernet_driver(self): d = vif.LibvirtGenericVIFDriver() self._check_ivs_ethernet_driver(d, diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 059d212a5735..2e9df69de33b 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -144,6 +144,10 @@ class LibvirtGenericVIFDriver(object): designer.set_vif_host_backend_hostdev_pci_config(conf, pci_slot) return conf + def _is_multiqueue_enabled(self, image_meta, flavor): + _, vhost_queues = self._get_virtio_mq_settings(image_meta, flavor) + return vhost_queues > 1 + def _get_virtio_mq_settings(self, image_meta, flavor): """A methods to set the number of virtio queues, if it has been requested in extra specs. @@ -770,7 +774,9 @@ class LibvirtGenericVIFDriver(object): instance.display_name, vif['address'], vif['devname'], ptype, -1, -1)) try: - linux_net.create_tap_dev(dev) + multiqueue = self._is_multiqueue_enabled(instance.image_meta, + instance.flavor) + linux_net.create_tap_dev(dev, multiqueue=multiqueue) utils.execute('vrouter-port-control', cmd_args, run_as_root=True) except processutils.ProcessExecutionError: LOG.exception(_LE("Failed while plugging vif"), instance=instance) diff --git a/releasenotes/notes/vif-vrouter-multiqueue-077785e1a2d242a0.yaml b/releasenotes/notes/vif-vrouter-multiqueue-077785e1a2d242a0.yaml new file mode 100644 index 000000000000..6b33e99f574d --- /dev/null +++ b/releasenotes/notes/vif-vrouter-multiqueue-077785e1a2d242a0.yaml @@ -0,0 +1,7 @@ +--- +features: + - When using libvirt driver, vrouter VIFs (OpenContrail) now supports + multiqueue mode, which allows to scale network performance across number + of vCPUs. To use this feature one needs to create instance with more than + 1 vCPU from an image with ``hw_vif_multiqueue_enabled`` property set to + ``true``.