static void configure_vcpus(struct flags f){
    struct xen_domctl_sched_credit sdom;
    int i, j, r, size, pcpus_supplied, min;
    xc_cpumap_t cpumap;

    size = xc_get_cpumap_size(xch) * 8; /* array is of uint8_t */

    for (i=0; i<f.vcpus; i++){
        if (f.vcpu_affinity[i]){ /* NULL means unset */
            pcpus_supplied = strlen(f.vcpu_affinity[i]);
            min = (pcpus_supplied < size)?pcpus_supplied:size;
            cpumap = xc_cpumap_alloc(xch);
            if (cpumap == NULL)
                failwith_oss_xc("xc_cpumap_alloc");

            for (j=0; j<min; j++) {
                if (f.vcpu_affinity[i][j] == '1')
                    cpumap[j/8] |= 1 << (j&7);
            }
            r = xc_vcpu_setaffinity(xch, domid, i, cpumap, NULL,
                                    XEN_VCPUAFFINITY_HARD);
            free(cpumap);
            if (r) {
                failwith_oss_xc("xc_vcpu_setaffinity");
            }
        }
    }

    r = xc_sched_credit_domain_get(xch, domid, &sdom);
    /* This should only happen when a different scheduler is set */
    if (r) {
        xg_info("Failed to get credit scheduler parameters: scheduler not enabled?\n");
        return;
    }
    if (f.vcpu_weight != 0L) sdom.weight = f.vcpu_weight;
    if (f.vcpu_cap != 0L) sdom.cap = f.vcpu_cap;
    /* This shouldn't fail, if "get" above succeeds. This error is fatal
       to highlight the need to investigate further. */
    r = xc_sched_credit_domain_set(xch, domid, &sdom);
    if (r)
        failwith_oss_xc("xc_sched_credit_domain_set");
}
Esempio n. 2
0
static int libxl__set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid,
                                   uint32_t vcpuid,
                                   const libxl_bitmap *cpumap_hard,
                                   const libxl_bitmap *cpumap_soft,
                                   unsigned flags)
{
    GC_INIT(ctx);
    libxl_bitmap hard, soft;
    int rc;

    libxl_bitmap_init(&hard);
    libxl_bitmap_init(&soft);

    if (!cpumap_hard && !cpumap_soft && !flags) {
        rc = ERROR_INVAL;
        goto out;
    }

    /*
     * Xen wants writable hard and/or soft cpumaps, to put back in them
     * the effective hard and/or soft affinity that will be used.
     */
    if (cpumap_hard) {
        rc = libxl_cpu_bitmap_alloc(ctx, &hard, 0);
        if (rc)
            goto out;

        libxl__bitmap_copy_best_effort(gc, &hard, cpumap_hard);
        flags |= XEN_VCPUAFFINITY_HARD;
    }
    if (cpumap_soft) {
        rc = libxl_cpu_bitmap_alloc(ctx, &soft, 0);
        if (rc)
            goto out;

        libxl__bitmap_copy_best_effort(gc, &soft, cpumap_soft);
        flags |= XEN_VCPUAFFINITY_SOFT;
    }

    if (xc_vcpu_setaffinity(ctx->xch, domid, vcpuid,
                            cpumap_hard ? hard.map : NULL,
                            cpumap_soft ? soft.map : NULL,
                            flags)) {
        LOGED(ERROR, domid, "Setting vcpu affinity");
        rc = ERROR_FAIL;
        goto out;
    }

    /*
     * Let's check the results. Hard affinity will never be empty, but it
     * is possible that Xen will use something different from what we asked
     * for various reasons. If that's the case, report it.
     */
    if (cpumap_hard &&
        !libxl_bitmap_equal(cpumap_hard, &hard, 0))
        LOGD(DEBUG, domid, "New hard affinity for vcpu %d has unreachable cpus", vcpuid);
    /*
     * Soft affinity can both be different from what asked and empty. Check
     * for (and report) both.
     */
    if (cpumap_soft) {
        if (!libxl_bitmap_equal(cpumap_soft, &soft, 0))
            LOGD(DEBUG, domid, "New soft affinity for vcpu %d has unreachable cpus",
                 vcpuid);
        if (libxl_bitmap_is_empty(&soft))
            LOGD(WARN, domid, "All cpus in soft affinity of vcpu %d are unreachable."
                 " Only hard affinity will be considered for scheduling",
                 vcpuid);
    }

    rc = 0;
 out:
    libxl_bitmap_dispose(&hard);
    libxl_bitmap_dispose(&soft);
    GC_FREE;
    return rc;
}