def apply_requests(self, requests, numa_cells=None): """Apply PCI requests to the PCI stats. This is used in multiple instance creation, when the scheduler has to maintain how the resources are consumed by the instances. If numa_cells is provided then only devices contained in those nodes are considered. """ if not all( [self._apply_request(self.pools, r, numa_cells) for r in requests]): raise exception.PciDeviceRequestFailed(requests=requests)
def apply_requests(self, requests, numa_cells=None, pci_strict=True): """Apply PCI requests to the PCI stats. This is used in multiple instance creation, when the scheduler has to maintain how the resources are consumed by the instances. If numa_cells is provided then only devices contained in those nodes are considered. """ for r in requests: # WRS: PCI request strict match on same NUMA node. if not self._apply_request(self.pools, r, numa_cells): # WRS: PCI request matching any NUMA node. if pci_strict or not self._apply_request(self.pools, r, None): raise exception.PciDeviceRequestFailed(requests=requests)
def apply_requests(self, requests, numa_cells=None): """Apply PCI requests to the PCI stats. This is used in multiple instance creation, when the scheduler has to maintain how the resources are consumed by the instances. If ``numa_cells`` is provided then NUMA locality may be taken into account, depending on the value of ``numa_policy``. :param requests: A list of InstancePCIRequest object describing the types, quantities and required NUMA affinities of devices we want. :type requests: nova.objects.InstancePCIRequests :param numa_cells: A list of InstanceNUMACell objects whose ``id`` corresponds to the ``id`` of host NUMACells, or None. :raises: exception.PciDeviceRequestFailed if this compute node cannot satisfy the given request. """ if not all( self._apply_request(self.pools, r, numa_cells) for r in requests): raise exception.PciDeviceRequestFailed(requests=requests)
def consume_requests(self, pci_requests, numa_cells=None): alloc_devices = [] for request in pci_requests: count = request.count spec = request.spec # For now, keep the same algorithm as during scheduling: # a spec may be able to match multiple pools. pools = self._filter_pools_for_spec(self.pools, spec) if numa_cells: pools = self._filter_pools_for_numa_cells(pools, numa_cells) # Failed to allocate the required number of devices # Return the devices already allocated back to their pools if sum([pool['count'] for pool in pools]) < count: LOG.error( _LE("Failed to allocate PCI devices for instance." " Unassigning devices back to pools." " This should not happen, since the scheduler" " should have accurate information, and allocation" " during claims is controlled via a hold" " on the compute node semaphore")) for d in range(len(alloc_devices)): self.add_device(alloc_devices.pop()) raise exception.PciDeviceRequestFailed(requests=pci_requests) for pool in pools: if pool['count'] >= count: num_alloc = count else: num_alloc = pool['count'] count -= num_alloc pool['count'] -= num_alloc for d in range(num_alloc): pci_dev = pool['devices'].pop() pci_dev.request_id = request.request_id alloc_devices.append(pci_dev) if count == 0: break return alloc_devices
def _claim_instance(self, context, instance, prefix=''): pci_requests = objects.InstancePCIRequests.get_by_instance( context, instance) if not pci_requests.requests: return None instance_numa_topology = hardware.instance_topology_from_instance( instance) instance_cells = None if instance_numa_topology: instance_cells = instance_numa_topology.cells devs = self.stats.consume_requests(pci_requests.requests, instance_cells) if not devs: raise exception.PciDeviceRequestFailed(pci_requests) for dev in devs: device.claim(dev, instance) if instance_numa_topology and any( dev.numa_node is None for dev in devs): LOG.warning(_LW("Assigning a pci device without numa affinity to" "instance %(instance)s which has numa topology"), {'instance': instance['uuid']}) return devs