[PATCH 4/5] xen/sched: rtds: make admission control cpupool-wide toggleable

Furkan Caliskan <[email protected]>
Newsgroups gmane.comp.emulators.xen.devel
Message-ID <[email protected]>
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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.