From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chong Li Subject: [PATCH v4 for Xen 4.6 3/4] libxl: enable per-VCPU parameter settings for RTDS scheduler Date: Fri, 10 Jul 2015 23:52:35 -0500 Message-ID: <1436590356-3706-4-git-send-email-chong.li@wustl.edu> References: <1436590356-3706-1-git-send-email-chong.li@wustl.edu> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1436590356-3706-1-git-send-email-chong.li@wustl.edu> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: Chong Li , wei.liu2@citrix.com, Sisu Xi , george.dunlap@eu.citrix.com, dario.faggioli@citrix.com, ian.jackson@eu.citrix.com, ian.campbell@eu.citrix.com, Meng Xu , lichong659@gmail.com, dgolomb@seas.upenn.edu List-Id: xen-devel@lists.xenproject.org Add libxl_vcpu_sched_params_get/set and sched_rtds_vcpu_get/set functions to support per-VCPU settings. Signed-off-by: Chong Li Signed-off-by: Meng Xu Signed-off-by: Sisu Xi --- Changes on PATCH v3: 1) Add sanity check on vcpuid 2) Add comments on per-domain and per-vcpu functions for libxl users CC: CC: CC: CC: CC: CC: CC: CC: --- tools/libxl/libxl.c | 265 ++++++++++++++++++++++++++++++++++++++++---- tools/libxl/libxl.h | 17 +++ tools/libxl/libxl_types.idl | 16 +++ 3 files changed, 276 insertions(+), 22 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index e9a2d26..9f7f859 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -5854,6 +5854,156 @@ static int sched_sedf_domain_set(libxl__gc *gc, uint32_t domid, return 0; } +static int sched_rtds_validate_params(libxl__gc *gc, int period, + int budget, uint32_t *sdom_period, + uint32_t *sdom_budget) +{ + if (period != LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT) { + if (period < 1) { + LOG(ERROR, "VCPU period is not set or out of range, " + "valid values are larger than or equal to 1"); + return 1; + } + *sdom_period = period; + } + + if (budget != LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT) { + if (budget < 1) { + LOG(ERROR, "VCPU budget is not set or out of range, " + "valid values are larger than or equal to 1"); + return 1; + } + *sdom_budget = budget; + } + + if (budget > period) { + LOG(ERROR, "VCPU budget is larger than VCPU period"); + return 1; + } + + return 0; +} + +static int sched_rtds_vcpu_get(libxl__gc *gc, uint32_t domid, + libxl_vcpu_sched_params *scinfo) +{ + uint16_t num_vcpus; + int rc, i; + xc_dominfo_t info; + xen_domctl_schedparam_vcpu_t *vcpus; + + rc = xc_domain_getinfo(CTX->xch, domid, 1, &info); + if (rc < 0) { + LOGE(ERROR, "getting domain info"); + return ERROR_FAIL; + } + + if (scinfo->num_vcpus == 0) + num_vcpus = info.max_vcpu_id + 1; + else + num_vcpus = scinfo->num_vcpus; + + GCNEW_ARRAY(vcpus, num_vcpus); + + if (scinfo->num_vcpus > 0) + for (i=0; i < num_vcpus; i++) { + if (scinfo->vcpus[i].vcpuid < 0 || + scinfo->vcpus[i].vcpuid > info.max_vcpu_id) { + LOG(ERROR, "VCPU index is out of range, " + "valid values are within range from 0 to %d", + info.max_vcpu_id); + return ERROR_INVAL; + } + vcpus[i].vcpuid = scinfo->vcpus[i].vcpuid; + } else + for (i=0; i < num_vcpus; i++) + vcpus[i].vcpuid = i; + + rc = xc_sched_rtds_vcpu_get(CTX->xch, domid, vcpus, num_vcpus); + if (rc != 0) { + LOGE(ERROR, "getting vcpu sched rtds"); + return ERROR_FAIL; + } + + scinfo->sched = LIBXL_SCHEDULER_RTDS; + if (scinfo->num_vcpus == 0) { + scinfo->num_vcpus = num_vcpus; + scinfo->vcpus = libxl__calloc(NOGC, num_vcpus, sizeof(libxl_sched_params)); + } + for(i = 0; i < num_vcpus; i++) { + scinfo->vcpus[i].period = vcpus[i].s.rtds.period; + scinfo->vcpus[i].budget = vcpus[i].s.rtds.budget; + scinfo->vcpus[i].vcpuid = vcpus[i].vcpuid; + } + + return 0; +} + +static int sched_rtds_vcpu_set(libxl__gc *gc, uint32_t domid, + const libxl_vcpu_sched_params *scinfo) +{ + int rc; + int i; + uint16_t max_vcpuid; + xc_dominfo_t info; + xen_domctl_schedparam_vcpu_t *vcpus; + int num_vcpus; + + rc = xc_domain_getinfo(CTX->xch, domid, 1, &info); + if (rc < 0) { + LOGE(ERROR, "getting domain info"); + return ERROR_FAIL; + } + max_vcpuid = info.max_vcpu_id; + + if (scinfo->num_vcpus > 0) { + num_vcpus = scinfo->num_vcpus; + GCNEW_ARRAY(vcpus, num_vcpus); + for (i = 0; i < num_vcpus; i++) { + if (scinfo->vcpus[i].vcpuid < 0 || + scinfo->vcpus[i].vcpuid > max_vcpuid) { + LOG(ERROR, "VCPU index is out of range, " + "valid values are within range from 0 to %d", + max_vcpuid); + return ERROR_INVAL; + } + vcpus[i].vcpuid = scinfo->vcpus[i].vcpuid; + + rc = sched_rtds_validate_params(gc, + scinfo->vcpus[i].period, scinfo->vcpus[i].budget, + &vcpus[i].s.rtds.period, &vcpus[i].s.rtds.budget); + if (rc) + return ERROR_INVAL; + } + } else { + num_vcpus = max_vcpuid + 1; + GCNEW_ARRAY(vcpus, num_vcpus); + rc = sched_rtds_validate_params(gc, + scinfo->vcpus[0].period, scinfo->vcpus[0].budget, + &vcpus[0].s.rtds.period, &vcpus[0].s.rtds.budget); + if (rc) + return ERROR_INVAL; + for (i = 0; i < num_vcpus; i++) { + vcpus[i].vcpuid = i; + vcpus[i].s.rtds.period = scinfo->vcpus[0].period; + vcpus[i].s.rtds.budget = scinfo->vcpus[0].budget; + } + } + + rc = xc_sched_rtds_vcpu_set(CTX->xch, domid, + vcpus, num_vcpus); + if (rc == 1) { + printf("WARN: too small period or budget may " + "result in large scheduling overhead\n"); + rc = 0; + } else if (rc != 0) { + LOGE(ERROR, "setting vcpu sched rtds"); + return ERROR_FAIL; + } + + return rc; +} + static int sched_rtds_domain_get(libxl__gc *gc, uint32_t domid, libxl_domain_sched_params *scinfo) { @@ -5887,29 +6037,10 @@ static int sched_rtds_domain_set(libxl__gc *gc, uint32_t domid, return ERROR_FAIL; } - if (scinfo->period != LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT) { - if (scinfo->period < 1) { - LOG(ERROR, "VCPU period is not set or out of range, " - "valid values are larger than 1"); - return ERROR_INVAL; - } - sdom.period = scinfo->period; - } - - if (scinfo->budget != LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT) { - if (scinfo->budget < 1) { - LOG(ERROR, "VCPU budget is not set or out of range, " - "valid values are larger than 1"); - return ERROR_INVAL; - } - sdom.budget = scinfo->budget; - } - - if (sdom.budget > sdom.period) { - LOG(ERROR, "VCPU budget is larger than VCPU period, " - "VCPU budget should be no larger than VCPU period"); + rc = sched_rtds_validate_params(gc, scinfo->period, scinfo->budget, + &sdom.period, &sdom.budget); + if (rc) return ERROR_INVAL; - } rc = xc_sched_rtds_domain_set(CTX->xch, domid, &sdom); if (rc < 0) { @@ -5920,6 +6051,11 @@ static int sched_rtds_domain_set(libxl__gc *gc, uint32_t domid, return 0; } +/* Set the per-domain scheduling parameters. +* For schedulers that support per-vcpu settings (e.g., RTDS), +* calling *_domain_set functions will set all vcpus with the same +* scheduling parameters. +*/ int libxl_domain_sched_params_set(libxl_ctx *ctx, uint32_t domid, const libxl_domain_sched_params *scinfo) { @@ -5956,6 +6092,52 @@ int libxl_domain_sched_params_set(libxl_ctx *ctx, uint32_t domid, return ret; } +/* Set the per-vcpu scheduling parameters */ +int libxl_vcpu_sched_params_set(libxl_ctx *ctx, uint32_t domid, + const libxl_vcpu_sched_params *scinfo) +{ + GC_INIT(ctx); + libxl_scheduler sched = scinfo->sched; + int ret; + + if (sched == LIBXL_SCHEDULER_UNKNOWN) + sched = libxl__domain_scheduler(gc, domid); + + switch (sched) { + case LIBXL_SCHEDULER_SEDF: + LOG(ERROR, "No per-vcpu set function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_CREDIT: + LOG(ERROR, "No per-vcpu set function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_CREDIT2: + LOG(ERROR, "No per-vcpu set function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_ARINC653: + LOG(ERROR, "No per-vcpu set function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_RTDS: + ret = sched_rtds_vcpu_set(gc, domid, scinfo); + break; + default: + LOG(ERROR, "Unknown scheduler"); + ret = ERROR_INVAL; + break; + } + + GC_FREE; + return ret; +} + +/* Get the per-domain scheduling parameters. +* For schedulers that support per-vcpu settings (e.g., RTDS), +* calling *_domain_get functions will get default scheduling +* parameters. +*/ int libxl_domain_sched_params_get(libxl_ctx *ctx, uint32_t domid, libxl_domain_sched_params *scinfo) { @@ -5989,6 +6171,45 @@ int libxl_domain_sched_params_get(libxl_ctx *ctx, uint32_t domid, return ret; } +/* Get the per-vcpu scheduling parameters */ +int libxl_vcpu_sched_params_get(libxl_ctx *ctx, uint32_t domid, + libxl_vcpu_sched_params *scinfo) +{ + GC_INIT(ctx); + int ret; + + scinfo->sched = libxl__domain_scheduler(gc, domid); + + switch (scinfo->sched) { + case LIBXL_SCHEDULER_SEDF: + LOG(ERROR, "No per-vcpu get function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_CREDIT: + LOG(ERROR, "No per-vcpu get function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_CREDIT2: + LOG(ERROR, "No per-vcpu get function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_ARINC653: + LOG(ERROR, "No per-vcpu get function provided"); + ret = ERROR_INVAL; + break; + case LIBXL_SCHEDULER_RTDS: + ret = sched_rtds_vcpu_get(gc, domid, scinfo); + break; + default: + LOG(ERROR, "Unknown scheduler"); + ret = ERROR_INVAL; + break; + } + + GC_FREE; + return ret; +} + static int libxl__domain_s3_resume(libxl__gc *gc, int domid) { int rc = 0; diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index a1c5d15..040a248 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -200,6 +200,16 @@ #define LIBXL_HAVE_DEVICETREE_PASSTHROUGH 1 /* + * libxl_vcpu_sched_params is used to store per-vcpu params +*/ +#define LIBXL_HAVE_VCPU_SCHED_PARAMS 1 + +/* + * libxl_sched_params is used to store the array of per-vcpu params +*/ +#define LIBXL_HAVE_SCHED_PARAMS 1 + +/* * libxl ABI compatibility * * The only guarantee which libxl makes regarding ABI compatibility @@ -1554,10 +1564,17 @@ int libxl_sched_credit_params_set(libxl_ctx *ctx, uint32_t poolid, #define LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT -1 #define LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT -1 +/* Per-VCPU parameters*/ +#define LIBXL_SCHED_PARAM_VCPU_INDEX_DEFAULT -1 + int libxl_domain_sched_params_get(libxl_ctx *ctx, uint32_t domid, libxl_domain_sched_params *params); int libxl_domain_sched_params_set(libxl_ctx *ctx, uint32_t domid, const libxl_domain_sched_params *params); +int libxl_vcpu_sched_params_get(libxl_ctx *ctx, uint32_t domid, + libxl_vcpu_sched_params *params); +int libxl_vcpu_sched_params_set(libxl_ctx *ctx, uint32_t domid, + const libxl_vcpu_sched_params *params); int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid, libxl_trigger trigger, uint32_t vcpuid); diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index e1632fa..ff70372 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -351,6 +351,22 @@ libxl_domain_restore_params = Struct("domain_restore_params", [ ("checkpointed_stream", integer), ]) +libxl_sched_params = Struct("sched_params",[ + ("vcpuid", integer, {'init_val': 'LIBXL_SCHED_PARAM_VCPU_INDEX_DEFAULT'}), + ("weight", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT'}), + ("cap", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_CAP_DEFAULT'}), + ("period", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT'}), + ("slice", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT'}), + ("latency", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_LATENCY_DEFAULT'}), + ("extratime", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT'}), + ("budget", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT'}), + ]) + +libxl_vcpu_sched_params = Struct("vcpu_sched_params",[ + ("sched", libxl_scheduler), + ("vcpus", Array(libxl_sched_params, "num_vcpus")), + ]) + libxl_domain_sched_params = Struct("domain_sched_params",[ ("sched", libxl_scheduler), ("weight", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT'}), -- 1.9.1