static int sched_credit_domain_set(libxl__gc *gc, uint32_t domid, const libxl_domain_sched_params *scinfo) { struct xen_domctl_sched_credit sdom; xc_domaininfo_t domaininfo; int rc; rc = xc_domain_getinfolist(CTX->xch, domid, 1, &domaininfo); if (rc < 0) { LOGED(ERROR, domid, "Getting domain info list"); return ERROR_FAIL; } if (rc != 1 || domaininfo.domain != domid) return ERROR_INVAL; rc = xc_sched_credit_domain_get(CTX->xch, domid, &sdom); if (rc != 0) { LOGED(ERROR, domid, "Getting domain sched credit"); return ERROR_FAIL; } if (scinfo->weight != LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT) { if (scinfo->weight < 1 || scinfo->weight > 65535) { LOGD(ERROR, domid, "Cpu weight out of range, " "valid values are within range from 1 to 65535"); return ERROR_INVAL; } sdom.weight = scinfo->weight; } if (scinfo->cap != LIBXL_DOMAIN_SCHED_PARAM_CAP_DEFAULT) { if (scinfo->cap < 0 || scinfo->cap > (domaininfo.max_vcpu_id + 1) * 100) { LOGD(ERROR, domid, "Cpu cap out of range, " "valid range is from 0 to %d for specified number of vcpus", ((domaininfo.max_vcpu_id + 1) * 100)); return ERROR_INVAL; } sdom.cap = scinfo->cap; } rc = xc_sched_credit_domain_set(CTX->xch, domid, &sdom); if ( rc < 0 ) { LOGED(ERROR, domid, "Setting domain sched credit"); return ERROR_FAIL; } return 0; }
static int sched_credit_domain_get(libxl__gc *gc, uint32_t domid, libxl_domain_sched_params *scinfo) { struct xen_domctl_sched_credit sdom; int rc; rc = xc_sched_credit_domain_get(CTX->xch, domid, &sdom); if (rc != 0) { LOGED(ERROR, domid, "Getting domain sched credit"); return ERROR_FAIL; } libxl_domain_sched_params_init(scinfo); scinfo->sched = LIBXL_SCHEDULER_CREDIT; scinfo->weight = sdom.weight; scinfo->cap = sdom.cap; return 0; }
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"); }