Exemple #1
0
def _get_possible_cpu_topologies(vcpus, maxtopology, allow_threads,
                                 specified_threads):
    """Get a list of possible topologies for a vCPU count
    :param vcpus: total number of CPUs for guest instance
    :param maxtopology: nova.objects.VirtCPUTopology for upper limits
    :param allow_threads: if the hypervisor supports CPU threads
    :param specified_threads: if there is a specific request for threads we
                              should attempt to honour

    Given a total desired vCPU count and constraints on the
    maximum number of sockets, cores and threads, return a
    list of nova.objects.VirtCPUTopology instances that represent every
    possible topology that satisfies the constraints.

    exception.ImageVCPULimitsRangeImpossible is raised if
    it is impossible to achieve the total vcpu count given
    the maximum limits on sockets, cores & threads.

    :returns: list of nova.objects.VirtCPUTopology instances
    """

    # Clamp limits to number of vcpus to prevent
    # iterating over insanely large list
    maxsockets = min(vcpus, maxtopology.sockets)
    maxcores = min(vcpus, maxtopology.cores)
    maxthreads = min(vcpus, maxtopology.threads)

    if not allow_threads:
        # NOTE (ndipanov): If we don't support threads - it doesn't matter that
        # they are specified by the NUMA logic.
        specified_threads = None
        maxthreads = 1

    LOG.debug(
        "Build topologies for %(vcpus)d vcpu(s) "
        "%(maxsockets)d:%(maxcores)d:%(maxthreads)d", {
            "vcpus": vcpus,
            "maxsockets": maxsockets,
            "maxcores": maxcores,
            "maxthreads": maxthreads
        })

    def _get_topology_for_vcpus(vcpus, sockets, cores, threads):
        if threads * cores * sockets == vcpus:
            return objects.VirtCPUTopology(sockets=sockets,
                                           cores=cores,
                                           threads=threads)

    # Figure out all possible topologies that match
    # the required vcpus count and satisfy the declared
    # limits. If the total vCPU count were very high
    # it might be more efficient to factorize the vcpu
    # count and then only iterate over its factors, but
    # that's overkill right now
    possible = []
    for s in range(1, maxsockets + 1):
        for c in range(1, maxcores + 1):
            if specified_threads:
                o = _get_topology_for_vcpus(vcpus, s, c, specified_threads)
                if o is not None:
                    possible.append(o)
            else:
                for t in range(1, maxthreads + 1):
                    o = _get_topology_for_vcpus(vcpus, s, c, t)
                    if o is not None:
                        possible.append(o)

    # We want to
    #  - Minimize threads (ie larger sockets * cores is best)
    #  - Prefer sockets over cores
    possible = sorted(possible,
                      reverse=True,
                      key=lambda x:
                      (x.sockets * x.cores, x.sockets, x.threads))

    LOG.debug("Got %d possible topologies", len(possible))
    if len(possible) == 0:
        raise exception.ImageVCPULimitsRangeImpossible(vcpus=vcpus,
                                                       sockets=maxsockets,
                                                       cores=maxcores,
                                                       threads=maxthreads)

    return possible
Exemple #2
0
    def get_possible_topologies(vcpus, maxtopology, allow_threads):
        """Get a list of possible topologies for a vCPU count
        :param vcpus: total number of CPUs for guest instance
        :param maxtopology: VirtCPUTopology for upper limits
        :param allow_threads: if the hypervisor supports CPU threads

        Given a total desired vCPU count and constraints on the
        maximum number of sockets, cores and threads, return a
        list of VirtCPUTopology instances that represent every
        possible topology that satisfies the constraints.

        exception.ImageVCPULimitsRangeImpossible is raised if
        it is impossible to achieve the total vcpu count given
        the maximum limits on sockets, cores & threads.

        :returns: list of VirtCPUTopology instances
        """

        # Clamp limits to number of vcpus to prevent
        # iterating over insanely large list
        maxsockets = min(vcpus, maxtopology.sockets)
        maxcores = min(vcpus, maxtopology.cores)
        maxthreads = min(vcpus, maxtopology.threads)

        if not allow_threads:
            maxthreads = 1

        LOG.debug(
            "Build topologies for %(vcpus)d vcpu(s) "
            "%(maxsockets)d:%(maxcores)d:%(maxthreads)d", {
                "vcpus": vcpus,
                "maxsockets": maxsockets,
                "maxcores": maxcores,
                "maxthreads": maxthreads
            })

        # Figure out all possible topologies that match
        # the required vcpus count and satisfy the declared
        # limits. If the total vCPU count were very high
        # it might be more efficient to factorize the vcpu
        # count and then only iterate over its factors, but
        # that's overkill right now
        possible = []
        for s in range(1, maxsockets + 1):
            for c in range(1, maxcores + 1):
                for t in range(1, maxthreads + 1):
                    if t * c * s == vcpus:
                        possible.append(VirtCPUTopology(s, c, t))

        # We want to
        #  - Minimize threads (ie larger sockets * cores is best)
        #  - Prefer sockets over cores
        possible = sorted(possible,
                          reverse=True,
                          key=lambda x:
                          (x.sockets * x.cores, x.sockets, x.threads))

        LOG.debug("Got %d possible topologies", len(possible))
        if len(possible) == 0:
            raise exception.ImageVCPULimitsRangeImpossible(vcpus=vcpus,
                                                           sockets=maxsockets,
                                                           cores=maxcores,
                                                           threads=maxthreads)

        return possible