|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 for Xen 4.6 1/4] xen: enable per-VCPU parameter settings for RTDS scheduler
Add XEN_DOMCTL_SCHEDOP_getvcpuinfo and _putvcpuinfo hypercalls
to independently get and set the scheduling parameters of each
vCPU of a domain
Signed-off-by: Chong Li <chong.li@xxxxxxxxx>
Signed-off-by: Meng Xu <mengxu@xxxxxxxxxxxxx>
Signed-off-by: Sisu Xi <xisisu@xxxxxxxxx>
---
Changes on PATCH v3:
1) Remove struct xen_domctl_schedparam_t.
2) Change struct xen_domctl_scheduler_op.
3) Check if period/budget is within a validated range
CC: <dario.faggioli@xxxxxxxxxx>
CC: <george.dunlap@xxxxxxxxxxxxx>
CC: <dgolomb@xxxxxxxxxxxxxx>
CC: <mengxu@xxxxxxxxxxxxx>
CC: <jbeulich@xxxxxxxx>
CC: <lichong659@xxxxxxxxx>
---
xen/common/domctl.c | 3 ++
xen/common/sched_rt.c | 100 +++++++++++++++++++++++++++++++++++++++++---
xen/common/schedule.c | 18 ++++++--
xen/include/public/domctl.h | 61 +++++++++++++++++++--------
4 files changed, 155 insertions(+), 27 deletions(-)
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 2a2d203..349f68b 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -839,6 +839,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
u_domctl)
case XEN_DOMCTL_scheduler_op:
ret = sched_adjust(d, &op->u.scheduler_op);
+ if ( ret == -ERESTART )
+ ret = hypercall_create_continuation(
+ __HYPERVISOR_domctl, "h", u_domctl);
copyback = 1;
break;
diff --git a/xen/common/sched_rt.c b/xen/common/sched_rt.c
index 4372486..fed9e09 100644
--- a/xen/common/sched_rt.c
+++ b/xen/common/sched_rt.c
@@ -78,7 +78,6 @@
* vcpu_insert, vcpu_remove, context_saved, __runq_insert
*/
-
/*
* Default parameters:
* Period and budget in default is 10 and 4 ms, respectively
@@ -86,6 +85,18 @@
#define RTDS_DEFAULT_PERIOD (MICROSECS(10000))
#define RTDS_DEFAULT_BUDGET (MICROSECS(4000))
+/*
+ * Max period: max delta of time type
+ * Min period: 100 us, considering the scheduling overhead
+ */
+#define RTDS_MAX_PERIOD (STIME_DELTA_MAX)
+#define RTDS_MIN_PERIOD (MICROSECS(100))
+
+/*
+ * Min budget: 100 us
+ */
+#define RTDS_MIN_BUDGET (MICROSECS(100))
+
#define UPDATE_LIMIT_SHIFT 10
#define MAX_SCHEDULE (MILLISECS(1))
/*
@@ -1137,14 +1148,17 @@ rt_dom_cntl(
struct list_head *iter;
unsigned long flags;
int rc = 0;
+ int warn = 0;
+ xen_domctl_schedparam_vcpu_t local_sched;
+ s_time_t period, budget;
+ unsigned int index;
switch ( op->cmd )
{
- case XEN_DOMCTL_SCHEDOP_getinfo:
+ case XEN_DOMCTL_SCHEDOP_getinfo: /* return the default parameters */
spin_lock_irqsave(&prv->lock, flags);
- svc = list_entry(sdom->vcpu.next, struct rt_vcpu, sdom_elem);
- op->u.rtds.period = svc->period / MICROSECS(1); /* transfer to us */
- op->u.rtds.budget = svc->budget / MICROSECS(1);
+ op->u.rtds.period = RTDS_DEFAULT_PERIOD / MICROSECS(1); /* transfer to
us */
+ op->u.rtds.budget = RTDS_DEFAULT_BUDGET / MICROSECS(1);
spin_unlock_irqrestore(&prv->lock, flags);
break;
case XEN_DOMCTL_SCHEDOP_putinfo:
@@ -1162,8 +1176,82 @@ rt_dom_cntl(
}
spin_unlock_irqrestore(&prv->lock, flags);
break;
+ case XEN_DOMCTL_SCHEDOP_getvcpuinfo:
+ spin_lock_irqsave(&prv->lock, flags);
+ for ( index = 0; index < op->u.v.nr_vcpus; index++ )
+ {
+ if ( copy_from_guest_offset(&local_sched,
+ op->u.v.vcpus, index, 1) )
+ {
+ rc = -EFAULT;
+ break;
+ }
+ if ( local_sched.vcpuid >= d->max_vcpus ||
+ d->vcpu[local_sched.vcpuid] == NULL )
+ {
+ rc = -EINVAL;
+ break;
+ }
+ svc = rt_vcpu(d->vcpu[local_sched.vcpuid]);
+
+ local_sched.s.rtds.budget = svc->budget / MICROSECS(1);
+ local_sched.s.rtds.period = svc->period / MICROSECS(1);
+
+ if ( __copy_to_guest_offset(op->u.v.vcpus, index,
+ &local_sched, 1) )
+ {
+ rc = -EFAULT;
+ break;
+ }
+ if( hypercall_preempt_check() )
+ {
+ rc = -ERESTART;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&prv->lock, flags);
+ break;
+ case XEN_DOMCTL_SCHEDOP_putvcpuinfo:
+ spin_lock_irqsave(&prv->lock, flags);
+ for( index = 0; index < op->u.v.nr_vcpus; index++ )
+ {
+ if ( copy_from_guest_offset(&local_sched,
+ op->u.v.vcpus, index, 1) )
+ {
+ rc = -EFAULT;
+ break;
+ }
+ if ( local_sched.vcpuid >= d->max_vcpus ||
+ d->vcpu[local_sched.vcpuid] == NULL )
+ {
+ rc = -EINVAL;
+ break;
+ }
+ svc = rt_vcpu(d->vcpu[local_sched.vcpuid]);
+ period = MICROSECS(local_sched.s.rtds.period);
+ budget = MICROSECS(local_sched.s.rtds.budget);
+ if ( period < MICROSECS(10) || period > RTDS_MAX_PERIOD ||
+ budget < MICROSECS(10) || budget > period )
+ {
+ rc = -EINVAL;
+ break;
+ }
+ if ( period < RTDS_MIN_PERIOD || budget < RTDS_MIN_BUDGET )
+ warn = 1;
+
+ svc->period = period;
+ svc->budget = budget;
+ if( hypercall_preempt_check() )
+ {
+ rc = -ERESTART;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&prv->lock, flags);
+ break;
}
-
+ if ( rc == 0 && warn == 1 ) /* print warning in libxl */
+ rc = 1;
return rc;
}
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index ecf1545..886e1b5 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1052,10 +1052,22 @@ long sched_adjust(struct domain *d, struct
xen_domctl_scheduler_op *op)
if ( ret )
return ret;
- if ( (op->sched_id != DOM2OP(d)->sched_id) ||
- ((op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) &&
- (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo)) )
+ if ( op->sched_id != DOM2OP(d)->sched_id )
return -EINVAL;
+ else
+ switch ( op->cmd )
+ {
+ case XEN_DOMCTL_SCHEDOP_putinfo:
+ break;
+ case XEN_DOMCTL_SCHEDOP_getinfo:
+ break;
+ case XEN_DOMCTL_SCHEDOP_putvcpuinfo:
+ break;
+ case XEN_DOMCTL_SCHEDOP_getvcpuinfo:
+ break;
+ default:
+ return -EINVAL;
+ }
/* NB: the pluggable scheduler code needs to take care
* of locking by itself. */
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index bc45ea5..bfb432f 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -330,31 +330,56 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
#define XEN_SCHEDULER_ARINC653 7
#define XEN_SCHEDULER_RTDS 8
+typedef struct xen_domctl_sched_sedf {
+ uint64_aligned_t period;
+ uint64_aligned_t slice;
+ uint64_aligned_t latency;
+ uint32_t extratime;
+ uint32_t weight;
+} xen_domctl_sched_sedf_t;
+
+typedef struct xen_domctl_sched_credit {
+ uint16_t weight;
+ uint16_t cap;
+} xen_domctl_sched_credit_t;
+
+typedef struct xen_domctl_sched_credit2 {
+ uint16_t weight;
+} xen_domctl_sched_credit2_t;
+
+typedef struct xen_domctl_sched_rtds {
+ uint32_t period;
+ uint32_t budget;
+} xen_domctl_sched_rtds_t;
+
+typedef struct xen_domctl_schedparam_vcpu {
+ union {
+ xen_domctl_sched_credit_t credit;
+ xen_domctl_sched_credit2_t credit2;
+ xen_domctl_sched_rtds_t rtds;
+ } s;
+ uint16_t vcpuid;
+ uint16_t padding;
+} xen_domctl_schedparam_vcpu_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_schedparam_vcpu_t);
+
/* Set or get info? */
#define XEN_DOMCTL_SCHEDOP_putinfo 0
#define XEN_DOMCTL_SCHEDOP_getinfo 1
+#define XEN_DOMCTL_SCHEDOP_putvcpuinfo 2
+#define XEN_DOMCTL_SCHEDOP_getvcpuinfo 3
struct xen_domctl_scheduler_op {
uint32_t sched_id; /* XEN_SCHEDULER_* */
uint32_t cmd; /* XEN_DOMCTL_SCHEDOP_* */
union {
- struct xen_domctl_sched_sedf {
- uint64_aligned_t period;
- uint64_aligned_t slice;
- uint64_aligned_t latency;
- uint32_t extratime;
- uint32_t weight;
- } sedf;
- struct xen_domctl_sched_credit {
- uint16_t weight;
- uint16_t cap;
- } credit;
- struct xen_domctl_sched_credit2 {
- uint16_t weight;
- } credit2;
- struct xen_domctl_sched_rtds {
- uint32_t period;
- uint32_t budget;
- } rtds;
+ xen_domctl_sched_sedf_t sedf;
+ xen_domctl_sched_credit_t credit;
+ xen_domctl_sched_credit2_t credit2;
+ xen_domctl_sched_rtds_t rtds;
+ struct {
+ XEN_GUEST_HANDLE_64(xen_domctl_schedparam_vcpu_t) vcpus;
+ uint16_t nr_vcpus;
+ } v;
} u;
};
typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;
--
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 |