Check if flavor.vcpus is more than MAX_TAP_QUEUES
When attempting to instantiate an instance based on an image with the metadata hw:vif_multiqueue_enabled=true, the code uses flavor.vcpus as the number of queues on a tap interface. In kernels prior to 3.0, multiple queues on a tap interface is not supported[1]. In kernels 3.x, the number of queues on a tap interface is limited to 8 as MAX_TAP_QUEUES in tun driver[2]. From 4.0, the number is 256[3]. If flavor.vcpus is more than MAX_TAP_QUEUES, creating the tap interface fails. This commit adds logic to check if flavor.vcpus is more than MAX_TAP_QUEUES and use MAX_TAP_QUEUES as the number of queues if so. [1]https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/net/tun.c?id=refs/tags/v2.6.32.71#n101 [2]https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/net/tun.c?id=refs/tags/v3.18.35#n118 [3]https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/net/tun.c?id=refs/tags/v4.1.26#n128 Change-Id: I2aa24e3cf550ff69909a2b4bc8be90641dbe3d69 Closes-Bug: #1570631
This commit is contained in:
parent
cdfa50599c
commit
b9303e6764
@ -487,14 +487,14 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
conf.add_device(nic)
|
||||
return conf.to_xml()
|
||||
|
||||
def test_virtio_multiqueue(self):
|
||||
def _test_virtio_multiqueue(self, vcpus, want_queues):
|
||||
self.flags(use_virtio_for_bridges=True,
|
||||
virt_type='kvm',
|
||||
group='libvirt')
|
||||
|
||||
flavor = objects.Flavor(name='m1.small',
|
||||
memory_mb=128,
|
||||
vcpus=4,
|
||||
vcpus=vcpus,
|
||||
root_gb=0,
|
||||
ephemeral_gb=0,
|
||||
swap=0,
|
||||
@ -515,7 +515,22 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
driver = node.find("driver").get("name")
|
||||
self.assertEqual(driver, 'vhost')
|
||||
queues = node.find("driver").get("queues")
|
||||
self.assertEqual(queues, '4')
|
||||
self.assertEqual(queues, want_queues)
|
||||
|
||||
def test_virtio_multiqueue(self):
|
||||
self._test_virtio_multiqueue(4, '4')
|
||||
|
||||
@mock.patch('os.uname', return_value=('Linux', '', '2.6.32-21-generic'))
|
||||
def test_virtio_multiqueue_in_kernel_2(self, mock_uname):
|
||||
self._test_virtio_multiqueue(10, '1')
|
||||
|
||||
@mock.patch('os.uname', return_value=('Linux', '', '3.19.0-47-generic'))
|
||||
def test_virtio_multiqueue_in_kernel_3(self, mock_uname):
|
||||
self._test_virtio_multiqueue(10, '8')
|
||||
|
||||
@mock.patch('os.uname', return_value=('Linux', '', '4.2.0-35-generic'))
|
||||
def test_virtio_multiqueue_in_kernel_4(self, mock_uname):
|
||||
self._test_virtio_multiqueue(10, '10')
|
||||
|
||||
def test_multiple_nics(self):
|
||||
conf = self._get_conf()
|
||||
|
@ -148,10 +148,31 @@ class LibvirtGenericVIFDriver(object):
|
||||
img_props = image_meta.properties
|
||||
if img_props.get('hw_vif_multiqueue_enabled'):
|
||||
driver = 'vhost'
|
||||
vhost_queues = flavor.vcpus
|
||||
max_tap_queues = self._get_max_tap_queues()
|
||||
if max_tap_queues:
|
||||
vhost_queues = (max_tap_queues if flavor.vcpus > max_tap_queues
|
||||
else flavor.vcpus)
|
||||
else:
|
||||
vhost_queues = flavor.vcpus
|
||||
|
||||
return (driver, vhost_queues)
|
||||
|
||||
def _get_max_tap_queues(self):
|
||||
# NOTE(kengo.sakai): In kernels prior to 3.0,
|
||||
# multiple queues on a tap interface is not supported.
|
||||
# In kernels 3.x, the number of queues on a tap interface
|
||||
# is limited to 8. From 4.0, the number is 256.
|
||||
# See: https://bugs.launchpad.net/nova/+bug/1570631
|
||||
kernel_version = int(os.uname()[2].split(".")[0])
|
||||
if kernel_version <= 2:
|
||||
return 1
|
||||
elif kernel_version == 3:
|
||||
return 8
|
||||
elif kernel_version == 4:
|
||||
return 256
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_bridge_name(self, vif):
|
||||
return vif['network']['bridge']
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
When instantiating an instance based on an image with the metadata
|
||||
hw_vif_multiqueue_enabled=true, if flavor.vcpus is less than the limit
|
||||
of the number of queues on a tap interface in the kernel, nova uses
|
||||
flavor.vcpus as the number of queues. if not, nova uses the limit.
|
||||
The limits are as follows:
|
||||
|
||||
* kernels prior to 3.0: 1
|
||||
* kernels 3.x: 8
|
||||
* kernels 4.x: 256
|
Loading…
Reference in New Issue
Block a user