All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] xen/sched: rtds: add per-cpupool admission control
@ 2026-08-26  4:57 Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 1/5] xen/sched: rtds: add global-EDF utilization " Furkan Caliskan
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Furkan Caliskan @ 2026-08-26  4:57 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, jbeulich, andrew.cooper3, roger, dfaggioli,
	anthony.perard, julien, sstabellini, gwd, enr0n, michal.orzel,
	Furkan Caliskan

RTDS currently has no admission control: nothing stops the sum of
all admitted units' (budget/period) reservations in a cpupool from
exceeding what its pCPUs can actually provide. Once that happens,
the global-EDF deadline guarantees the scheduler is built around no
longer hold for any unit sharing that pool.

This series adds admission control to prevent that, tracks and
report utilization, and makes the check toggleable per cpupool so
an operator can disable it if they intentionally want to overcommit.

Patch 1 introduces the core mechanism: a running utilization total
per cpupool, a fixed-point representation of a unit's (budget/period),
and a capacity check enforced in rt_alloc_udata()/rt_free_udata() -
the lifecycle hooks that catch every new unit's default reservation.

Patch 2 extends the same check to domctl, so growing an existing
reservation via xl sched-rtds is checked too.

Patch 3 reports a cpupool's admitted utilization agains its capacity
via the 'r' debug key.

Patch 4 makes admission control itself toggleable per cpupool
(enabled by default) via sysctl.

Patch 5 wires that toggle through libxl and adds -s/-a to
xl sched-rtds, and documents it.

Furkan Caliskan (5):
  xen/sched: rtds: add global-EDF utilization admission control
  xen/sched: rtds: enforce admission control in xl sched-rtds
  xen/sched: rtds: report utilization and cap via debug key
  xen/sched: rtds: make admission control cpupool-wide toggleable
  tools: expose admission control toggle via xl sched-rtds

 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                |   4 +
 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                  | 103 +++++++++++++-
 xen/common/sched/rt.c                | 205 ++++++++++++++++++++++++++-
 xen/include/public/sysctl.h          |   5 +
 12 files changed, 463 insertions(+), 6 deletions(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] xen/sched: rtds: add global-EDF utilization admission control
  2026-08-26  4:57 [PATCH 0/5] xen/sched: rtds: add per-cpupool admission control Furkan Caliskan
@ 2026-08-26  4:57 ` Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 2/5] xen/sched: rtds: enforce admission control in xl sched-rtds Furkan Caliskan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Furkan Caliskan @ 2026-08-26  4:57 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, jbeulich, andrew.cooper3, roger, dfaggioli,
	anthony.perard, julien, sstabellini, gwd, enr0n, michal.orzel,
	Furkan Caliskan

RTDS has no admission control: nothing stops the sum of all admitted
units' (budget/period) reservations in a cpupool from exceeding
what its pCPUs can actually provide. Once that happens, none of the
EDF deadline guarantees this scheduler is built around still hold
for the units sharing that pool.

Introduce admission control to prevent this: reject a reservation
whenever admitting it would push a cpupool's units over its capacity.
Track a running utilization total per cpupool, and enforce it in
rt_alloc_udata()/rt_free_udata(), the paired lifecycle hooks for a
unit's creation and destruction. This catches the default
period/budget every new unit gets.

Utilization is represented as a fixed-point value: budget is
left shifted by RTDS_UTIL_SHIFT (20 bits) and divided by period.
A plain "(budget << RTDS_UTIL_SHIFT) / period" risks overflowing
the multiply for large enough budgets. Rather than widen the
arithmetic to tolerate any input, the input itself is bounded:
rt_validate_params() rejects any budget above RTDS_MAX_BUDGET,
chosen as the largest value that can be left-shifted by
RTDS_UTIL_SHIFT without overflowing 64 bits, so the shift in
rt_unit_utilization() can never overflow.

A cpupool's capacity rt_utilization_cap() scales with the number of
scheduling resources in it. It is calculated as:
(number of sched_resources * RTDS_UTIL_SCALE * RTDS_UTIL_CAP_PCT / 100),
where RTDS_UTIL_CAP_PCT controls how much of that capacity can
actually be reserved; at 100% (its current value), all of it can be.

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
---
 xen/common/sched/rt.c | 105 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 104 insertions(+), 1 deletion(-)

diff --git a/xen/common/sched/rt.c b/xen/common/sched/rt.c
index 0e9f04ea72..9126320801 100644
--- a/xen/common/sched/rt.c
+++ b/xen/common/sched/rt.c
@@ -114,6 +114,24 @@
  */
 #define RTDS_MAX_PRIORITY_LEVEL (~0U)
 
+/*
+ * Fixed-point scale for utilization (budget/period)
+ */
+#define RTDS_UTIL_SHIFT     20
+#define RTDS_UTIL_SCALE     (1ULL << RTDS_UTIL_SHIFT)
+
+/*
+ * Largest budget safe to left-shift by RTDS_UTIL_SHIFT without
+ * overflowing 64 bits. Enforced in rt_validate_params().
+ */
+#define RTDS_MAX_BUDGET_BITS  (64 - RTDS_UTIL_SHIFT)
+#define RTDS_MAX_BUDGET       ((1ULL << RTDS_MAX_BUDGET_BITS) - 1)
+
+/*
+ * % of a cpupool's sched_resource capacity admitted units may sum up to.
+ */
+#define RTDS_UTIL_CAP_PCT   100
+
 /*
  * UPDATE_LIMIT_SHIFT: a constant used in rt_update_deadline(). When finding
  * the next deadline, performing addition could be faster if the difference
@@ -195,6 +213,9 @@ struct rt_private {
     struct list_head replq;     /* ordered list of units that need replenishment */
 
     cpumask_t tickled;          /* cpus been tickled */
+
+    /* Sum of admitted units' (budget/period), scaled by RTDS_UTIL_SCALE */
+    uint64_t utilization;
 };
 
 /*
@@ -635,6 +656,54 @@ replq_reinsert(const struct scheduler *ops, struct rt_unit *svc)
         set_timer(&rt_priv(ops)->repl_timer, rearm_svc->cur_deadline);
 }
 
+/*
+ * budget << RTDS_UTIL_SHIFT can't overflow: rt_validate_params()
+ * caps budget at RTDS_MAX_BUDGET. period == 0 means "no
+ * reservation" (a unit being removed), not an error.
+ */
+static uint64_t
+rt_unit_utilization(s_time_t period, s_time_t budget)
+{
+    if ( period <= 0 )
+        return 0;
+
+    return ((uint64_t)budget << RTDS_UTIL_SHIFT) / (uint64_t)period;
+}
+
+/*
+ * Utilization capacity of the cpupool domain d resides in.
+ */
+static uint64_t
+rt_utilization_cap(const struct domain *d)
+{
+    unsigned int cpus = cpumask_weight(cpupool_domain_master_cpumask(d));
+
+    return (uint64_t)cpus * RTDS_UTIL_SCALE * RTDS_UTIL_CAP_PCT / 100;
+}
+
+/*
+ * Replaces a unit's reservation and updates prv->utilization
+ * to match. Growth that would push utilization over the
+ * cpupool's cap is refused. Removing a unit or shrinking
+ * a unit's reservation always succeed.
+ */
+static int
+rt_admission_test(struct rt_private *prv, const struct domain *d,
+		   s_time_t old_period, s_time_t old_budget,
+		   s_time_t new_period, s_time_t new_budget)
+{
+    uint64_t old_util = rt_unit_utilization(old_period, old_budget);
+    uint64_t new_util = rt_unit_utilization(new_period, new_budget);
+    uint64_t total    = prv->utilization - old_util + new_util;
+
+    if ( new_util > old_util && total > rt_utilization_cap(d) )
+        return -EINVAL;
+
+    prv->utilization = total;
+
+    return 0;
+}
+
 /*
  * Pick a valid resource for the unit vc
  * Valid resource of an unit is intesection of unit's affinity
@@ -864,6 +933,7 @@ rt_free_domdata(const struct scheduler *ops, void *data)
 static void * cf_check
 rt_alloc_udata(const struct scheduler *ops, struct sched_unit *unit, void *dd)
 {
+    struct rt_private *prv = rt_priv(ops);
     struct rt_unit *svc;
 
     /* Allocate per-UNIT info */
@@ -881,9 +951,30 @@ rt_alloc_udata(const struct scheduler *ops, struct sched_unit *unit, void *dd)
     __set_bit(__RTDS_extratime, &svc->flags);
     svc->priority_level = 0;
     svc->period = RTDS_DEFAULT_PERIOD;
+
     if ( !is_idle_unit(unit) )
+    {
+        unsigned long flags;
+        int rc;
+
         svc->budget = RTDS_DEFAULT_BUDGET;
 
+        spin_lock_irqsave(&prv->lock, flags);
+        rc = rt_admission_test(prv, unit->domain, 0, 0,
+                                svc->period, svc->budget);
+        spin_unlock_irqrestore(&prv->lock, flags);
+
+        if ( rc )
+        {
+            printk(XENLOG_WARNING
+                   "RTDS: ADMISSION CONTROL: refusing unit %u of d%d,"
+                   " would exceed utilization capacity of the cpupool\n",
+                   unit->unit_id, unit->domain->domain_id);
+            xfree(svc);
+            return NULL;
+        }
+    }
+
     SCHED_STAT_CRANK(unit_alloc);
 
     return svc;
@@ -892,8 +983,19 @@ rt_alloc_udata(const struct scheduler *ops, struct sched_unit *unit, void *dd)
 static void cf_check
 rt_free_udata(const struct scheduler *ops, void *priv)
 {
+    struct rt_private *prv = rt_priv(ops);
     struct rt_unit *svc = priv;
 
+    if ( svc && !is_idle_unit(svc->unit) )
+    {
+        unsigned long flags;
+
+        spin_lock_irqsave(&prv->lock, flags);
+        rt_admission_test(prv, svc->unit->domain,
+                           svc->period, svc->budget, 0, 0);
+        spin_unlock_irqrestore(&prv->lock, flags);
+    }
+
     xfree(svc);
 }
 
@@ -1389,7 +1491,8 @@ rt_validate_params(const struct xen_domctl_sched_rtds *rtds,
     s_time_t b = MICROSECS(rtds->budget);
 
     if ( p < RTDS_MIN_PERIOD || p > RTDS_MAX_PERIOD ||
-         b < RTDS_MIN_BUDGET || b > p )
+         b < RTDS_MIN_BUDGET || b > p ||
+         b > (s_time_t)RTDS_MAX_BUDGET )
         return -EINVAL;
 
     *period = p;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5] xen/sched: rtds: enforce admission control in xl sched-rtds
  2026-08-26  4:57 [PATCH 0/5] xen/sched: rtds: add per-cpupool admission control Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 1/5] xen/sched: rtds: add global-EDF utilization " Furkan Caliskan
@ 2026-08-26  4:57 ` Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 3/5] xen/sched: rtds: report utilization and cap via debug key Furkan Caliskan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Furkan Caliskan @ 2026-08-26  4:57 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, jbeulich, andrew.cooper3, roger, dfaggioli,
	anthony.perard, julien, sstabellini, gwd, enr0n, michal.orzel,
	Furkan Caliskan

Now that we have introduced admission control for new and
removed units. Extend it to XEN_DOMCTL_SCHEDOP_putinfo and
putvcpuinfo, so growing an existing reservation via
xl sched-rtds is checked too.

putinfo sets the same (period, budget) for every unit of a
domain at once, so it tests the whole domain's utilization
delta atomically, rather than unit-by-unit, which could
spuriously reject an overall-acceptable change depending on
iteration order.

putvcpuinfo changes one unit at a time, so it just calls
rt_admission_test() directly.

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
---
 xen/common/sched/rt.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/xen/common/sched/rt.c b/xen/common/sched/rt.c
index 9126320801..9643a277fe 100644
--- a/xen/common/sched/rt.c
+++ b/xen/common/sched/rt.c
@@ -1527,11 +1527,43 @@ rt_dom_cntl(
         op->u.rtds.budget = RTDS_DEFAULT_BUDGET / MICROSECS(1);
         break;
     case XEN_DOMCTL_SCHEDOP_putinfo:
+    {
+        uint64_t dom_old_util = 0, new_util, new_total;
+        unsigned int nr_units = 0;
+
         rc = rt_validate_params(&op->u.rtds, &period, &budget);
         if ( rc )
             break;
 
+        new_util = rt_unit_utilization(period, budget);
+
         spin_lock_irqsave(&prv->lock, flags);
+
+        /*
+         * Same (period, budget) for every unit of d: test and commit
+         * the domain's whole utilization delta atomically, rather
+         * than unit-by-unit, which could spuriously reject an
+         * overall-acceptable change depending on iteration order.
+         */
+        for_each_sched_unit ( d, unit )
+        {
+            svc = rt_unit(unit);
+            dom_old_util += rt_unit_utilization(svc->period, svc->budget);
+            nr_units++;
+        }
+
+        new_total = prv->utilization - dom_old_util +
+                    (uint64_t)nr_units * new_util;
+
+        if ( new_total > prv->utilization && new_total > rt_utilization_cap(d) )
+        {
+            rc = -EINVAL;
+            spin_unlock_irqrestore(&prv->lock, flags);
+            break;
+        }
+
+        prv->utilization = new_total;
+
         for_each_sched_unit ( d, unit )
         {
             svc = rt_unit(unit);
@@ -1540,6 +1572,7 @@ rt_dom_cntl(
         }
         spin_unlock_irqrestore(&prv->lock, flags);
         break;
+    }
     case XEN_DOMCTL_SCHEDOP_getvcpuinfo:
     case XEN_DOMCTL_SCHEDOP_putvcpuinfo:
         while ( index < op->u.v.nr_vcpus )
@@ -1584,6 +1617,15 @@ rt_dom_cntl(
 
                 spin_lock_irqsave(&prv->lock, flags);
                 svc = rt_unit(d->vcpu[local_sched.vcpuid]->sched_unit);
+
+                rc = rt_admission_test(prv, d, svc->period, svc->budget,
+                                        period, budget);
+                if ( rc )
+                {
+                    spin_unlock_irqrestore(&prv->lock, flags);
+                    break;
+                }
+
                 svc->period = period;
                 svc->budget = budget;
                 if ( local_sched.u.rtds.flags & XEN_DOMCTL_SCHEDRT_extra )
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5] xen/sched: rtds: report utilization and cap via debug key
  2026-08-26  4:57 [PATCH 0/5] xen/sched: rtds: add per-cpupool admission control Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 1/5] xen/sched: rtds: add global-EDF utilization " Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 2/5] xen/sched: rtds: enforce admission control in xl sched-rtds Furkan Caliskan
@ 2026-08-26  4:57 ` Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 4/5] xen/sched: rtds: make admission control cpupool-wide toggleable Furkan Caliskan
  2026-08-26  4:57 ` [PATCH 5/5] tools: expose admission control toggle via xl sched-rtds Furkan Caliskan
  4 siblings, 0 replies; 7+ messages in thread
From: Furkan Caliskan @ 2026-08-26  4:57 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, jbeulich, andrew.cooper3, roger, dfaggioli,
	anthony.perard, julien, sstabellini, gwd, enr0n, michal.orzel,
	Furkan Caliskan

Print a cpupool's admitted utilization against its capacity in the
'r' debug ky (xl debug-keys r), so an operator can see the total
usage of a cpupool.

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
---
 xen/common/sched/rt.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/xen/common/sched/rt.c b/xen/common/sched/rt.c
index 9643a277fe..0582c0094d 100644
--- a/xen/common/sched/rt.c
+++ b/xen/common/sched/rt.c
@@ -399,12 +399,22 @@ rt_dump(const struct scheduler *ops)
     const struct rt_unit *svc;
     const struct rt_dom *sdom;
     unsigned long flags;
+    uint64_t cap;
 
     spin_lock_irqsave(&prv->lock, flags);
 
     if ( list_empty(&prv->sdom) )
         goto out;
 
+    cap = (uint64_t)cpumask_weight(ops->cpupool->res_valid) *
+          RTDS_UTIL_SCALE * RTDS_UTIL_CAP_PCT / 100;
+
+    if ( cap )
+        printk("Utilization: %llu%% of capacity\n",
+               (unsigned long long)(prv->utilization * 100 / cap));
+    else
+        printk("Utilization: cpupool has no capacity\n");
+
     runq = rt_runq(ops);
     depletedq = rt_depletedq(ops);
     replq = rt_replq(ops);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] xen/sched: rtds: make admission control cpupool-wide toggleable
  2026-08-26  4:57 [PATCH 0/5] xen/sched: rtds: add per-cpupool admission control Furkan Caliskan
                   ` (2 preceding siblings ...)
  2026-08-26  4:57 ` [PATCH 3/5] xen/sched: rtds: report utilization and cap via debug key Furkan Caliskan
@ 2026-08-26  4:57 ` Furkan Caliskan
  2026-08-26  6:14   ` Jan Beulich
  2026-08-26  4:57 ` [PATCH 5/5] tools: expose admission control toggle via xl sched-rtds Furkan Caliskan
  4 siblings, 1 reply; 7+ messages in thread
From: Furkan Caliskan @ 2026-08-26  4:57 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, jbeulich, andrew.cooper3, roger, dfaggioli,
	anthony.perard, julien, sstabellini, gwd, enr0n, michal.orzel,
	Furkan Caliskan

Add a per-cpupool on/off switch for RTDS admission control via
XEN_SYSCTL_scheduler_op, enabled by default, so an operator can
disable/enable enforcement for a pool.

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
---
 xen/common/sched/rt.c       | 56 ++++++++++++++++++++++++++++++++++---
 xen/include/public/sysctl.h |  5 ++++
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/xen/common/sched/rt.c b/xen/common/sched/rt.c
index 0582c0094d..b150f84242 100644
--- a/xen/common/sched/rt.c
+++ b/xen/common/sched/rt.c
@@ -216,6 +216,8 @@ struct rt_private {
 
     /* Sum of admitted units' (budget/period), scaled by RTDS_UTIL_SCALE */
     uint64_t utilization;
+
+    bool admission_control_enabled; /* on/off flag for admission control. */
 };
 
 /*
@@ -409,6 +411,9 @@ rt_dump(const struct scheduler *ops)
     cap = (uint64_t)cpumask_weight(ops->cpupool->res_valid) *
           RTDS_UTIL_SCALE * RTDS_UTIL_CAP_PCT / 100;
 
+    printk("Admission control: %s\n",
+            prv->admission_control_enabled ? "enabled" : "disabled");
+
     if ( cap )
         printk("Utilization: %llu%% of capacity\n",
                (unsigned long long)(prv->utilization * 100 / cap));
@@ -694,8 +699,8 @@ rt_utilization_cap(const struct domain *d)
 /*
  * Replaces a unit's reservation and updates prv->utilization
  * to match. Growth that would push utilization over the
- * cpupool's cap is refused. Removing a unit or shrinking
- * a unit's reservation always succeed.
+ * cpupool's cap is refused if admission control is enabled.
+ * Removing a unit or shrinking a unit's reservation always succeed.
  */
 static int
 rt_admission_test(struct rt_private *prv, const struct domain *d,
@@ -706,7 +711,8 @@ rt_admission_test(struct rt_private *prv, const struct domain *d,
     uint64_t new_util = rt_unit_utilization(new_period, new_budget);
     uint64_t total    = prv->utilization - old_util + new_util;
 
-    if ( new_util > old_util && total > rt_utilization_cap(d) )
+    if ( prv->admission_control_enabled &&
+         new_util > old_util && total > rt_utilization_cap(d) )
         return -EINVAL;
 
     prv->utilization = total;
@@ -773,6 +779,7 @@ rt_init(struct scheduler *ops)
     INIT_LIST_HEAD(&prv->runq);
     INIT_LIST_HEAD(&prv->depletedq);
     INIT_LIST_HEAD(&prv->replq);
+    prv->admission_control_enabled = true;
 
     ops->sched_data = prv;
     rc = 0;
@@ -1565,8 +1572,14 @@ rt_dom_cntl(
         new_total = prv->utilization - dom_old_util +
                     (uint64_t)nr_units * new_util;
 
-        if ( new_total > prv->utilization && new_total > rt_utilization_cap(d) )
+        if ( prv->admission_control_enabled &&
+             new_total > prv->utilization && new_total > rt_utilization_cap(d) )
         {
+            printk(XENLOG_WARNING
+                   "RTDS: ADMISSION CONTROL: refusing d%d,"
+                   " would exceed utilization capacity of the cpupool\n",
+                   d->domain_id);
+
             rc = -EINVAL;
             spin_unlock_irqrestore(&prv->lock, flags);
             break;
@@ -1632,6 +1645,11 @@ rt_dom_cntl(
                                         period, budget);
                 if ( rc )
                 {
+                    printk(XENLOG_WARNING
+                           "RTDS: ADMISSION CONTROL: refusing vcpu %u of d%d,"
+                           " would exceed utilization capacity of the cpupool\n",
+                           local_sched.vcpuid, d->domain_id);
+
                     spin_unlock_irqrestore(&prv->lock, flags);
                     break;
                 }
@@ -1691,6 +1709,33 @@ rt_dom_cntl(
     return rc;
 }
 
+#ifdef CONFIG_SYSCTL
+static int cf_check
+rt_sys_cntl(const struct scheduler *ops,
+             struct xen_sysctl_scheduler_op *sc)
+{
+    struct xen_sysctl_rtds_schedule *params = &sc->u.sched_rtds;
+    struct rt_private *prv = rt_priv(ops);
+    unsigned long flags;
+
+    switch ( sc->cmd )
+    {
+    case XEN_SYSCTL_SCHEDOP_putinfo:
+        spin_lock_irqsave(&prv->lock, flags);
+        prv->admission_control_enabled = params->admission_control_enabled;
+        spin_unlock_irqrestore(&prv->lock, flags);
+        break;
+    case XEN_SYSCTL_SCHEDOP_getinfo:
+        spin_lock_irqsave(&prv->lock, flags);
+        params->admission_control_enabled = prv->admission_control_enabled;
+        spin_unlock_irqrestore(&prv->lock, flags);
+        break;
+    }
+
+    return 0;
+}
+#endif
+
 /*
  * The replenishment timer handler picks units
  * from the replq and does the actual replenishment.
@@ -1791,6 +1836,9 @@ static const struct sched_ops sched_rtds_def = {
     .remove_unit    = rt_unit_remove,
 
     .adjust         = rt_dom_cntl,
+#ifdef CONFIG_SYSCTL
+    .adjust_global  = rt_sys_cntl,
+#endif
 
     .pick_resource  = rt_res_pick,
     .do_schedule    = rt_schedule,
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index c7cd9b4eb0..f1bf3293e3 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -814,6 +814,10 @@ struct xen_sysctl_credit2_schedule {
     uint32_t ratelimit_us;
 };
 
+struct xen_sysctl_rtds_schedule {
+    bool admission_control_enabled;
+};
+
 /* XEN_SYSCTL_scheduler_op */
 /* Set or get info? */
 #define XEN_SYSCTL_SCHEDOP_putinfo 0
@@ -828,6 +832,7 @@ struct xen_sysctl_scheduler_op {
         } sched_arinc653;
         struct xen_sysctl_credit_schedule sched_credit;
         struct xen_sysctl_credit2_schedule sched_credit2;
+        struct xen_sysctl_rtds_schedule sched_rtds;
     } u;
 };
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5] tools: expose admission control toggle via xl sched-rtds
  2026-08-26  4:57 [PATCH 0/5] xen/sched: rtds: add per-cpupool admission control Furkan Caliskan
                   ` (3 preceding siblings ...)
  2026-08-26  4:57 ` [PATCH 4/5] xen/sched: rtds: make admission control cpupool-wide toggleable Furkan Caliskan
@ 2026-08-26  4:57 ` Furkan Caliskan
  4 siblings, 0 replies; 7+ messages in thread
From: Furkan Caliskan @ 2026-08-26  4:57 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, jbeulich, andrew.cooper3, roger, dfaggioli,
	anthony.perard, julien, sstabellini, gwd, enr0n, michal.orzel,
	Furkan Caliskan

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 <frn1furkan10@gmail.com>
---
 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                |   4 ++
 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                  | 103 +++++++++++++++++++++++++--
 10 files changed, 254 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<EXAMPLE>
@@ -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..ff993c38b7 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -2797,6 +2797,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 <Domain> [-v[=VCPUID/all]] [-p[=PERIOD]] [-b[=BUDGET]] [-e[=Extratime]]]",
+      "[-d <Domain> [-v[=VCPUID/all]] [-p[=PERIOD]] [-b[=BUDGET]] [-e[=Extratime]]]\n"
+      "                [-c <Cpupool> -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..7257d1854b 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,49 @@ 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 */
+            if (sched_rtds_params_get(poolid, &scparam)) {
+                r = EXIT_FAILURE;
+                goto out;
+            }
+
+            scparam.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 */
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 4/5] xen/sched: rtds: make admission control cpupool-wide toggleable
  2026-08-26  4:57 ` [PATCH 4/5] xen/sched: rtds: make admission control cpupool-wide toggleable Furkan Caliskan
@ 2026-08-26  6:14   ` Jan Beulich
  0 siblings, 0 replies; 7+ messages in thread
From: Jan Beulich @ 2026-08-26  6:14 UTC (permalink / raw)
  To: Furkan Caliskan
  Cc: jgross, andrew.cooper3, roger, dfaggioli, anthony.perard, julien,
	sstabellini, gwd, enr0n, michal.orzel, xen-devel

On 26.08.2026 06:57, Furkan Caliskan wrote:
> @@ -1691,6 +1709,33 @@ rt_dom_cntl(
>      return rc;
>  }
>  
> +#ifdef CONFIG_SYSCTL
> +static int cf_check
> +rt_sys_cntl(const struct scheduler *ops,
> +             struct xen_sysctl_scheduler_op *sc)
> +{
> +    struct xen_sysctl_rtds_schedule *params = &sc->u.sched_rtds;
> +    struct rt_private *prv = rt_priv(ops);
> +    unsigned long flags;
> +
> +    switch ( sc->cmd )
> +    {
> +    case XEN_SYSCTL_SCHEDOP_putinfo:
> +        spin_lock_irqsave(&prv->lock, flags);
> +        prv->admission_control_enabled = params->admission_control_enabled;
> +        spin_unlock_irqrestore(&prv->lock, flags);
> +        break;
> +    case XEN_SYSCTL_SCHEDOP_getinfo:
> +        spin_lock_irqsave(&prv->lock, flags);
> +        params->admission_control_enabled = prv->admission_control_enabled;
> +        spin_unlock_irqrestore(&prv->lock, flags);
> +        break;
> +    }

Blank line please between non-fall-through case blocks.

> --- a/xen/include/public/sysctl.h
> +++ b/xen/include/public/sysctl.h
> @@ -814,6 +814,10 @@ struct xen_sysctl_credit2_schedule {
>      uint32_t ratelimit_us;
>  };
>  
> +struct xen_sysctl_rtds_schedule {
> +    bool admission_control_enabled;
> +};

In the public headers only fixed-width types may be used. The width of
bool is ABI-dependent (no matter that it's exceedingly unlikely to ever
be other than the same size as char).

Jan


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-08-26  6:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-26  4:57 [PATCH 0/5] xen/sched: rtds: add per-cpupool admission control Furkan Caliskan
2026-08-26  4:57 ` [PATCH 1/5] xen/sched: rtds: add global-EDF utilization " Furkan Caliskan
2026-08-26  4:57 ` [PATCH 2/5] xen/sched: rtds: enforce admission control in xl sched-rtds Furkan Caliskan
2026-08-26  4:57 ` [PATCH 3/5] xen/sched: rtds: report utilization and cap via debug key Furkan Caliskan
2026-08-26  4:57 ` [PATCH 4/5] xen/sched: rtds: make admission control cpupool-wide toggleable Furkan Caliskan
2026-08-26  6:14   ` Jan Beulich
2026-08-26  4:57 ` [PATCH 5/5] tools: expose admission control toggle via xl sched-rtds Furkan Caliskan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.