[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 for Xen 4.6 1/4] xen: enabling XL to set per-VCPU parameters of a domain for RTDS scheduler



Add two hypercalls(XEN_DOMCTL_SCHEDOP_getvcpuinfo/putvcpuinfo) to get/set a 
domain's
per-VCPU parameters. Hypercalls are handled by newly added hook (.adjust_vcpu) 
in the
scheduler interface.

Add a new data structure (struct xen_domctl_scheduler_vcpu_op) for transferring 
data
between tool and hypervisor.

Signed-off-by: Chong Li <chong.li@xxxxxxxxx>
Signed-off-by: Meng Xu <mengxu@xxxxxxxxxxxxx>
Signed-off-by: Sisu Xi <xisisu@xxxxxxxxx>
---
 xen/common/domctl.c         |  5 ++++
 xen/common/sched_rt.c       | 71 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/schedule.c       | 24 +++++++++++++++
 xen/include/public/domctl.h | 29 ++++++++++++++++++
 xen/include/xen/sched-if.h  |  2 ++
 xen/include/xen/sched.h     |  1 +
 6 files changed, 131 insertions(+), 1 deletion(-)

diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 28aea55..8143c44 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -841,6 +841,11 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
         copyback = 1;
         break;
 
+    case XEN_DOMCTL_scheduler_vcpu_op:
+        ret = sched_adjust_vcpu(d, &op->u.scheduler_vcpu_op);
+        copyback = 1;
+        break;
+
     case XEN_DOMCTL_getdomaininfo:
     {
         domid_t dom = op->domain;
diff --git a/xen/common/sched_rt.c b/xen/common/sched_rt.c
index 7c39a9e..524ea8e 100644
--- a/xen/common/sched_rt.c
+++ b/xen/common/sched_rt.c
@@ -1071,7 +1071,7 @@ out:
 }
 
 /*
- * set/get each vcpu info of each domain
+ * set/get per-domain params of a domain
  */
 static int
 rt_dom_cntl(
@@ -1115,6 +1115,74 @@ rt_dom_cntl(
     return rc;
 }
 
+/*
+ * set/get per-vcpu params of a domain
+ */
+static int
+rt_vcpu_cntl(
+    const struct scheduler *ops,
+    struct domain *d,
+    struct xen_domctl_scheduler_vcpu_op *op)
+{
+    struct rt_private *prv = rt_priv(ops);
+    struct rt_dom * const sdom = rt_dom(d);
+    struct rt_vcpu *svc;
+    struct list_head *iter;
+    unsigned long flags;
+    int rc = 0;
+    xen_domctl_sched_rtds_params_t local_sched;
+    unsigned int vcpuid;
+    unsigned int i;
+
+    switch ( op->cmd )
+    {
+    case XEN_DOMCTL_SCHEDOP_getvcpuinfo:
+        spin_lock_irqsave(&prv->lock, flags);
+        list_for_each( iter, &sdom->vcpu )
+        {
+            svc = list_entry(iter, struct rt_vcpu, sdom_elem);
+            vcpuid = svc->vcpu->vcpu_id;
+
+            local_sched.budget = svc->budget / MICROSECS(1);
+            local_sched.period = svc->period / MICROSECS(1);
+            if ( copy_to_guest_offset(op->u.rtds.vcpus, vcpuid,
+                    &local_sched, 1) )
+            {
+                spin_unlock_irqrestore(&prv->lock, flags);
+                return  -EFAULT;
+            }
+            hypercall_preempt_check();
+        }
+        spin_unlock_irqrestore(&prv->lock, flags);
+        break;
+    case XEN_DOMCTL_SCHEDOP_putvcpuinfo:
+        spin_lock_irqsave(&prv->lock, flags);
+        for( i = 0; i < op->u.rtds.nr_vcpus; i++ )
+        {
+            if ( copy_from_guest_offset(&local_sched,
+                    op->u.rtds.vcpus, i, 1) )
+            {
+                spin_unlock_irqrestore(&prv->lock, flags);
+                return -EFAULT;
+            }
+            if ( local_sched.period <= 0 || local_sched.budget <= 0 )
+            {
+                spin_unlock_irqrestore(&prv->lock, flags);
+                return -EINVAL;
+            }
+            svc = rt_vcpu(d->vcpu[local_sched.vcpuid]);
+            svc->period = MICROSECS(local_sched.period);
+            svc->budget = MICROSECS(local_sched.budget);
+            hypercall_preempt_check();
+        }
+        spin_unlock_irqrestore(&prv->lock, flags);
+        break;
+    }
+
+    return rc;
+}
+
+
 static struct rt_private _rt_priv;
 
 const struct scheduler sched_rtds_def = {
@@ -1139,6 +1207,7 @@ const struct scheduler sched_rtds_def = {
     .remove_vcpu    = rt_vcpu_remove,
 
     .adjust         = rt_dom_cntl,
+    .adjust_vcpu    = rt_vcpu_cntl,
 
     .pick_cpu       = rt_cpu_pick,
     .do_schedule    = rt_schedule,
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index f5a2e55..64b3c11 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1104,6 +1104,30 @@ long sched_adjust(struct domain *d, struct 
xen_domctl_scheduler_op *op)
     return ret;
 }
 
+/* Adjust scheduling parameter for the vcpus of a given domain. */
+long sched_adjust_vcpu(
+    struct domain *d,
+    struct xen_domctl_scheduler_vcpu_op *op)
+{
+    long ret;
+
+    ret = xsm_domctl_scheduler_op(XSM_HOOK, d, op->cmd);
+    if ( ret )
+        return ret;
+
+    if ( (op->sched_id != DOM2OP(d)->sched_id) ||
+         ((op->cmd != XEN_DOMCTL_SCHEDOP_putvcpuinfo) &&
+          (op->cmd != XEN_DOMCTL_SCHEDOP_getvcpuinfo)) )
+        return -EINVAL;
+
+    /* NB: the pluggable scheduler code needs to take care
+     * of locking by itself. */
+    if ( (ret = SCHED_OP(DOM2OP(d), adjust_vcpu, d, op)) == 0 )
+        TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
+
+    return ret;
+}
+
 long sched_adjust_global(struct xen_sysctl_scheduler_op *op)
 {
     struct cpupool *pool;
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 10b51ef..13a88a3 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -342,6 +342,15 @@ struct xen_domctl_max_vcpus {
 typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
 
+struct xen_domctl_sched_rtds_params {
+    /* vcpus' info */
+    uint32_t period;
+    uint32_t budget;
+    uint16_t vcpuid;
+    uint16_t padding[3];
+};
+typedef struct xen_domctl_sched_rtds_params xen_domctl_sched_rtds_params_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_sched_rtds_params_t);
 
 /* XEN_DOMCTL_scheduler_op */
 /* Scheduler types. */
@@ -354,6 +363,23 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
 /* Set or get info? */
 #define XEN_DOMCTL_SCHEDOP_putinfo 0
 #define XEN_DOMCTL_SCHEDOP_getinfo 1
+#define XEN_DOMCTL_SCHEDOP_getvcpuinfo 2
+#define XEN_DOMCTL_SCHEDOP_putvcpuinfo 3
+
+struct xen_domctl_scheduler_vcpu_op {
+    uint32_t sched_id;  /* XEN_SCHEDULER_* */
+    uint32_t cmd;       /* XEN_DOMCTL_SCHEDOP_{get, put}vcpuinfo */
+    union {
+        struct xen_domctl_sched_rtds_vcpus {
+            XEN_GUEST_HANDLE_64(xen_domctl_sched_rtds_params_t) vcpus;
+            uint16_t nr_vcpus;
+            uint16_t padding[3];
+        } rtds;
+    } u;
+};
+typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_vcpu_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_scheduler_vcpu_op_t);
+
 struct xen_domctl_scheduler_op {
     uint32_t sched_id;  /* XEN_SCHEDULER_* */
     uint32_t cmd;       /* XEN_DOMCTL_SCHEDOP_* */
@@ -1118,6 +1144,8 @@ struct xen_domctl {
 #define XEN_DOMCTL_setvnumainfo                  74
 #define XEN_DOMCTL_psr_cmt_op                    75
 #define XEN_DOMCTL_monitor_op                    77
+/* FIXME: put scheduler_vcpu_op here or after scheduler_op */
+#define XEN_DOMCTL_scheduler_vcpu_op                  78
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -1139,6 +1167,7 @@ struct xen_domctl {
         struct xen_domctl_getvcpuinfo       getvcpuinfo;
         struct xen_domctl_max_vcpus         max_vcpus;
         struct xen_domctl_scheduler_op      scheduler_op;
+        struct xen_domctl_scheduler_vcpu_op scheduler_vcpu_op;
         struct xen_domctl_setdomainhandle   setdomainhandle;
         struct xen_domctl_setdebugging      setdebugging;
         struct xen_domctl_irq_permission    irq_permission;
diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h
index 7cc25c6..8106310 100644
--- a/xen/include/xen/sched-if.h
+++ b/xen/include/xen/sched-if.h
@@ -156,6 +156,8 @@ struct scheduler {
                                     unsigned int);
     int          (*adjust)         (const struct scheduler *, struct domain *,
                                     struct xen_domctl_scheduler_op *);
+    int          (*adjust_vcpu)         (const struct scheduler *, struct 
domain *,
+                                    struct xen_domctl_scheduler_vcpu_op *);
     int          (*adjust_global)  (const struct scheduler *,
                                     struct xen_sysctl_scheduler_op *);
     void         (*dump_settings)  (const struct scheduler *);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 80c6f62..0e72bb6 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -643,6 +643,7 @@ int  sched_init_domain(struct domain *d);
 void sched_destroy_domain(struct domain *d);
 int sched_move_domain(struct domain *d, struct cpupool *c);
 long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *);
+long sched_adjust_vcpu(struct domain *, struct xen_domctl_scheduler_vcpu_op *);
 long sched_adjust_global(struct xen_sysctl_scheduler_op *);
 int  sched_id(void);
 void sched_tick_suspend(void);
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.