From 31405d5bee44519f51db22573de928419c1342a3 Mon Sep 17 00:00:00 2001 From: Furkan Caliskan Date: Fri, 18 Sep 2026 13:41:06 +0300 Subject: [PATCH] tools: expose admission control toggle via xl sched-rtds Wire the per-cpupool admission-control switch through libxl to xl sched-rtds, and document it. Add -s/--schedparam to list or set pool-wide RTDS scheduler parameters, and -a/--admission to enable or disable admission control for a cpupool ("-c pool -s -a 0/1"). Signed-off-by: Furkan Caliskan Reviewed-by: Juergen Gross Acked-by: Anthony PERARD --- docs/man/xl.1.pod.in | 20 ++++++ tools/golang/xenlight/helpers.gen.go | 23 ++++++ tools/golang/xenlight/types.gen.go | 4 ++ tools/include/libxl.h | 12 ++++ tools/include/xenctrl.h | 6 ++ tools/libs/ctrl/xc_rt.c | 40 +++++++++++ tools/libs/light/libxl_sched.c | 46 ++++++++++++ tools/libs/light/libxl_types.idl | 5 ++ tools/xl/xl_cmdtable.c | 8 ++- tools/xl/xl_sched.c | 100 +++++++++++++++++++++++++-- 10 files changed, 259 insertions(+), 5 deletions(-) diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in index 88ccf7ad82..51405f4e33 100644 --- a/docs/man/xl.1.pod.in +++ b/docs/man/xl.1.pod.in @@ -1230,6 +1230,16 @@ the unreserved system resource. Restrict output to domains in the specified cpupool. +=item B<-s>, B<--schedparam> + +Specify to list or set pool-wide scheduler parameters. + +=item B<-a ADMISSION_CONTROL>, B<--admission=ADMISSION_CONTROL> + +Binary flag to enable or disable admission control for the cpupool. +When enabled (the default), a reservation is rejected if admitting +it would exceed the cpupool's utilization capacity. + =back B @@ -1293,6 +1303,16 @@ e.g., "xl sched-rtds -d vm1 -v 0 -p 100 -b 50 -e 1 -v 3 -p 300 -b 150 -e 0". To change the parameters of all the VCPUs of a domain, use B<-v all>, e.g., "xl sched-rtds -d vm1 -v all -p 500 -b 250 -e 1". +4) Use B<-c CPUPOOL -s> to see whether admission control is enabled +for a cpupool, and B<-c CPUPOOL -s -a> to change it: + + xl sched-rtds -c pool-rt -s + Cpupool pool-rt: sched=RTDS admission-control=enabled + + xl sched-rtds -c pool-rt -s -a 0 + xl sched-rtds -c pool-rt -s + Cpupool pool-rt: sched=RTDS admission-control=disabled + =back =back diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go index b0c09da910..18ab0731ef 100644 --- a/tools/golang/xenlight/helpers.gen.go +++ b/tools/golang/xenlight/helpers.gen.go @@ -4192,6 +4192,29 @@ func (x *SchedCredit2Params) toC(xc *C.libxl_sched_credit2_params) (err error){x return nil } +// NewSchedRtdsParams returns an instance of SchedRtdsParams initialized with defaults. +func NewSchedRtdsParams() (*SchedRtdsParams, error) { +var ( +x SchedRtdsParams +xc C.libxl_sched_rtds_params) + +C.libxl_sched_rtds_params_init(&xc) + +if err := x.fromC(&xc); err != nil { +return nil, err } + +return &x, nil} + +func (x *SchedRtdsParams) fromC(xc *C.libxl_sched_rtds_params) error { + x.AdmissionControlEnabled = bool(xc.admission_control_enabled) + + return nil} + +func (x *SchedRtdsParams) toC(xc *C.libxl_sched_rtds_params) (err error){xc.admission_control_enabled = C.bool(x.AdmissionControlEnabled) + + return nil + } + // NewDomainRemusInfo returns an instance of DomainRemusInfo initialized with defaults. func NewDomainRemusInfo() (*DomainRemusInfo, error) { var ( diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go index e0fd78ec03..897100d9b6 100644 --- a/tools/golang/xenlight/types.gen.go +++ b/tools/golang/xenlight/types.gen.go @@ -1231,6 +1231,10 @@ type SchedCredit2Params struct { RatelimitUs int } +type SchedRtdsParams struct { +AdmissionControlEnabled bool +} + type DomainRemusInfo struct { Interval int AllowUnsafe Defbool diff --git a/tools/include/libxl.h b/tools/include/libxl.h index 7c098edab6..617ce973b2 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -229,6 +229,14 @@ */ #define LIBXL_HAVE_SCHED_RTDS 1 +/* + * LIBXL_HAVE_SCHED_RTDS_PARAMS indicates that libxl has the + * libxl_sched_rtds_params type, along with library functions + * libxl_sched_rtds_params_get/set to get and set pool-wide RTDS + * scheduler parameters for a given cpupool. + */ +#define LIBXL_HAVE_SCHED_RTDS_PARAMS 1 + /* * LIBXL_HAVE_SCHED_NULL indicates that the 'null' static scheduler * is available. @@ -2797,6 +2805,10 @@ int libxl_sched_credit2_params_get(libxl_ctx *ctx, uint32_t poolid, libxl_sched_credit2_params *scinfo); int libxl_sched_credit2_params_set(libxl_ctx *ctx, uint32_t poolid, libxl_sched_credit2_params *scinfo); +int libxl_sched_rtds_params_get(libxl_ctx *ctx, uint32_t poolid, + libxl_sched_rtds_params *scinfo); +int libxl_sched_rtds_params_set(libxl_ctx *ctx, uint32_t poolid, + libxl_sched_rtds_params *scinfo); /* Scheduler Per-domain parameters */ diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index 9f00d4a19d..6f4ea7ca62 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -897,6 +897,12 @@ int xc_sched_rtds_vcpu_get(xc_interface *xch, uint32_t domid, struct xen_domctl_schedparam_vcpu *vcpus, uint32_t num_vcpus); +int xc_sched_rtds_params_set(xc_interface *xch, + uint32_t cpupool_id, + struct xen_sysctl_rtds_schedule *schedule); +int xc_sched_rtds_params_get(xc_interface *xch, + uint32_t cpupool_id, + struct xen_sysctl_rtds_schedule *schedule); int xc_sched_arinc653_schedule_set( diff --git a/tools/libs/ctrl/xc_rt.c b/tools/libs/ctrl/xc_rt.c index 3cb3fbb923..fb3f567d4f 100644 --- a/tools/libs/ctrl/xc_rt.c +++ b/tools/libs/ctrl/xc_rt.c @@ -130,3 +130,43 @@ int xc_sched_rtds_vcpu_get(xc_interface *xch, return rc; } + +int xc_sched_rtds_params_set(xc_interface *xch, + uint32_t cpupool_id, + struct xen_sysctl_rtds_schedule *schedule) +{ + struct xen_sysctl sysctl = {}; + + sysctl.cmd = XEN_SYSCTL_scheduler_op; + sysctl.u.scheduler_op.cpupool_id = cpupool_id; + sysctl.u.scheduler_op.sched_id = XEN_SCHEDULER_RTDS; + sysctl.u.scheduler_op.cmd = XEN_SYSCTL_SCHEDOP_putinfo; + + sysctl.u.scheduler_op.u.sched_rtds = *schedule; + + if ( do_sysctl(xch, &sysctl) ) + return -1; + + *schedule = sysctl.u.scheduler_op.u.sched_rtds; + + return 0; +} + +int xc_sched_rtds_params_get(xc_interface *xch, + uint32_t cpupool_id, + struct xen_sysctl_rtds_schedule *schedule) +{ + struct xen_sysctl sysctl = {}; + + sysctl.cmd = XEN_SYSCTL_scheduler_op; + sysctl.u.scheduler_op.cpupool_id = cpupool_id; + sysctl.u.scheduler_op.sched_id = XEN_SCHEDULER_RTDS; + sysctl.u.scheduler_op.cmd = XEN_SYSCTL_SCHEDOP_getinfo; + + if ( do_sysctl(xch, &sysctl) ) + return -1; + + *schedule = sysctl.u.scheduler_op.u.sched_rtds; + + return 0; +} diff --git a/tools/libs/light/libxl_sched.c b/tools/libs/light/libxl_sched.c index 2d6635dae7..ae4379cf09 100644 --- a/tools/libs/light/libxl_sched.c +++ b/tools/libs/light/libxl_sched.c @@ -397,6 +397,52 @@ int libxl_sched_credit2_params_set(libxl_ctx *ctx, uint32_t poolid, return rc; } +int libxl_sched_rtds_params_get(libxl_ctx *ctx, uint32_t poolid, + libxl_sched_rtds_params *scinfo) +{ + struct xen_sysctl_rtds_schedule sparam; + int r, rc; + GC_INIT(ctx); + + r = xc_sched_rtds_params_get(ctx->xch, poolid, &sparam); + if (r < 0) { + LOGE(ERROR, "getting RTDS scheduler parameters"); + rc = ERROR_FAIL; + goto out; + } + + scinfo->admission_control_enabled = sparam.admission_control_enabled; + + rc = 0; +out: + GC_FREE; + return rc; +} + +int libxl_sched_rtds_params_set(libxl_ctx *ctx, uint32_t poolid, + libxl_sched_rtds_params *scinfo) +{ + struct xen_sysctl_rtds_schedule sparam; + int r, rc; + GC_INIT(ctx); + + sparam.admission_control_enabled = scinfo->admission_control_enabled; + + r = xc_sched_rtds_params_set(ctx->xch, poolid, &sparam); + if (r < 0) { + LOGE(ERROR, "Setting RTDS scheduler parameters"); + rc = ERROR_FAIL; + goto out; + } + + scinfo->admission_control_enabled = sparam.admission_control_enabled; + + rc = 0; +out: + GC_FREE; + return rc; +} + static int sched_credit2_domain_get(libxl__gc *gc, uint32_t domid, libxl_domain_sched_params *scinfo) { diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index a7893460f0..d3121ea277 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -1286,6 +1286,11 @@ libxl_sched_credit2_params = Struct("sched_credit2_params", [ ("ratelimit_us", integer), ], dispose_fn=None) +libxl_sched_rtds_params = Struct("sched_rtds_params", [ + ("admission_control_enabled", bool), + ], dispose_fn=None) + + libxl_domain_remus_info = Struct("domain_remus_info",[ ("interval", integer), ("allow_unsafe", libxl_defbool), diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c index 502244f683..e48d5c5edc 100644 --- a/tools/xl/xl_cmdtable.c +++ b/tools/xl/xl_cmdtable.c @@ -295,13 +295,19 @@ const struct cmd_spec cmd_table[] = { { "sched-rtds", &main_sched_rtds, 0, 1, "Get/set rtds scheduler parameters", - "[-d [-v[=VCPUID/all]] [-p[=PERIOD]] [-b[=BUDGET]] [-e[=Extratime]]]", + "[-d [-v[=VCPUID/all]] [-p[=PERIOD]] [-b[=BUDGET]] [-e[=Extratime]]]\n" + " [-c -s [-a[=ADMISSION_CONTROL]]]", "-d DOMAIN, --domain=DOMAIN Domain to modify\n" "-v VCPUID/all, --vcpuid=VCPUID/all VCPU to modify or output;\n" " Using '-v all' to modify/output all vcpus\n" "-p PERIOD, --period=PERIOD Period (us)\n" "-b BUDGET, --budget=BUDGET Budget (us)\n" "-e Extratime, --extratime=Extratime Extratime (1=yes, 0=no)\n" + "-c CPUPOOL, --cpupool=CPUPOOL Restrict output to domains in CPUPOOL\n" + "-s, --schedparam List or set pool-wide scheduler parameters\n" + "-a ADMISSION_CONTROL, --admission=ADMISSION_CONTROL\n" + " Enable or disable admission control for the cpupool\n" + " (1=enabled, 0=disabled); requires -s\n" }, { "domid", &main_domid, 0, 0, diff --git a/tools/xl/xl_sched.c b/tools/xl/xl_sched.c index 73cd7040cd..4477f71e67 100644 --- a/tools/xl/xl_sched.c +++ b/tools/xl/xl_sched.c @@ -246,6 +246,28 @@ static int sched_credit2_pool_output(uint32_t poolid) return 0; } +static int sched_rtds_params_set(int poolid, + libxl_sched_rtds_params *scinfo) +{ + if (libxl_sched_rtds_params_set(ctx, poolid, scinfo)) { + fprintf(stderr, "libxl_sched_rtds_params_set failed.\n"); + return 1; + } + + return 0; +} + +static int sched_rtds_params_get(int poolid, + libxl_sched_rtds_params *scinfo) +{ + if (libxl_sched_rtds_params_get(ctx, poolid, scinfo)) { + fprintf(stderr, "libxl_sched_rtds_params_get failed.\n"); + return 1; + } + + return 0; +} + static int sched_rtds_domain_output( int domid) { @@ -339,10 +361,15 @@ static int sched_rtds_vcpu_output_all(int domid, static int sched_rtds_pool_output(uint32_t poolid) { - char *poolname; + libxl_sched_rtds_params scparam; + char *poolname = libxl_cpupoolid_to_name(ctx, poolid); - poolname = libxl_cpupoolid_to_name(ctx, poolid); - printf("Cpupool %s: sched=RTDS\n", poolname); + if (sched_rtds_params_get(poolid, &scparam)) + printf("Cpupool %s: [sched params unavailable]\n", poolname); + else + printf("Cpupool %s: sched=RTDS admission-control=%s\n", + poolname, + scparam.admission_control_enabled ? "enabled" : "disabled"); free(poolname); return 0; @@ -715,6 +742,8 @@ int main_sched_credit2(int argc, char **argv) * -d [domid] -v [vcpuid 1] [params] -v [vcpuid 2] [params] ... : * Set per-VCPU params for domain * -d [domid] -v all [params] : Set all per-VCPU params for domain + * -c [cpupool] -s : List pool-wide scheduling parameters for cpupool + * -c [cpupool] -s -a [0|1] : Set admission control for cpupool */ int main_sched_rtds(int argc, char **argv) { @@ -736,7 +765,10 @@ int main_sched_rtds(int argc, char **argv) bool opt_b = false; bool opt_e = false; bool opt_v = false; + bool opt_s = false; + bool opt_a = false; bool opt_all = false; /* output per-dom parameters */ + bool admission_control = false; int opt, i, rc, r; static struct option opts[] = { {"domain", 1, 0, 'd'}, @@ -745,10 +777,12 @@ int main_sched_rtds(int argc, char **argv) {"extratime", 1, 0, 'e'}, {"vcpuid",1, 0, 'v'}, {"cpupool", 1, 0, 'c'}, + {"schedparam", 0, 0, 's'}, + {"admission", 1, 0, 'a'}, COMMON_LONG_OPTS }; - SWITCH_FOREACH_OPT(opt, "d:p:b:e:v:c", opts, "sched-rtds", 0) { + SWITCH_FOREACH_OPT(opt, "d:p:b:e:v:c:a:s", opts, "sched-rtds", 0) { case 'd': dom = optarg; break; @@ -801,6 +835,19 @@ int main_sched_rtds(int argc, char **argv) case 'c': cpupool = optarg; break; + case 's': + opt_s = true; + break; + case 'a': + if (strcmp(optarg, "0") && strcmp(optarg, "1")) + { + fprintf(stderr, "Invalid admission_control value.\n"); + r = EXIT_FAILURE; + goto out; + } + admission_control = strtol(optarg, NULL, 10); + opt_a = true; + break; } if (cpupool && (dom || opt_p || opt_b || opt_e || opt_v || opt_all)) { @@ -809,6 +856,11 @@ int main_sched_rtds(int argc, char **argv) r = EXIT_FAILURE; goto out; } + if (opt_s && (dom || opt_p || opt_b || opt_e || opt_v || opt_all)) { + fprintf(stderr, "-s cannot be combined with domain/VCPU options.\n"); + r = EXIT_FAILURE; + goto out; + } if (!dom && (opt_p || opt_b || opt_e || opt_v)) { fprintf(stderr, "Missing parameters.\n"); r = EXIT_FAILURE; @@ -831,6 +883,46 @@ int main_sched_rtds(int argc, char **argv) r = EXIT_FAILURE; goto out; } + if (opt_a && !opt_s) { + fprintf(stderr, "-a/--admission requires -s/--schedparam.\n"); + r = EXIT_FAILURE; + goto out; + } + + if (opt_s) + { + libxl_sched_rtds_params scparam; + uint32_t poolid = 0; + + if (cpupool) { + if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool, + &poolid, NULL) || + !libxl_cpupoolid_is_valid(ctx, poolid)) { + fprintf(stderr, "Unknown cpupool \'%s\'\n", cpupool); + r = EXIT_FAILURE; + goto out; + } + } + + if (!opt_a) { /* output pool-wide scheduling parameters */ + if (sched_rtds_pool_output(poolid)) { + r = EXIT_FAILURE; + goto out; + } + } else { /* set pool-wide scheduling parameters */ + scparam = (libxl_sched_rtds_params){ + .admission_control_enabled = admission_control, + }; + + if (sched_rtds_params_set(poolid, &scparam)) { + r = EXIT_FAILURE; + goto out; + } + } + + r = EXIT_SUCCESS; + goto out; + } if ((!dom) && opt_all) { /* get all domain's per-vcpu rtds scheduler parameters */