1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
Description: Add context switch chance to other thread during get_available_resources
The get_available_resources method checks host's resource usage by
connecting libvirt. The libvirt connection uses libvirt python bindings
and the connection handling is implemented in C lang. So the eventlet
greenthread can't notice the network connection and doesn't trigger
thread context switch while the nova-compute connects to the libvirt.
If one hypervisor has over 50 or more instances and libvirt is slow
any reason, the no context switch situation causes nova-compute's status
down and some other failure since other tasks have no chance to work.
.
This commit adds greenthread.sleep(0) in the middle of for-loop section
which is the long running no-context switch section. This sleep(0) gives
other tasks to work even though the resource check task takes long time.
The force context switch can prevent lack of any heartbeat operation.
Author: Masahito Muroi <masahito.muroi@linecorp.com>
Date: Tue, 24 Dec 2024 16:00:08 +0900
Bug: https://launchpad.net/bugs/2085709
Change-Id: Ieefc50d91672948faa2cb6e9b676f11c6f88988b
Origin: upstream, https://review.opendev.org/c/openstack/nova/+/938215
Last-Update: 2024-12-27
Index: nova/nova/virt/libvirt/driver.py
===================================================================
--- nova.orig/nova/virt/libvirt/driver.py
+++ nova/nova/virt/libvirt/driver.py
@@ -8740,15 +8740,21 @@ class LibvirtDriver(driver.ComputeDriver
except libvirt.libvirtError:
return []
- net_devs = [
- dev for dev in devices.values() if "net" in _safe_list_caps(dev)
- ]
- vdpa_devs = [
- dev for dev in devices.values() if "vdpa" in _safe_list_caps(dev)
- ]
- pci_devs = {
- name: dev for name, dev in devices.items()
- if "pci" in _safe_list_caps(dev)}
+ net_devs = []
+ vdpa_devs = []
+ pci_devs = {}
+ for name, dev in devices.items():
+ device_caps = _safe_list_caps(dev)
+ if "net" in device_caps:
+ net_devs.append(dev)
+ if "vdpa" in device_caps:
+ vdpa_devs.append(dev)
+ if "pci" in device_caps:
+ pci_devs[name] = dev
+
+ # Give other tasks to work during libvirt connection task
+ greenthread.sleep(0)
+
pci_info = [
self._host._get_pcidev_info(
name, dev, net_devs,
|