is 1000 microseconds (1ms). Valid range is 100 to 500000 (500ms).
The ratelimit length must be lower than the timeslice length.
+=item B<-m DELAY>, B<--migration_delay_us=DELAY>
+
+Migration delay specifies for how long a vCPU, after it stopped running should
+be considered "cache-hot". Basically, if less than DELAY us passed since when
+the vCPU was executing on a CPU, it is likely that most of the vCPU's working
+set is still in the CPU's cache, and therefore the vCPU is not migrated.
+
+Default is 0. Maximum is 100 ms. This can be effective at preventing vCPUs
+to bounce among CPUs too quickly, but, at the same time, the scheduler stops
+being fully work-conserving.
+
=back
B<COMBINATION>
*/
#define LIBXL_HAVE_SCHED_CREDIT2_PARAMS 1
+/*
+ * LIBXL_HAVE_SCHED_CREDIT_MIGR_DELAY indicates that there is a field
+ * in libxl_sched_credit_params called vcpu_migr_delay_us which controls
+ * the resistance of the vCPUs of the cpupool to migrations among pCPUs.
+ */
+#define LIBXL_HAVE_SCHED_CREDIT_MIGR_DELAY
+
/*
* LIBXL_HAVE_VIRIDIAN_CRASH_CTL indicates that the 'crash_ctl' value
* is present in the viridian enlightenment enumeration.
scinfo->tslice_ms = sparam.tslice_ms;
scinfo->ratelimit_us = sparam.ratelimit_us;
+ scinfo->vcpu_migr_delay_us = sparam.vcpu_migr_delay_us;
rc = 0;
out:
rc = ERROR_INVAL;
goto out;
}
+ if (scinfo->vcpu_migr_delay_us > XEN_SYSCTL_CSCHED_MGR_DLY_MAX_US) {
+ LOG(ERROR, "vcpu migration delay should be >= 0 and <= %dus",
+ XEN_SYSCTL_CSCHED_MGR_DLY_MAX_US);
+ rc = ERROR_INVAL;
+ goto out;
+ }
sparam.tslice_ms = scinfo->tslice_ms;
sparam.ratelimit_us = scinfo->ratelimit_us;
+ sparam.vcpu_migr_delay_us = scinfo->vcpu_migr_delay_us;
r = xc_sched_credit_params_set(ctx->xch, poolid, &sparam);
if ( r < 0 ) {
scinfo->tslice_ms = sparam.tslice_ms;
scinfo->ratelimit_us = sparam.ratelimit_us;
+ scinfo->vcpu_migr_delay_us = sparam.vcpu_migr_delay_us;
rc = 0;
out:
libxl_sched_credit_params = Struct("sched_credit_params", [
("tslice_ms", integer),
("ratelimit_us", integer),
+ ("vcpu_migr_delay_us", integer),
], dispose_fn=None)
libxl_sched_credit2_params = Struct("sched_credit2_params", [
"-s --schedparam Query / modify scheduler parameters\n"
"-t TSLICE, --tslice_ms=TSLICE Set the timeslice, in milliseconds\n"
"-r RLIMIT, --ratelimit_us=RLIMIT Set the scheduling rate limit, in microseconds\n"
+ "-m DLY, --migration_delay_us=DLY Set the migration delay, in microseconds\n"
"-p CPUPOOL, --cpupool=CPUPOOL Restrict output to CPUPOOL"
},
{ "sched-credit2",
printf("Cpupool %s: [sched params unavailable]\n",
poolname);
} else {
- printf("Cpupool %s: tslice=%dms ratelimit=%dus\n",
+ printf("Cpupool %s: tslice=%dms ratelimit=%dus migration-delay=%dus\n",
poolname,
scparam.tslice_ms,
- scparam.ratelimit_us);
+ scparam.ratelimit_us,
+ scparam.vcpu_migr_delay_us);
}
free(poolname);
return 0;
const char *dom = NULL;
const char *cpupool = NULL;
int weight = 256, cap = 0;
- int tslice = 0, ratelimit = 0;
+ int tslice = 0, ratelimit = 0, migrdelay = 0;
bool opt_w = false, opt_c = false;
bool opt_t = false, opt_r = false;
- bool opt_s = false;
+ bool opt_s = false, opt_m = false;
int opt, rc;
static struct option opts[] = {
{"domain", 1, 0, 'd'},
{"schedparam", 0, 0, 's'},
{"tslice_ms", 1, 0, 't'},
{"ratelimit_us", 1, 0, 'r'},
+ {"migration_delay_us", 1, 0, 'm'},
{"cpupool", 1, 0, 'p'},
COMMON_LONG_OPTS
};
- SWITCH_FOREACH_OPT(opt, "d:w:c:p:t:r:s", opts, "sched-credit", 0) {
+ SWITCH_FOREACH_OPT(opt, "d:w:c:p:t:r:m:s", opts, "sched-credit", 0) {
case 'd':
dom = optarg;
break;
ratelimit = strtol(optarg, NULL, 10);
opt_r = true;
break;
+ case 'm':
+ migrdelay = strtol(optarg, NULL, 10);
+ opt_m = true;
+ break;
case 's':
opt_s = true;
break;
fprintf(stderr, "Must specify a domain.\n");
return EXIT_FAILURE;
}
- if (!opt_s && (opt_t || opt_r)) {
+ if (!opt_s && (opt_t || opt_r || opt_m)) {
fprintf(stderr, "Must specify schedparam to set schedule "
"parameter values.\n");
return EXIT_FAILURE;
}
}
- if (!opt_t && !opt_r) { /* Output scheduling parameters */
+ if (!opt_t && !opt_r && !opt_m) { /* Output scheduling parameters */
if (sched_credit_pool_output(poolid))
return EXIT_FAILURE;
} else { /* Set scheduling parameters*/
if (opt_r)
scparam.ratelimit_us = ratelimit;
+ if (opt_m)
+ scparam.vcpu_migr_delay_us = migrdelay;
+
if (sched_credit_params_set(poolid, &scparam))
return EXIT_FAILURE;
}