|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |