Пример #1
0
 def test_spec_list(self):
     self.assertTrue(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1',
                            'capabilities_network': ['cap1', 'cap2',
                                                     'cap3']}]))
     self.assertTrue(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1',
                            'capabilities_network': ['cap3', 'cap1']}]))
Пример #2
0
 def test_spec_list(self):
     self.assertTrue(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1',
                            'capabilities_network': ['cap1', 'cap2',
                                                     'cap3']}]))
     self.assertTrue(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1',
                            'capabilities_network': ['cap3', 'cap1']}]))
Пример #3
0
 def test_single_spec_match(self):
     self.assertTrue(
         utils.pci_device_prop_match(self.fake_pci_1, [{
             'vendor_id': 'v1',
             'device_id': 'd1'
         }]))
     self.assertTrue(
         utils.pci_device_prop_match(self.fake_pci_1, [{
             'vendor_id': 'V1',
             'device_id': 'D1'
         }]))
Пример #4
0
 def test_spec_extra_key(self):
     self.assertFalse(
         utils.pci_device_prop_match(self.fake_pci_1, [{
             'vendor_id': 'v1',
             'device_id': 'd1',
             'wrong_key': 'k1'
         }]))
Пример #5
0
    def _filter_pools_for_socket_affinity(self, pools, numa_cells):
        host_cells = self.numa_topology.cells
        # bail early if we don't have socket information for all host_cells.
        # This could happen if we're running on an weird older system with
        # multiple sockets per NUMA node, which is a configuration that we
        # explicitly chose not to support.
        if any(cell.socket is None for cell in host_cells):
            LOG.debug('No socket information in host NUMA cell(s).')
            return []

        # get a set of host sockets that the guest cells are in. Since guest
        # cell IDs map to host cell IDs, we can just lookup the latter's
        # socket.
        socket_ids = set()
        for guest_cell in numa_cells:
            for host_cell in host_cells:
                if guest_cell.id == host_cell.id:
                    socket_ids.add(host_cell.socket)

        # now get a set of host NUMA nodes that are in the above sockets
        allowed_numa_nodes = set()
        for host_cell in host_cells:
            if host_cell.socket in socket_ids:
                allowed_numa_nodes.add(host_cell.id)

        # filter out pools that are not in one of the correct host NUMA nodes.
        return [
            pool for pool in pools if any(
                utils.pci_device_prop_match(pool, [{
                    'numa_node': numa_node
                }]) for numa_node in allowed_numa_nodes)
        ]
Пример #6
0
 def test_spec_list_no_matching(self):
     self.assertFalse(
         utils.pci_device_prop_match(
             self.fake_pci_1, [{
                 'vendor_id': 'v1',
                 'device_id': 'd1',
                 'capabilities_network': ['cap1', 'cap33']
             }]))
Пример #7
0
 def test_spec_dismatch(self):
     self.assertFalse(
         utils.pci_device_prop_match(self.fake_pci_1, [{
             'vendor_id': 'v4',
             'device_id': 'd4'
         }, {
             'vendor_id': 'v3',
             'device_id': 'd3'
         }]))
Пример #8
0
 def test_multiple_spec_match(self):
     self.assertTrue(
         utils.pci_device_prop_match(self.fake_pci_1, [{
             'vendor_id': 'v1',
             'device_id': 'd1'
         }, {
             'vendor_id': 'v3',
             'device_id': 'd3'
         }]))
Пример #9
0
 def _filter_pools_for_numa_cells(pools, numa_cells):
     # Some systems don't report numa node info for pci devices, in
     # that case None is reported in pci_device.numa_node, by adding None
     # to numa_cells we allow assigning those devices to instances with
     # numa topology
     numa_cells = [None] + [cell.id for cell in numa_cells]
     # filter out pools which numa_node is not included in numa_cells
     return [pool for pool in pools if any(utils.pci_device_prop_match(
                             pool, [{'numa_node': cell}])
                                           for cell in numa_cells)]
Пример #10
0
 def _filter_pools_for_numa_cells(pools, numa_cells):
     # Some systems don't report numa node info for pci devices, in
     # that case None is reported in pci_device.numa_node, by adding None
     # to numa_cells we allow assigning those devices to instances with
     # numa topology
     numa_cells = [None] + [cell.id for cell in numa_cells]
     # filter out pools which numa_node is not included in numa_cells
     return [pool for pool in pools if any(utils.pci_device_prop_match(
                             pool, [{'numa_node': cell}])
                                           for cell in numa_cells)]
Пример #11
0
    def _filter_pools_for_spec(self, pools, request):
        """Filter out pools that don't match the request's device spec.

        Exclude pools that do not match the specified ``vendor_id``,
        ``product_id`` and/or ``device_type`` field, or any of the other
        arbitrary tags such as ``physical_network``, specified in the request.

        :param pools: A list of PCI device pool dicts
        :param request: An InstancePCIRequest object describing the type,
            quantity and required NUMA affinity of device(s) we want.
        :returns: A list of pools that can be used to support the request if
            this is possible.
        """
        request_specs = request.spec
        return [
            pool for pool in pools
            if utils.pci_device_prop_match(pool, request_specs)
        ]
 def _filter_pools_for_spec(pools, request_specs):
     return [
         pool for pool in pools
         if utils.pci_device_prop_match(pool, request_specs)
     ]
    def _filter_pools_for_numa_cells(cls, pools, numa_cells, numa_policy,
                                     requested_count):
        """Filter out pools with the wrong NUMA affinity, if required.

        Exclude pools that do not have *suitable* PCI NUMA affinity.
        ``numa_policy`` determines what *suitable* means, being one of
        PREFERRED (nice-to-have), LEGACY (must-have-if-available) and REQUIRED
        (must-have). We iterate through the various policies in order of
        strictness. This means that even if we only *prefer* PCI-NUMA affinity,
        we will still attempt to provide it if possible.

        :param pools: A list of PCI device pool dicts
        :param numa_cells: A list of InstanceNUMACell objects whose ``id``
            corresponds to the ``id`` of host NUMACells.
        :param numa_policy: The PCI NUMA affinity policy to apply.
        :param requested_count: The number of PCI devices requested.
        :returns: A list of pools that can, together, provide at least
            ``requested_count`` PCI devices with the level of NUMA affinity
            required by ``numa_policy``, else all pools that can satisfy this
            policy even if it's not enough.
        """
        # NOTE(stephenfin): We may wish to change the default policy at a later
        # date
        requested_policy = numa_policy or fields.PCINUMAAffinityPolicy.LEGACY
        numa_cell_ids = [cell.id for cell in numa_cells]

        # filter out pools which numa_node is not included in numa_cell_ids
        filtered_pools = [
            pool for pool in pools if any(
                utils.pci_device_prop_match(pool, [{
                    'numa_node': cell
                }]) for cell in numa_cell_ids)
        ]

        # we can't apply a less strict policy than the one requested, so we
        # need to return if we've demanded a NUMA affinity of REQUIRED.
        # However, NUMA affinity is a good thing. If we can get enough devices
        # with the stricter policy then we will use them.
        if requested_policy == fields.PCINUMAAffinityPolicy.REQUIRED or sum(
                pool['count'] for pool in filtered_pools) >= requested_count:
            return filtered_pools

        # some systems don't report NUMA node info for PCI devices, in which
        # case None is reported in 'pci_device.numa_node'. The LEGACY policy
        # allows us to use these devices so we include None in the list of
        # suitable NUMA cells.
        numa_cell_ids.append(None)

        # filter out pools which numa_node is not included in numa_cell_ids
        filtered_pools = [
            pool for pool in pools if any(
                utils.pci_device_prop_match(pool, [{
                    'numa_node': cell
                }]) for cell in numa_cell_ids)
        ]

        # once again, we can't apply a less strict policy than the one
        # requested, so we need to return if we've demanded a NUMA affinity of
        # LEGACY. Similarly, we will also return if we have enough devices to
        # satisfy this somewhat strict policy.
        if requested_policy == fields.PCINUMAAffinityPolicy.LEGACY or sum(
                pool['count'] for pool in filtered_pools) >= requested_count:
            return filtered_pools

        # if we've got here, we're using the PREFERRED policy and weren't able
        # to provide anything with stricter affinity. Use whatever devices you
        # can, folks.
        return sorted(
            pools, key=lambda pool: pool.get('numa_node') not in numa_cell_ids)
Пример #14
0
 def test_spec_list_wrong_type(self):
     self.assertFalse(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': ['d1']}]))
Пример #15
0
 def _filter_pools_for_spec(pools, request_specs):
     return [pool for pool in pools if utils.pci_device_prop_match(pool, request_specs)]
Пример #16
0
 def test_spec_dismatch(self):
     self.assertFalse(
         utils.pci_device_prop_match(
             self.fake_pci_1, [{"vendor_id": "v4", "device_id": "d4"}, {"vendor_id": "v3", "device_id": "d3"}]
         )
     )
Пример #17
0
 def test_spec_list_no_matching(self):
     self.assertFalse(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1',
                            'capabilities_network': ['cap1', 'cap33']}]))
Пример #18
0
 def test_spec_dismatch(self):
     self.assertFalse(utils.pci_device_prop_match(
         self.fake_pci_1,
         [{'vendor_id': 'v4', 'device_id': 'd4'},
          {'vendor_id': 'v3', 'device_id': 'd3'}]))
Пример #19
0
 def test_spec_extra_key(self):
     self.assertFalse(utils.pci_device_prop_match(
         self.fake_pci_1,
         [{'vendor_id': 'v1', 'device_id': 'd1', 'wrong_key': 'k1'}]))
Пример #20
0
 def test_single_spec_match(self):
     self.assertTrue(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1'}]))
     self.assertTrue(utils.pci_device_prop_match(
         self.fake_pci_1, [{'vendor_id': 'V1', 'device_id': 'D1'}]))
Пример #21
0
 def test_multiple_spec_match(self):
     self.assertTrue(utils.pci_device_prop_match(
         self.fake_pci_1,
         [{'vendor_id': 'v1', 'device_id': 'd1'},
          {'vendor_id': 'v3', 'device_id': 'd3'}]))
Пример #22
0
 def test_spec_extra_key(self):
     self.assertFalse(
         utils.pci_device_prop_match(self.fake_pci_1, [{"vendor_id": "v1", "device_id": "d1", "wrong_key": "k1"}])
     )
Пример #23
0
    def _filter_pools_for_numa_cells(self, pools, request, numa_cells):
        """Filter out pools with the wrong NUMA affinity, if required.

        Exclude pools that do not have *suitable* PCI NUMA affinity.
        ``numa_policy`` determines what *suitable* means, being one of
        PREFERRED (nice-to-have), LEGACY (must-have-if-available) and REQUIRED
        (must-have). We iterate through the various policies in order of
        strictness. This means that even if we only *prefer* PCI-NUMA affinity,
        we will still attempt to provide it if possible.

        :param pools: A list of PCI device pool dicts
        :param request: An InstancePCIRequest object describing the type,
            quantity and required NUMA affinity of device(s) we want.
        :param numa_cells: A list of InstanceNUMACell objects whose ``id``
            corresponds to the ``id`` of host NUMACells.
        :returns: A list of pools that can, together, provide at least
            ``requested_count`` PCI devices with the level of NUMA affinity
            required by ``numa_policy``, else all pools that can satisfy this
            policy even if it's not enough.
        """
        if not numa_cells:
            return pools

        # we default to the 'legacy' policy for...of course...legacy reasons
        requested_policy = fields.PCINUMAAffinityPolicy.LEGACY
        if 'numa_policy' in request:
            requested_policy = request.numa_policy or requested_policy

        requested_count = request.count
        numa_cell_ids = [cell.id for cell in numa_cells]

        # filter out pools which numa_node is not included in numa_cell_ids
        filtered_pools = [
            pool for pool in pools if any(
                utils.pci_device_prop_match(pool, [{
                    'numa_node': cell
                }]) for cell in numa_cell_ids)
        ]

        # we can't apply a less strict policy than the one requested, so we
        # need to return if we've demanded a NUMA affinity of REQUIRED.
        # However, NUMA affinity is a good thing. If we can get enough devices
        # with the stricter policy then we will use them.
        if requested_policy == fields.PCINUMAAffinityPolicy.REQUIRED or sum(
                pool['count'] for pool in filtered_pools) >= requested_count:
            return filtered_pools

        # the SOCKET policy is a bit of a special case. It's less strict than
        # REQUIRED (so REQUIRED will automatically fulfil SOCKET, at least
        # with our assumption of never having multiple sockets per NUMA node),
        # but not always more strict than LEGACY: a PCI device with no NUMA
        # affinity will fulfil LEGACY but not SOCKET. If we have SOCKET,
        # process it here and don't continue.
        if requested_policy == fields.PCINUMAAffinityPolicy.SOCKET:
            return self._filter_pools_for_socket_affinity(pools, numa_cells)

        # some systems don't report NUMA node info for PCI devices, in which
        # case None is reported in 'pci_device.numa_node'. The LEGACY policy
        # allows us to use these devices so we include None in the list of
        # suitable NUMA cells.
        numa_cell_ids.append(None)

        # filter out pools which numa_node is not included in numa_cell_ids
        filtered_pools = [
            pool for pool in pools if any(
                utils.pci_device_prop_match(pool, [{
                    'numa_node': cell
                }]) for cell in numa_cell_ids)
        ]

        # once again, we can't apply a less strict policy than the one
        # requested, so we need to return if we've demanded a NUMA affinity of
        # LEGACY. Similarly, we will also return if we have enough devices to
        # satisfy this somewhat strict policy.
        if requested_policy == fields.PCINUMAAffinityPolicy.LEGACY or sum(
                pool['count'] for pool in filtered_pools) >= requested_count:
            return filtered_pools

        # if we've got here, we're using the PREFERRED policy and weren't able
        # to provide anything with stricter affinity. Use whatever devices you
        # can, folks.
        return sorted(
            pools, key=lambda pool: pool.get('numa_node') not in numa_cell_ids)
Пример #24
0
 def test_multiple_spec_match(self):
     self.assertTrue(
         utils.pci_device_prop_match(
             self.fake_pci_1, [{"vendor_id": "v1", "device_id": "d1"}, {"vendor_id": "v3", "device_id": "d3"}]
         )
     )
Пример #25
0
    def _filter_pools_for_numa_cells(cls, pools, numa_cells, numa_policy,
            requested_count):
        """Filter out pools with the wrong NUMA affinity, if required.

        Exclude pools that do not have *suitable* PCI NUMA affinity.
        ``numa_policy`` determines what *suitable* means, being one of
        PREFERRED (nice-to-have), LEGACY (must-have-if-available) and REQUIRED
        (must-have). We iterate through the various policies in order of
        strictness. This means that even if we only *prefer* PCI-NUMA affinity,
        we will still attempt to provide it if possible.

        :param pools: A list of PCI device pool dicts
        :param numa_cells: A list of InstanceNUMACell objects whose ``id``
            corresponds to the ``id`` of host NUMACells.
        :param numa_policy: The PCI NUMA affinity policy to apply.
        :param requested_count: The number of PCI devices requested.
        :returns: A list of pools that can, together, provide at least
            ``requested_count`` PCI devices with the level of NUMA affinity
            required by ``numa_policy``, else all pools that can satisfy this
            policy even if it's not enough.
        """
        # NOTE(stephenfin): We may wish to change the default policy at a later
        # date
        requested_policy = numa_policy or fields.PCINUMAAffinityPolicy.LEGACY
        numa_cell_ids = [cell.id for cell in numa_cells]

        # filter out pools which numa_node is not included in numa_cell_ids
        filtered_pools = [
            pool for pool in pools if any(utils.pci_device_prop_match(
                pool, [{'numa_node': cell}]) for cell in numa_cell_ids)]

        # we can't apply a less strict policy than the one requested, so we
        # need to return if we've demanded a NUMA affinity of REQUIRED.
        # However, NUMA affinity is a good thing. If we can get enough devices
        # with the stricter policy then we will use them.
        if requested_policy == fields.PCINUMAAffinityPolicy.REQUIRED or sum(
                pool['count'] for pool in filtered_pools) >= requested_count:
            return filtered_pools

        # some systems don't report NUMA node info for PCI devices, in which
        # case None is reported in 'pci_device.numa_node'. The LEGACY policy
        # allows us to use these devices so we include None in the list of
        # suitable NUMA cells.
        numa_cell_ids.append(None)

        # filter out pools which numa_node is not included in numa_cell_ids
        filtered_pools = [
            pool for pool in pools if any(utils.pci_device_prop_match(
                pool, [{'numa_node': cell}]) for cell in numa_cell_ids)]

        # once again, we can't apply a less strict policy than the one
        # requested, so we need to return if we've demanded a NUMA affinity of
        # LEGACY. Similarly, we will also return if we have enough devices to
        # satisfy this somewhat strict policy.
        if requested_policy == fields.PCINUMAAffinityPolicy.LEGACY or sum(
                pool['count'] for pool in filtered_pools) >= requested_count:
            return filtered_pools

        # if we've got here, we're using the PREFERRED policy and weren't able
        # to provide anything with stricter affinity. Use whatever devices you
        # can, folks.
        return sorted(
            pools, key=lambda pool: pool.get('numa_node') not in numa_cell_ids)
Пример #26
0
 def test_spec_list_wrong_type(self):
     self.assertFalse(
         utils.pci_device_prop_match(self.fake_pci_1, [{
             'vendor_id': 'v1',
             'device_id': ['d1']
         }]))