From: Chong Li <lichong659@gmail.com>
To: xen-devel@lists.xen.org
Cc: Chong Li <chong.li@wustl.edu>, Sisu Xi <xisisu@gmail.com>,
george.dunlap@eu.citrix.com, dario.faggioli@citrix.com,
Meng Xu <mengxu@cis.upenn.edu>,
jbeulich@suse.com, lichong659@gmail.com, dgolomb@seas.upenn.edu
Subject: [PATCH v8 for Xen 4.7 1/4] xen: enable per-VCPU parameter for RTDS
Date: Fri, 18 Mar 2016 16:26:22 -0500 [thread overview]
Message-ID: <1458336385-2606-2-git-send-email-lichong659@gmail.com> (raw)
In-Reply-To: <1458336385-2606-1-git-send-email-lichong659@gmail.com>
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@wustl.edu>
Signed-off-by: Meng Xu <mengxu@cis.upenn.edu>
Signed-off-by: Sisu Xi <xisisu@gmail.com>
---
Changes on PATCH v7:
1) A bug in case XEN_DOMCTL_SCHEDOP_getinfo (in Xen 4.6) is fixed:
The default PERIOD or BUDGET should be divided by MICROSECS(1),
before returned to upper caller.
2) In the *cntl() functions in sched_credit.c and sched_credit2.c, remove
two unhandled cases in "switch".
Changes on PATCH v6:
1) Add explain for nr_vcpus in struct xen_domctl_scheduler_op, because it is used
in both IN and OUT ways.
2) Remove the check and warning for vcpu settings with low budget or budget. Making this
feature "per-domain" or "per-operation" is one of the future work.
3) In the *cntl() functions in sched_credit.c and sched_credit2.c, change the "if-else"
structure to "switch" structure.
4) In rt_dom_cntl(), use copy_to_guest* instead of __copy_to_guest*, because the latter one
requires lock protection.
Changes on PATCH v5:
1) When processing XEN_DOMCTL_SCHEDOP_get/putvcpuinfo, we do
preemption check in a similar way to XEN_SYSCTL_pcitopoinfo
Changes on PATCH v4:
1) Add uint32_t vcpu_index to struct xen_domctl_scheduler_op.
When processing XEN_DOMCTL_SCHEDOP_get/putvcpuinfo, we call
hypercall_preemption_check in case the current hypercall lasts
too long. If we decide to preempt the current hypercall, we record
the index of the most-recent finished vcpu into the vcpu_index of
struct xen_domctl_scheduler_op. So when we resume the hypercall after
preemption, we start processing from the posion specified by vcpu_index,
and don't need to repeat the work that has already been done in the
hypercall before the preemption.
(This design is based on the do_grant_table_op() in grant_table.c)
2) Coding style changes
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
Changes on PATCH v2:
1) Change struct xen_domctl_scheduler_op, for transferring per-vcpu parameters
between libxc and hypervisor.
2) Handler of XEN_DOMCTL_SCHEDOP_getinfo now just returns the default budget and
period values of RTDS scheduler.
3) Handler of XEN_DOMCTL_SCHEDOP_getvcpuinfo now can return a random subset of
the parameters of the VCPUs of a specific domain
CC: <dario.faggioli@citrix.com>
CC: <george.dunlap@eu.citrix.com>
CC: <dgolomb@seas.upenn.edu>
CC: <mengxu@cis.upenn.edu>
CC: <jbeulich@suse.com>
CC: <lichong659@gmail.com>
---
xen/common/sched_credit.c | 14 +++----
xen/common/sched_credit2.c | 13 ++++---
xen/common/sched_rt.c | 93 ++++++++++++++++++++++++++++++++++++++-------
xen/common/schedule.c | 15 ++++++--
xen/include/public/domctl.h | 64 +++++++++++++++++++++++++------
5 files changed, 157 insertions(+), 42 deletions(-)
diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index 0dce790..b504702 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -1054,15 +1054,13 @@ csched_dom_cntl(
* lock. Runq lock not needed anywhere in here. */
spin_lock_irqsave(&prv->lock, flags);
- if ( op->cmd == XEN_DOMCTL_SCHEDOP_getinfo )
+ switch ( op->cmd )
{
+ case XEN_DOMCTL_SCHEDOP_getinfo:
op->u.credit.weight = sdom->weight;
op->u.credit.cap = sdom->cap;
- }
- else
- {
- ASSERT(op->cmd == XEN_DOMCTL_SCHEDOP_putinfo);
-
+ break;
+ case XEN_DOMCTL_SCHEDOP_putinfo:
if ( op->u.credit.weight != 0 )
{
if ( !list_empty(&sdom->active_sdom_elem) )
@@ -1075,7 +1073,9 @@ csched_dom_cntl(
if ( op->u.credit.cap != (uint16_t)~0U )
sdom->cap = op->u.credit.cap;
-
+ break;
+ default:
+ return -EINVAL;
}
spin_unlock_irqrestore(&prv->lock, flags);
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 3c49ffa..c2dcf0f 100644
--- a/xen/common/sched_credit2.c
+++ b/xen/common/sched_credit2.c
@@ -1421,14 +1421,12 @@ csched2_dom_cntl(
* runq lock to update csvcs. */
spin_lock_irqsave(&prv->lock, flags);
- if ( op->cmd == XEN_DOMCTL_SCHEDOP_getinfo )
+ switch ( op->cmd )
{
+ case XEN_DOMCTL_SCHEDOP_getinfo:
op->u.credit2.weight = sdom->weight;
- }
- else
- {
- ASSERT(op->cmd == XEN_DOMCTL_SCHEDOP_putinfo);
-
+ break;
+ case XEN_DOMCTL_SCHEDOP_putinfo:
if ( op->u.credit2.weight != 0 )
{
struct vcpu *v;
@@ -1457,6 +1455,9 @@ csched2_dom_cntl(
vcpu_schedule_unlock(lock, svc->vcpu);
}
}
+ break;
+ default:
+ return -EINVAL;
}
spin_unlock_irqrestore(&prv->lock, flags);
diff --git a/xen/common/sched_rt.c b/xen/common/sched_rt.c
index 3f1d047..b640e59 100644
--- a/xen/common/sched_rt.c
+++ b/xen/common/sched_rt.c
@@ -86,6 +86,22 @@
#define RTDS_DEFAULT_PERIOD (MICROSECS(10000))
#define RTDS_DEFAULT_BUDGET (MICROSECS(4000))
+/*
+ * Max period: max delta of time type, because period is added to the time
+ * a vcpu activates, so this must not overflow.
+ * Min period: 10 us, considering the scheduling overhead (when period is
+ * too low, scheduling is invoked too frequently, causing high overhead).
+ */
+#define RTDS_MAX_PERIOD (STIME_DELTA_MAX)
+#define RTDS_MIN_PERIOD (MICROSECS(10))
+
+/*
+ * Min budget: 10 us, considering the scheduling overhead (when budget is
+ * consumed too fast, scheduling is invoked too frequently, causing
+ * high overhead).
+ */
+#define RTDS_MIN_BUDGET (MICROSECS(10))
+
#define UPDATE_LIMIT_SHIFT 10
#define MAX_SCHEDULE (MILLISECS(1))
/*
@@ -1129,24 +1145,16 @@ rt_dom_cntl(
struct vcpu *v;
unsigned long flags;
int rc = 0;
+ xen_domctl_schedparam_vcpu_t local_sched;
+ s_time_t period, budget;
+ uint32_t index = 0;
switch ( op->cmd )
{
case XEN_DOMCTL_SCHEDOP_getinfo:
- if ( d->max_vcpus > 0 )
- {
- spin_lock_irqsave(&prv->lock, flags);
- svc = rt_vcpu(d->vcpu[0]);
- op->u.rtds.period = svc->period / MICROSECS(1);
- op->u.rtds.budget = svc->budget / MICROSECS(1);
- spin_unlock_irqrestore(&prv->lock, flags);
- }
- else
- {
- /* If we don't have vcpus yet, let's just return the defaults. */
- op->u.rtds.period = RTDS_DEFAULT_PERIOD;
- op->u.rtds.budget = RTDS_DEFAULT_BUDGET;
- }
+ /* Return the default parameters. */
+ op->u.rtds.period = RTDS_DEFAULT_PERIOD / MICROSECS(1);
+ op->u.rtds.budget = RTDS_DEFAULT_BUDGET / MICROSECS(1);
break;
case XEN_DOMCTL_SCHEDOP_putinfo:
if ( op->u.rtds.period == 0 || op->u.rtds.budget == 0 )
@@ -1163,6 +1171,63 @@ rt_dom_cntl(
}
spin_unlock_irqrestore(&prv->lock, flags);
break;
+ case XEN_DOMCTL_SCHEDOP_getvcpuinfo:
+ case XEN_DOMCTL_SCHEDOP_putvcpuinfo:
+ while ( index < op->u.v.nr_vcpus )
+ {
+ 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;
+ }
+
+ if ( op->cmd == XEN_DOMCTL_SCHEDOP_getvcpuinfo )
+ {
+ spin_lock_irqsave(&prv->lock, flags);
+ svc = rt_vcpu(d->vcpu[local_sched.vcpuid]);
+ local_sched.u.rtds.budget = svc->budget / MICROSECS(1);
+ local_sched.u.rtds.period = svc->period / MICROSECS(1);
+ spin_unlock_irqrestore(&prv->lock, flags);
+
+ if ( copy_to_guest_offset(op->u.v.vcpus, index,
+ &local_sched, 1) )
+ {
+ rc = -EFAULT;
+ break;
+ }
+ }
+ else
+ {
+ period = MICROSECS(local_sched.u.rtds.period);
+ budget = MICROSECS(local_sched.u.rtds.budget);
+ if ( period > RTDS_MAX_PERIOD || budget < RTDS_MIN_BUDGET ||
+ budget > period || period < RTDS_MIN_PERIOD )
+ {
+ rc = -EINVAL;
+ break;
+ }
+
+ spin_lock_irqsave(&prv->lock, flags);
+ svc = rt_vcpu(d->vcpu[local_sched.vcpuid]);
+ svc->period = period;
+ svc->budget = budget;
+ spin_unlock_irqrestore(&prv->lock, flags);
+ }
+ /* Process a most 64 vCPUs without checking for preemptions. */
+ if ( (++index > 63) && hypercall_preempt_check() )
+ break;
+ }
+ if ( !rc )
+ /* notify upper caller how many vcpus have been processed. */
+ op->u.v.nr_vcpus = index;
+ break;
}
return rc;
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index c195129..cd25e08 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1148,11 +1148,20 @@ 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;
+ switch ( op->cmd )
+ {
+ case XEN_DOMCTL_SCHEDOP_putinfo:
+ case XEN_DOMCTL_SCHEDOP_getinfo:
+ case XEN_DOMCTL_SCHEDOP_putvcpuinfo:
+ case XEN_DOMCTL_SCHEDOP_getvcpuinfo:
+ break;
+ default:
+ return -EINVAL;
+ }
+
/* NB: the pluggable scheduler code needs to take care
* of locking by itself. */
if ( (ret = SCHED_OP(DOM2OP(d), adjust, d, op)) == 0 )
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 7a56b3f..24675f5 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -338,24 +338,64 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
#define XEN_SCHEDULER_ARINC653 7
#define XEN_SCHEDULER_RTDS 8
-/* Set or get info? */
+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;
+ } u;
+ uint32_t vcpuid;
+ uint16_t padding[2];
+} xen_domctl_schedparam_vcpu_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_schedparam_vcpu_t);
+
+/*
+ * Set or get info?
+ * For schedulers supporting per-vcpu settings (e.g., RTDS):
+ * XEN_DOMCTL_SCHEDOP_putinfo sets params for all vcpus;
+ * XEN_DOMCTL_SCHEDOP_getinfo gets default params;
+ * XEN_DOMCTL_SCHEDOP_put(get)vcpuinfo sets (gets) params of vcpus;
+ *
+ * For schedulers not supporting per-vcpu settings:
+ * XEN_DOMCTL_SCHEDOP_putinfo sets params for all vcpus;
+ * XEN_DOMCTL_SCHEDOP_getinfo gets domain-wise params;
+ * XEN_DOMCTL_SCHEDOP_put(get)vcpuinfo returns error;
+ */
#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_* */
+ /* IN/OUT */
union {
- 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_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;
+ /*
+ * IN: Number of elements in vcpus array.
+ * OUT: Number of processed elements of vcpus array.
+ */
+ uint32_t nr_vcpus;
+ uint32_t padding;
+ } v;
} u;
};
typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2016-03-18 21:26 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-18 21:26 [PATCH v8 for Xen 4.7 0/4] Enable per-VCPU parameter for RTDS Chong Li
2016-03-18 21:26 ` Chong Li [this message]
2016-03-21 13:35 ` [PATCH v8 for Xen 4.7 1/4] xen: enable " Jan Beulich
2016-03-21 15:18 ` Chong Li
2016-03-21 15:39 ` George Dunlap
2016-03-21 15:49 ` Jan Beulich
2016-03-21 16:03 ` Chong Li
2016-03-21 16:25 ` Jan Beulich
2016-03-25 18:07 ` Chong Li
2016-03-29 10:58 ` Dario Faggioli
2016-03-29 16:59 ` Dario Faggioli
2016-03-29 17:13 ` Konrad Rzeszutek Wilk
2016-03-29 17:36 ` Dario Faggioli
2016-03-18 21:26 ` [PATCH v8 for Xen 4.7 2/4] libxc: " Chong Li
2016-03-29 17:08 ` Dario Faggioli
2016-03-31 16:59 ` Wei Liu
2016-03-18 21:26 ` [PATCH v8 for Xen 4.7 3/4] libxl: " Chong Li
2016-03-30 17:04 ` Dario Faggioli
2016-03-31 16:59 ` Wei Liu
2016-03-18 21:26 ` [PATCH v8 for Xen 4.7 4/4] xl: " Chong Li
2016-03-31 17:00 ` Wei Liu
2016-03-31 17:22 ` Dario Faggioli
2016-03-31 17:17 ` Dario Faggioli
2016-03-31 20:16 ` Wei Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1458336385-2606-2-git-send-email-lichong659@gmail.com \
--to=lichong659@gmail.com \
--cc=chong.li@wustl.edu \
--cc=dario.faggioli@citrix.com \
--cc=dgolomb@seas.upenn.edu \
--cc=george.dunlap@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=mengxu@cis.upenn.edu \
--cc=xen-devel@lists.xen.org \
--cc=xisisu@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.