static void
virCapabilitiesFreeHostNUMACell(virCapsHostNUMACellPtr cell)
{
    if (cell == NULL)
        return;

    virCapabilitiesClearHostNUMACellCPUTopology(cell->cpus, cell->ncpus);

    VIR_FREE(cell->cpus);
    VIR_FREE(cell);
}
Beispiel #2
0
/*
 * Build  NUMA Toplogy with cell id starting from (0 + seq)
 * for testing
 */
static virCapsPtr
buildNUMATopology(int seq)
{
    virCapsPtr caps;
    virCapsHostNUMACellCPUPtr cell_cpus = NULL;
    int core_id, cell_id;
    int id;

    if ((caps = virCapabilitiesNew(VIR_ARCH_X86_64, false, false)) == NULL)
        goto error;

    id = 0;
    for (cell_id = 0; cell_id < MAX_CELLS; cell_id++) {
        if (VIR_ALLOC_N(cell_cpus, MAX_CPUS_IN_CELL) < 0)
            goto error;

        for (core_id = 0; core_id < MAX_CPUS_IN_CELL; core_id++) {
            cell_cpus[core_id].id = id + core_id;
            cell_cpus[core_id].socket_id = cell_id + seq;
            cell_cpus[core_id].core_id = id + core_id;
            if (!(cell_cpus[core_id].siblings =
                  virBitmapNew(MAX_CPUS_IN_CELL)))
                goto error;
            ignore_value(virBitmapSetBit(cell_cpus[core_id].siblings, id));
        }
        id++;

        if (virCapabilitiesAddHostNUMACell(caps, cell_id + seq,
                                           MAX_MEM_IN_CELL,
                                           MAX_CPUS_IN_CELL, cell_cpus,
                                           VIR_ARCH_NONE, NULL,
                                           VIR_ARCH_NONE, NULL) < 0)
           goto error;

        cell_cpus = NULL;
    }

    return caps;

 error:
    virCapabilitiesClearHostNUMACellCPUTopology(cell_cpus, MAX_CPUS_IN_CELL);
    VIR_FREE(cell_cpus);
    virObjectUnref(caps);
    return NULL;

}
Beispiel #3
0
static int
libxlCapsInitNuma(libxl_ctx *ctx, virCapsPtr caps)
{
    libxl_numainfo *numa_info = NULL;
    libxl_cputopology *cpu_topo = NULL;
    int nr_nodes = 0, nr_cpus = 0;
    virCapsHostNUMACellCPUPtr *cpus = NULL;
    int *nr_cpus_node = NULL;
    size_t i;
    int ret = -1;

    /* Let's try to fetch all the topology information */
    numa_info = libxl_get_numainfo(ctx, &nr_nodes);
    if (numa_info == NULL || nr_nodes == 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("libxl_get_numainfo failed"));
        goto cleanup;
    } else {
        cpu_topo = libxl_get_cpu_topology(ctx, &nr_cpus);
        if (cpu_topo == NULL || nr_cpus == 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("libxl_get_cpu_topology failed"));
            goto cleanup;
        }
    }

    if (VIR_ALLOC_N(cpus, nr_nodes) < 0)
        goto cleanup;

    if (VIR_ALLOC_N(nr_cpus_node, nr_nodes) < 0)
        goto cleanup;

    /* For each node, prepare a list of CPUs belonging to that node */
    for (i = 0; i < nr_cpus; i++) {
        int node = cpu_topo[i].node;

        if (cpu_topo[i].core == LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
            continue;

        nr_cpus_node[node]++;

        if (nr_cpus_node[node] == 1) {
            if (VIR_ALLOC(cpus[node]) < 0)
                goto cleanup;
        } else {
            if (VIR_REALLOC_N(cpus[node], nr_cpus_node[node]) < 0)
                goto cleanup;
        }

        /* Mapping between what libxl tells and what libvirt wants */
        cpus[node][nr_cpus_node[node]-1].id = i;
        cpus[node][nr_cpus_node[node]-1].socket_id = cpu_topo[i].socket;
        cpus[node][nr_cpus_node[node]-1].core_id = cpu_topo[i].core;
        /* Allocate the siblings maps. We will be filling them later */
        cpus[node][nr_cpus_node[node]-1].siblings = virBitmapNew(nr_cpus);
        if (!cpus[node][nr_cpus_node[node]-1].siblings) {
            virReportOOMError();
            goto cleanup;
        }
    }

    /* Let's now populate the siblings bitmaps */
    for (i = 0; i < nr_cpus; i++) {
        int node = cpu_topo[i].node;
        size_t j;

        if (cpu_topo[i].core == LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
            continue;

        for (j = 0; j < nr_cpus_node[node]; j++) {
            if (cpus[node][j].socket_id == cpu_topo[i].socket &&
                cpus[node][j].core_id == cpu_topo[i].core)
                ignore_value(virBitmapSetBit(cpus[node][j].siblings, i));
        }
    }

    for (i = 0; i < nr_nodes; i++) {
        if (numa_info[i].size == LIBXL_NUMAINFO_INVALID_ENTRY)
            continue;

        if (virCapabilitiesAddHostNUMACell(caps, i, nr_cpus_node[i],
                                           numa_info[i].size / 1024,
                                           cpus[i]) < 0) {
            virCapabilitiesClearHostNUMACellCPUTopology(cpus[i],
                                                        nr_cpus_node[i]);
            goto cleanup;
        }

        /* This is safe, as the CPU list is now stored in the NUMA cell */
        cpus[i] = NULL;
    }

    ret = 0;

 cleanup:
    if (ret != 0) {
        for (i = 0; cpus && i < nr_nodes; i++)
            VIR_FREE(cpus[i]);
        virCapabilitiesFreeNUMAInfo(caps);
    }

    VIR_FREE(cpus);
    VIR_FREE(nr_cpus_node);
    libxl_cputopology_list_free(cpu_topo, nr_cpus);
    libxl_numainfo_list_free(numa_info, nr_nodes);

    return ret;
}
Beispiel #4
0
static virCapsPtr
buildVirCapabilities(int max_cells,
                     int max_cpus_in_cell,
                     int max_mem_in_cell)
{
    virCapsPtr caps;
    virCapsHostNUMACellCPUPtr cell_cpus = NULL;
    virCapsHostNUMACellSiblingInfoPtr siblings = NULL;
    int core_id, cell_id, nsiblings;
    int id;
    size_t i;

    if ((caps = virCapabilitiesNew(VIR_ARCH_X86_64, 0, 0)) == NULL)
        goto error;

    id = 0;
    for (cell_id = 0; cell_id < max_cells; cell_id++) {
        if (VIR_ALLOC_N(cell_cpus, max_cpus_in_cell) < 0)
            goto error;

        for (core_id = 0; core_id < max_cpus_in_cell; core_id++) {
            cell_cpus[core_id].id = id;
            cell_cpus[core_id].socket_id = cell_id;
            cell_cpus[core_id].core_id = id + core_id;
            if (!(cell_cpus[core_id].siblings =
                  virBitmapNew(max_cpus_in_cell)))
                goto error;
            ignore_value(virBitmapSetBit(cell_cpus[core_id].siblings, id));
        }
        id++;

        if (VIR_ALLOC_N(siblings, max_cells) < 0)
            goto error;
        nsiblings = max_cells;

        for (i = 0; i < nsiblings; i++) {
            siblings[i].node = i;
            /* Some magical constants, see virNumaGetDistances()
             * for their description. */
            siblings[i].distance = cell_id == i ? 10 : 20;
        }

        if (virCapabilitiesAddHostNUMACell(caps, cell_id,
                                           max_mem_in_cell,
                                           max_cpus_in_cell, cell_cpus,
                                           nsiblings, siblings,
                                           0, NULL) < 0)
           goto error;

        cell_cpus = NULL;
        siblings = NULL;
    }

    return caps;

 error:
    virCapabilitiesClearHostNUMACellCPUTopology(cell_cpus, max_cpus_in_cell);
    VIR_FREE(cell_cpus);
    VIR_FREE(siblings);
    virObjectUnref(caps);
    return NULL;
}