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