[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 |