mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Remove all traces of the obsolete BVT scheduler.
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
ae95fdf65a
commit
db51cd09d3
20 files changed
+7
-1008
No files matched your search
@@ -511,55 +511,6 @@ FIXME: we really need a scheduler expert to write up this section.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<sched-bvt> I<mcuadv> I<warpback> I<warpvalue> I<warpl> I<warpu>
|
||||
|
||||
Performs runtime adjustments to the default parameters for the
|
||||
Borrowed Virtual Time (BVT) scheduler. For full information on the
|
||||
BVT concept, please consult the base paper listed in the B<SEE ALSO>
|
||||
section.
|
||||
|
||||
Set Borrowed Virtual Time (BVT) scheduler parameters. There are five
|
||||
required parameters, which are given in order below.
|
||||
|
||||
FIXME: what units are all the BVT params in?
|
||||
|
||||
B<PARAMETERS>
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<mcuadv>
|
||||
|
||||
The MCU (Minimum Charging Unit) advance determines the proportional
|
||||
share of the CPU that a domain receives. It is set inversely
|
||||
proportionally to a domain's sharing weight.
|
||||
|
||||
=item I<warpback>
|
||||
|
||||
The amount of `virtual time' the domain is allowed to warp backwards.
|
||||
|
||||
=item I<warpvalue>
|
||||
|
||||
Warp value (FIXME: what does this really mean?)
|
||||
|
||||
=item I<warpl>
|
||||
|
||||
The warp limit is the maximum time a domain can run warped for.
|
||||
|
||||
=item I<warpu>
|
||||
|
||||
The unwarp requirement is the minimum time a domain must run unwarped
|
||||
for before it can warp again.
|
||||
|
||||
=back
|
||||
|
||||
=item B<sched-bvt-ctxallow> I<allow>
|
||||
|
||||
Sets the BVT scheduler's context switch allowance.
|
||||
|
||||
The context switch allowance is similar to the ``quantum'' in
|
||||
traditional schedulers. It is the minimum time that a scheduled domain
|
||||
will be allowed to run before being preempted.
|
||||
|
||||
=item B<sched-sedf> I<period> I<slice> I<latency-hint> I<extratime> I<weight>
|
||||
|
||||
Set Simple EDF (Earliest Deadline First) scheduler parameters. This
|
||||
@@ -1126,12 +1077,6 @@ their binary identifiers (ssidrefs) used inside Xen.
|
||||
|
||||
B<xmdomain.cfg>(5), B<xentop>(1)
|
||||
|
||||
BVT scheduling paper: K.J. Duda and D.R. Cheriton. Borrowed Virtual
|
||||
Time (BVT) scheduling: supporting latency-sensitive threads in a
|
||||
general purpose scheduler. In proceedings of the 17th ACM SIGOPS
|
||||
Symposium on Operating Systems principles, volume 33(5) of ACM
|
||||
Operating Systems Review, pages 261-267
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Sean Dague <sean at dague dot net>
|
||||
|
||||
@@ -337,14 +337,6 @@ Python client interface in {\tt xen.xend.XendClient}.
|
||||
{\tt xend\_domain\_pincpu(self, id, cpu)}\\:
|
||||
Pin a domain to a cpu.
|
||||
|
||||
\item {\tt POST /domain/[dom] bvt\_set(mcuadv, warp, warpl, warpu)},\\
|
||||
{\tt xend\_domain\_cpu\_bvt\_set(dom, mcuadv, warp, warpl, warpu)}:\\
|
||||
Set BVT scheduler parameters.
|
||||
|
||||
\item {\tt POST /domain/[dom] atropos\_set(period, slice, latency, xtratime)},\\
|
||||
{\tt xend\_domain\_cpu\_atropos\_set(dom, period, slice, latency, xtratime)}:\\
|
||||
Set atropos scheduler parameters.
|
||||
|
||||
\item {\tt POST /domain/[dom] maxmem\_set(memory)},\\
|
||||
{\tt xend\_domain\_maxmem\_set(dom, memory)}:\\
|
||||
Set domain maximum memory limit.
|
||||
|
||||
@@ -209,8 +209,8 @@ implement timeout values when they block.
|
||||
|
||||
Xen offers a uniform API for CPU schedulers. It is possible to choose
|
||||
from a number of schedulers at boot and it should be easy to add more.
|
||||
The SEDF, BVT, and Credit schedulers are part of the normal Xen
|
||||
distribution. BVT and SEDF will be going away and their use should be
|
||||
The SEDF and Credit schedulers are part of the normal Xen
|
||||
distribution. SEDF will be going away and its use should be
|
||||
avoided once the credit scheduler has stabilized and become the default.
|
||||
The Credit scheduler provides proportional fair shares of the
|
||||
host's CPUs to the running domains. It does this while transparently
|
||||
|
||||
+1
-4
@@ -3179,7 +3179,7 @@ editing \path{grub.conf}.
|
||||
\item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
|
||||
pages (default 0).
|
||||
\item [ sched=xxx ] Select the CPU scheduler Xen should use. The
|
||||
current possibilities are `credit' (default), `sedf', and `bvt'.
|
||||
current possibilities are `credit' (default), and `sedf'.
|
||||
\item [ apic\_verbosity=debug,verbose ] Print more detailed
|
||||
information about local APIC and IOAPIC configuration.
|
||||
\item [ lapic ] Force use of local APIC even when left disabled by
|
||||
@@ -4135,9 +4135,6 @@ as it will forward multicasts received from other machines on the subnet.
|
||||
|
||||
\begin{description}
|
||||
|
||||
\item[BVT] The BVT scheduler is used to give proportional fair shares
|
||||
of the CPU to domains.
|
||||
|
||||
\item[Domain] A domain is the execution context that contains a
|
||||
running {\bf virtual machine}. The relationship between virtual
|
||||
machines and domains on Xen is similar to that between programs and
|
||||
|
||||
@@ -11,7 +11,6 @@ XEN_ROOT = ../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
CTRL_SRCS-y :=
|
||||
CTRL_SRCS-y += xc_bvtsched.c
|
||||
CTRL_SRCS-y += xc_core.c
|
||||
CTRL_SRCS-y += xc_domain.c
|
||||
CTRL_SRCS-y += xc_evtchn.c
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/******************************************************************************
|
||||
* xc_bvtsched.c
|
||||
*
|
||||
* API for manipulating parameters of the Borrowed Virtual Time scheduler.
|
||||
*
|
||||
* Copyright (c) 2003, K A Fraser.
|
||||
*/
|
||||
|
||||
#include "xc_private.h"
|
||||
|
||||
int xc_bvtsched_global_set(int xc_handle,
|
||||
unsigned long ctx_allow)
|
||||
{
|
||||
DECLARE_DOM0_OP;
|
||||
|
||||
op.cmd = DOM0_SCHEDCTL;
|
||||
op.u.schedctl.sched_id = SCHED_BVT;
|
||||
op.u.schedctl.direction = SCHED_INFO_PUT;
|
||||
op.u.schedctl.u.bvt.ctx_allow = ctx_allow;
|
||||
|
||||
return do_dom0_op(xc_handle, &op);
|
||||
}
|
||||
|
||||
int xc_bvtsched_global_get(int xc_handle,
|
||||
unsigned long *ctx_allow)
|
||||
{
|
||||
DECLARE_DOM0_OP;
|
||||
int ret;
|
||||
|
||||
op.cmd = DOM0_SCHEDCTL;
|
||||
op.u.schedctl.sched_id = SCHED_BVT;
|
||||
op.u.schedctl.direction = SCHED_INFO_GET;
|
||||
|
||||
ret = do_dom0_op(xc_handle, &op);
|
||||
|
||||
*ctx_allow = op.u.schedctl.u.bvt.ctx_allow;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xc_bvtsched_domain_set(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t mcuadv,
|
||||
int warpback,
|
||||
int32_t warpvalue,
|
||||
long long warpl,
|
||||
long long warpu)
|
||||
{
|
||||
DECLARE_DOM0_OP;
|
||||
struct bvt_adjdom *bvtadj = &op.u.adjustdom.u.bvt;
|
||||
|
||||
op.cmd = DOM0_ADJUSTDOM;
|
||||
op.u.adjustdom.domain = (domid_t)domid;
|
||||
op.u.adjustdom.sched_id = SCHED_BVT;
|
||||
op.u.adjustdom.direction = SCHED_INFO_PUT;
|
||||
|
||||
bvtadj->mcu_adv = mcuadv;
|
||||
bvtadj->warpback = warpback;
|
||||
bvtadj->warpvalue = warpvalue;
|
||||
bvtadj->warpl = warpl;
|
||||
bvtadj->warpu = warpu;
|
||||
return do_dom0_op(xc_handle, &op);
|
||||
}
|
||||
|
||||
|
||||
int xc_bvtsched_domain_get(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t *mcuadv,
|
||||
int *warpback,
|
||||
int32_t *warpvalue,
|
||||
long long *warpl,
|
||||
long long *warpu)
|
||||
{
|
||||
|
||||
DECLARE_DOM0_OP;
|
||||
int ret;
|
||||
struct bvt_adjdom *adjptr = &op.u.adjustdom.u.bvt;
|
||||
|
||||
op.cmd = DOM0_ADJUSTDOM;
|
||||
op.u.adjustdom.domain = (domid_t)domid;
|
||||
op.u.adjustdom.sched_id = SCHED_BVT;
|
||||
op.u.adjustdom.direction = SCHED_INFO_GET;
|
||||
|
||||
ret = do_dom0_op(xc_handle, &op);
|
||||
|
||||
*mcuadv = adjptr->mcu_adv;
|
||||
*warpback = adjptr->warpback;
|
||||
*warpvalue = adjptr->warpvalue;
|
||||
*warpl = adjptr->warpl;
|
||||
*warpu = adjptr->warpu;
|
||||
return ret;
|
||||
}
|
||||
+2
-30
@@ -250,36 +250,8 @@ int xc_domain_setcpuweight(int xc_handle,
|
||||
if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 )
|
||||
return ret;
|
||||
|
||||
switch ( sched_id )
|
||||
{
|
||||
case SCHED_BVT:
|
||||
{
|
||||
uint32_t mcuadv;
|
||||
int warpback;
|
||||
int32_t warpvalue;
|
||||
long long warpl;
|
||||
long long warpu;
|
||||
|
||||
/* Preserve all the scheduling parameters apart
|
||||
of MCU advance. */
|
||||
if ( (ret = xc_bvtsched_domain_get(
|
||||
xc_handle, domid, &mcuadv,
|
||||
&warpback, &warpvalue, &warpl, &warpu)) != 0 )
|
||||
return ret;
|
||||
|
||||
/* The MCU advance is inverse of the weight.
|
||||
Default value of the weight is 1, default mcuadv 10.
|
||||
The scaling factor is therefore 10. */
|
||||
if ( weight > 0 )
|
||||
mcuadv = 10 / weight;
|
||||
|
||||
ret = xc_bvtsched_domain_set(xc_handle, domid, mcuadv,
|
||||
warpback, warpvalue, warpl, warpu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* No-op. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xc_domain_setmaxmem(int xc_handle,
|
||||
|
||||
@@ -327,28 +327,6 @@ int xc_shadow_control(int xc_handle,
|
||||
uint32_t mode,
|
||||
xc_shadow_control_stats_t *stats);
|
||||
|
||||
int xc_bvtsched_global_set(int xc_handle,
|
||||
unsigned long ctx_allow);
|
||||
|
||||
int xc_bvtsched_domain_set(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t mcuadv,
|
||||
int warpback,
|
||||
int32_t warpvalue,
|
||||
long long warpl,
|
||||
long long warpu);
|
||||
|
||||
int xc_bvtsched_global_get(int xc_handle,
|
||||
unsigned long *ctx_allow);
|
||||
|
||||
int xc_bvtsched_domain_get(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t *mcuadv,
|
||||
int *warpback,
|
||||
int32_t *warpvalue,
|
||||
long long *warpl,
|
||||
long long *warpu);
|
||||
|
||||
int xc_sedf_domain_set(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint64_t period, uint64_t slice,
|
||||
|
||||
@@ -388,83 +388,6 @@ static PyObject *pyxc_hvm_build(XcObject *self,
|
||||
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
|
||||
}
|
||||
|
||||
static PyObject *pyxc_bvtsched_global_set(XcObject *self, PyObject *args)
|
||||
{
|
||||
unsigned long ctx_allow;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l", &ctx_allow))
|
||||
return NULL;
|
||||
|
||||
if (xc_bvtsched_global_set(self->xc_handle, ctx_allow) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_bvtsched_global_get(XcObject *self)
|
||||
{
|
||||
unsigned long ctx_allow;
|
||||
|
||||
if (xc_bvtsched_global_get(self->xc_handle, &ctx_allow) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
|
||||
}
|
||||
|
||||
static PyObject *pyxc_bvtsched_domain_set(XcObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
uint32_t dom;
|
||||
uint32_t mcuadv;
|
||||
int warpback;
|
||||
int32_t warpvalue;
|
||||
long long warpl;
|
||||
long long warpu;
|
||||
|
||||
static char *kwd_list[] = { "dom", "mcuadv", "warpback", "warpvalue",
|
||||
"warpl", "warpu", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiiLL", kwd_list,
|
||||
&dom, &mcuadv, &warpback, &warpvalue,
|
||||
&warpl, &warpu) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_bvtsched_domain_set(self->xc_handle, dom, mcuadv,
|
||||
warpback, warpvalue, warpl, warpu) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_bvtsched_domain_get(XcObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
uint32_t dom;
|
||||
uint32_t mcuadv;
|
||||
int warpback;
|
||||
int32_t warpvalue;
|
||||
long long warpl;
|
||||
long long warpu;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i", &dom))
|
||||
return NULL;
|
||||
|
||||
if (xc_bvtsched_domain_get(self->xc_handle, dom, &mcuadv, &warpback,
|
||||
&warpvalue, &warpl, &warpu) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
|
||||
"domain", dom,
|
||||
"mcuadv", mcuadv,
|
||||
"warpback", warpback,
|
||||
"warpvalue", warpvalue,
|
||||
"warpl", warpl,
|
||||
"warpu", warpu);
|
||||
}
|
||||
|
||||
static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
@@ -1051,45 +974,6 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "bvtsched_global_set",
|
||||
(PyCFunction)pyxc_bvtsched_global_set,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
|
||||
" ctx_allow [int]: Minimal guaranteed quantum.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "bvtsched_global_get",
|
||||
(PyCFunction)pyxc_bvtsched_global_get,
|
||||
METH_NOARGS, "\n"
|
||||
"Get global tuning parameters for BVT scheduler.\n"
|
||||
"Returns: [dict]:\n"
|
||||
" ctx_allow [int]: context switch allowance\n" },
|
||||
|
||||
{ "bvtsched_domain_set",
|
||||
(PyCFunction)pyxc_bvtsched_domain_set,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
|
||||
" dom [int]: Identifier of domain to be tuned.\n"
|
||||
" mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
|
||||
" warpback [int]: Warp ? \n"
|
||||
" warpvalue [int]: How far to warp domain's EVT on unblock.\n"
|
||||
" warpl [int]: How long the domain can run warped.\n"
|
||||
" warpu [int]: How long before the domain can warp again.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "bvtsched_domain_get",
|
||||
(PyCFunction)pyxc_bvtsched_domain_get,
|
||||
METH_VARARGS, "\n"
|
||||
"Get per-domain tuning parameters under the BVT scheduler.\n"
|
||||
" dom [int]: Identifier of domain to be queried.\n"
|
||||
"Returns [dict]:\n"
|
||||
" domain [int]: Domain ID.\n"
|
||||
" mcuadv [long]: MCU Advance.\n"
|
||||
" warp [long]: Warp.\n"
|
||||
" warpu [long]: Unwarp requirement.\n"
|
||||
" warpl [long]: Warp limit,\n"
|
||||
},
|
||||
|
||||
{ "sedf_domain_set",
|
||||
(PyCFunction)pyxc_sedf_domain_set,
|
||||
METH_KEYWORDS, "\n"
|
||||
|
||||
@@ -471,34 +471,6 @@ class XendDomain:
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
def domain_cpu_bvt_set(self, domid, mcuadv, warpback, warpvalue, warpl,
|
||||
warpu):
|
||||
"""Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
|
||||
"""
|
||||
dominfo = self.domain_lookup_by_name_or_id_nr(domid)
|
||||
if not dominfo:
|
||||
raise XendInvalidDomain(str(domid))
|
||||
try:
|
||||
return xc.bvtsched_domain_set(dom=dominfo.getDomid(),
|
||||
mcuadv=mcuadv,
|
||||
warpback=warpback,
|
||||
warpvalue=warpvalue,
|
||||
warpl=warpl, warpu=warpu)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
def domain_cpu_bvt_get(self, domid):
|
||||
"""Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
|
||||
"""
|
||||
dominfo = self.domain_lookup_by_name_or_id_nr(domid)
|
||||
if not dominfo:
|
||||
raise XendInvalidDomain(str(domid))
|
||||
try:
|
||||
return xc.bvtsched_domain_get(dominfo.getDomid())
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
|
||||
def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
|
||||
weight):
|
||||
"""Set Simple EDF scheduler parameters for a domain.
|
||||
|
||||
@@ -39,12 +39,6 @@ class XendNode:
|
||||
def notify(self, _):
|
||||
return 0
|
||||
|
||||
def cpu_bvt_slice_set(self, ctx_allow):
|
||||
return self.xc.bvtsched_global_set(ctx_allow)
|
||||
|
||||
def cpu_bvt_slice_get(self):
|
||||
return self.xc.bvtsched_global_get()
|
||||
|
||||
def info(self):
|
||||
return (self.nodeinfo() + self.physinfo() + self.xeninfo() +
|
||||
self.xendinfo())
|
||||
|
||||
@@ -102,18 +102,6 @@ class SrvDomain(SrvDir):
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_cpu_bvt_set(self, _, req):
|
||||
fn = FormFn(self.xd.domain_cpu_bvt_set,
|
||||
[['dom', 'int'],
|
||||
['mcuadv', 'int'],
|
||||
['warpback', 'int'],
|
||||
['warpvalue', 'int'],
|
||||
['warpl', 'long'],
|
||||
['warpu', 'long']])
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
|
||||
def op_cpu_sedf_get(self, _, req):
|
||||
fn = FormFn(self.xd.domain_cpu_sedf_get,
|
||||
[['dom', 'int']])
|
||||
|
||||
@@ -39,12 +39,6 @@ class SrvNode(SrvDir):
|
||||
val = self.xn.reboot()
|
||||
return val
|
||||
|
||||
def op_cpu_bvt_slice_set(self, _, req):
|
||||
fn = FormFn(self.xn.cpu_bvt_slice_set,
|
||||
[['ctx_allow', 'int']])
|
||||
val = fn(req.args, {})
|
||||
return val
|
||||
|
||||
def render_POST(self, req):
|
||||
return self.perform(req)
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ class XMLRPCServer:
|
||||
self.server.register_function(fn, "xend.domain.%s" % name[7:])
|
||||
|
||||
# Functions in XendNode and XendDmesg
|
||||
for type, lst, n in [(XendNode, ['info', 'cpu_bvt_slice_set'], 'node'),
|
||||
for type, lst, n in [(XendNode, ['info'], 'node'),
|
||||
(XendDmesg, ['info', 'clear'], 'node.dmesg')]:
|
||||
inst = type.instance()
|
||||
for name in lst:
|
||||
|
||||
@@ -89,10 +89,6 @@ dmesg_help = "dmesg [-c|--clear] Read or clear Xen's message buf
|
||||
info_help = "info Get information about the xen host"
|
||||
rename_help = "rename <DomId> <New Name> Rename a domain"
|
||||
log_help = "log Print the xend log"
|
||||
sched_bvt_help = """sched-bvt <Parameters> Set Borrowed Virtual Time scheduler
|
||||
parameters"""
|
||||
sched_bvt_ctxallow_help = """sched-bvt-ctxallow <Allow> Set the BVT scheduler context switch
|
||||
allowance"""
|
||||
sched_sedf_help = "sched-sedf [DOM] [OPTIONS] Show|Set simple EDF parameters\n" + \
|
||||
" -p, --period Relative deadline(ms).\n\
|
||||
-s, --slice Worst-case execution time(ms)\n\
|
||||
@@ -192,8 +188,6 @@ host_commands = [
|
||||
|
||||
scheduler_commands = [
|
||||
"sched-credit",
|
||||
"sched-bvt",
|
||||
"sched-bvt-ctxallow",
|
||||
"sched-sedf",
|
||||
]
|
||||
|
||||
@@ -672,18 +666,6 @@ def xm_domname(args):
|
||||
dom = server.xend.domain(name)
|
||||
print sxp.child_value(dom, 'name')
|
||||
|
||||
def xm_sched_bvt(args):
|
||||
arg_check(args, "sched-bvt", 6)
|
||||
dom = args[0]
|
||||
v = map(long, args[1:6])
|
||||
server.xend.domain.cpu_bvt_set(dom, *v)
|
||||
|
||||
def xm_sched_bvt_ctxallow(args):
|
||||
arg_check(args, "sched-bvt-ctxallow", 1)
|
||||
|
||||
slice = int(args[0])
|
||||
server.xend.node.cpu_bvt_slice_set(slice)
|
||||
|
||||
def xm_sched_sedf(args):
|
||||
def ns_to_ms(val):
|
||||
return float(val) * 0.000001
|
||||
@@ -1209,8 +1191,6 @@ commands = {
|
||||
"log": xm_log,
|
||||
"serve": xm_serve,
|
||||
# scheduler
|
||||
"sched-bvt": xm_sched_bvt,
|
||||
"sched-bvt-ctxallow": xm_sched_bvt_ctxallow,
|
||||
"sched-sedf": xm_sched_sedf,
|
||||
"sched-credit": xm_sched_credit,
|
||||
# block
|
||||
|
||||
@@ -17,4 +17,4 @@ Elilo update for Xen/ia64 HowTo 2005/12/01
|
||||
vmm=xen.gz
|
||||
initrd=initrd-2.6.9-5.7.EL.img
|
||||
read-only
|
||||
append="com2=57600,8n1 console=com2 sched=bvt -- nomca console=ttyS1,57600 console=tty0 root=/dev/sda3"
|
||||
append="com2=57600,8n1 console=com2 -- nomca console=ttyS1,57600 console=tty0 root=/dev/sda3"
|
||||
@@ -12,7 +12,6 @@ obj-y += memory.o
|
||||
obj-y += multicall.o
|
||||
obj-y += page_alloc.o
|
||||
obj-y += rangeset.o
|
||||
obj-y += sched_bvt.o
|
||||
obj-y += sched_credit.o
|
||||
obj-y += sched_sedf.o
|
||||
obj-y += schedule.o
|
||||
|
||||
@@ -1,588 +0,0 @@
|
||||
/****************************************************************************
|
||||
* (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge
|
||||
* (C) 2002-2003 University of Cambridge
|
||||
* (C) 2004 - Mark Williamson - Intel Research Cambridge
|
||||
****************************************************************************
|
||||
*
|
||||
* File: common/schedule.c
|
||||
* Author: Rolf Neugebauer & Keir Fraser
|
||||
* Updated for generic API by Mark Williamson
|
||||
*
|
||||
* Description: CPU scheduling
|
||||
* implements A Borrowed Virtual Time scheduler.
|
||||
* (see Duda & Cheriton SOSP'99)
|
||||
*/
|
||||
|
||||
#include <xen/config.h>
|
||||
#include <xen/init.h>
|
||||
#include <xen/lib.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/delay.h>
|
||||
#include <xen/event.h>
|
||||
#include <xen/time.h>
|
||||
#include <xen/timer.h>
|
||||
#include <xen/perfc.h>
|
||||
#include <xen/sched-if.h>
|
||||
#include <xen/softirq.h>
|
||||
#include <xen/errno.h>
|
||||
|
||||
/* all per-domain BVT-specific scheduling info is stored here */
|
||||
struct bvt_vcpu_info
|
||||
{
|
||||
struct list_head run_list; /* runqueue list pointers */
|
||||
u32 avt; /* actual virtual time */
|
||||
u32 evt; /* effective virtual time */
|
||||
int migrated; /* migrated to a new CPU */
|
||||
struct vcpu *vcpu;
|
||||
struct bvt_dom_info *inf;
|
||||
};
|
||||
|
||||
struct bvt_dom_info
|
||||
{
|
||||
struct domain *domain; /* domain this info belongs to */
|
||||
u32 mcu_advance; /* inverse of weight */
|
||||
int warpback; /* warp? */
|
||||
int warp; /* warp set and within the warp
|
||||
limits*/
|
||||
s32 warp_value; /* virtual time warp */
|
||||
s_time_t warpl; /* warp limit */
|
||||
struct timer warp_timer; /* deals with warpl */
|
||||
s_time_t warpu; /* unwarp time requirement */
|
||||
struct timer unwarp_timer; /* deals with warpu */
|
||||
|
||||
struct bvt_vcpu_info vcpu_inf[MAX_VIRT_CPUS];
|
||||
};
|
||||
|
||||
struct bvt_cpu_info
|
||||
{
|
||||
struct list_head runqueue;
|
||||
unsigned long svt;
|
||||
};
|
||||
|
||||
#define BVT_INFO(p) ((struct bvt_dom_info *)(p)->sched_priv)
|
||||
#define EBVT_INFO(p) ((struct bvt_vcpu_info *)(p)->sched_priv)
|
||||
#define CPU_INFO(cpu) \
|
||||
((struct bvt_cpu_info *)(per_cpu(schedule_data, cpu).sched_priv))
|
||||
#define RUNLIST(p) ((struct list_head *)&(EBVT_INFO(p)->run_list))
|
||||
#define RUNQUEUE(cpu) ((struct list_head *)&(CPU_INFO(cpu)->runqueue))
|
||||
#define CPU_SVT(cpu) (CPU_INFO(cpu)->svt)
|
||||
|
||||
#define MCU (s32)MICROSECS(100) /* Minimum unit */
|
||||
#define MCU_ADVANCE 10 /* default weight */
|
||||
#define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */
|
||||
#define CTX_MIN (s32)MICROSECS(10) /* Low limit for ctx_allow */
|
||||
static s32 ctx_allow = (s32)MILLISECS(5); /* context switch allowance */
|
||||
|
||||
static inline void __add_to_runqueue_head(struct vcpu *d)
|
||||
{
|
||||
list_add(RUNLIST(d), RUNQUEUE(d->processor));
|
||||
}
|
||||
|
||||
static inline void __add_to_runqueue_tail(struct vcpu *d)
|
||||
{
|
||||
list_add_tail(RUNLIST(d), RUNQUEUE(d->processor));
|
||||
}
|
||||
|
||||
static inline void __del_from_runqueue(struct vcpu *d)
|
||||
{
|
||||
struct list_head *runlist = RUNLIST(d);
|
||||
list_del(runlist);
|
||||
runlist->next = NULL;
|
||||
}
|
||||
|
||||
static inline int __task_on_runqueue(struct vcpu *d)
|
||||
{
|
||||
return (RUNLIST(d))->next != NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Warp/unwarp timer functions */
|
||||
static void warp_timer_fn(void *data)
|
||||
{
|
||||
struct bvt_dom_info *inf = data;
|
||||
struct vcpu *v = inf->domain->vcpu[0];
|
||||
|
||||
vcpu_schedule_lock_irq(v);
|
||||
|
||||
inf->warp = 0;
|
||||
|
||||
/* unwarp equal to zero => stop warping */
|
||||
if ( inf->warpu == 0 )
|
||||
{
|
||||
inf->warpback = 0;
|
||||
cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
|
||||
}
|
||||
|
||||
set_timer(&inf->unwarp_timer, NOW() + inf->warpu);
|
||||
|
||||
vcpu_schedule_unlock_irq(v);
|
||||
}
|
||||
|
||||
static void unwarp_timer_fn(void *data)
|
||||
{
|
||||
struct bvt_dom_info *inf = data;
|
||||
struct vcpu *v = inf->domain->vcpu[0];
|
||||
|
||||
vcpu_schedule_lock_irq(v);
|
||||
|
||||
if ( inf->warpback )
|
||||
{
|
||||
inf->warp = 1;
|
||||
cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
|
||||
}
|
||||
|
||||
vcpu_schedule_unlock_irq(v);
|
||||
}
|
||||
|
||||
static inline u32 calc_avt(struct vcpu *v, s_time_t now)
|
||||
{
|
||||
u32 ranfor, mcus;
|
||||
struct bvt_dom_info *inf = BVT_INFO(v->domain);
|
||||
struct bvt_vcpu_info *einf = EBVT_INFO(v);
|
||||
|
||||
ranfor = (u32)(now - v->runstate.state_entry_time);
|
||||
mcus = (ranfor + MCU - 1)/MCU;
|
||||
|
||||
return einf->avt + mcus * inf->mcu_advance;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the effective virtual time for a domain. Take into account
|
||||
* warping limits
|
||||
*/
|
||||
static inline u32 calc_evt(struct vcpu *d, u32 avt)
|
||||
{
|
||||
struct bvt_dom_info *inf = BVT_INFO(d->domain);
|
||||
/* TODO The warp routines need to be rewritten GM */
|
||||
|
||||
if ( inf->warp )
|
||||
return avt - inf->warp_value;
|
||||
else
|
||||
return avt;
|
||||
}
|
||||
|
||||
/**
|
||||
* bvt_init_vcpu - allocate BVT private structures for a VCPU.
|
||||
* Returns non-zero on failure.
|
||||
*/
|
||||
static int bvt_init_vcpu(struct vcpu *v)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
struct bvt_dom_info *inf;
|
||||
struct bvt_vcpu_info *einf;
|
||||
|
||||
if ( (d->sched_priv == NULL) )
|
||||
{
|
||||
if ( (d->sched_priv = xmalloc(struct bvt_dom_info)) == NULL )
|
||||
return -1;
|
||||
memset(d->sched_priv, 0, sizeof(struct bvt_dom_info));
|
||||
}
|
||||
|
||||
inf = BVT_INFO(d);
|
||||
|
||||
v->sched_priv = &inf->vcpu_inf[v->vcpu_id];
|
||||
|
||||
inf->vcpu_inf[v->vcpu_id].inf = BVT_INFO(d);
|
||||
inf->vcpu_inf[v->vcpu_id].vcpu = v;
|
||||
|
||||
if ( v->vcpu_id == 0 )
|
||||
{
|
||||
inf->mcu_advance = MCU_ADVANCE;
|
||||
inf->domain = v->domain;
|
||||
inf->warpback = 0;
|
||||
/* Set some default values here. */
|
||||
inf->warp = 0;
|
||||
inf->warp_value = 0;
|
||||
inf->warpl = MILLISECS(2000);
|
||||
inf->warpu = MILLISECS(1000);
|
||||
/* Initialise the warp timers. */
|
||||
init_timer(&inf->warp_timer, warp_timer_fn, inf, v->processor);
|
||||
init_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
|
||||
}
|
||||
|
||||
einf = EBVT_INFO(v);
|
||||
|
||||
/* Allocate per-CPU context if this is the first domain to be added. */
|
||||
if ( CPU_INFO(v->processor) == NULL )
|
||||
{
|
||||
per_cpu(schedule_data, v->processor).sched_priv =
|
||||
xmalloc(struct bvt_cpu_info);
|
||||
BUG_ON(CPU_INFO(v->processor) == NULL);
|
||||
INIT_LIST_HEAD(RUNQUEUE(v->processor));
|
||||
CPU_SVT(v->processor) = 0;
|
||||
}
|
||||
|
||||
if ( is_idle_vcpu(v) )
|
||||
{
|
||||
einf->avt = einf->evt = ~0U;
|
||||
BUG_ON(__task_on_runqueue(v));
|
||||
__add_to_runqueue_head(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set avt and evt to system virtual time. */
|
||||
einf->avt = CPU_SVT(v->processor);
|
||||
einf->evt = CPU_SVT(v->processor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bvt_wake(struct vcpu *v)
|
||||
{
|
||||
struct bvt_vcpu_info *einf = EBVT_INFO(v);
|
||||
struct vcpu *curr;
|
||||
s_time_t now, r_time;
|
||||
int cpu = v->processor;
|
||||
u32 curr_evt;
|
||||
|
||||
if ( unlikely(__task_on_runqueue(v)) )
|
||||
return;
|
||||
|
||||
__add_to_runqueue_head(v);
|
||||
|
||||
now = NOW();
|
||||
|
||||
/* Set the BVT parameters. AVT should always be updated
|
||||
if CPU migration ocurred.*/
|
||||
if ( (einf->avt < CPU_SVT(cpu)) || einf->migrated )
|
||||
{
|
||||
einf->avt = CPU_SVT(cpu);
|
||||
einf->migrated = 0;
|
||||
}
|
||||
|
||||
/* Deal with warping here. */
|
||||
einf->evt = calc_evt(v, einf->avt);
|
||||
|
||||
curr = per_cpu(schedule_data, cpu).curr;
|
||||
curr_evt = calc_evt(curr, calc_avt(curr, now));
|
||||
/* Calculate the time the current domain would run assuming
|
||||
the second smallest evt is of the newly woken domain */
|
||||
r_time = curr->runstate.state_entry_time +
|
||||
((einf->evt - curr_evt) / BVT_INFO(curr->domain)->mcu_advance) +
|
||||
ctx_allow;
|
||||
|
||||
if ( is_idle_vcpu(curr) || (einf->evt <= curr_evt) )
|
||||
cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
|
||||
else if ( per_cpu(schedule_data, cpu).s_timer.expires > r_time )
|
||||
set_timer(&per_cpu(schedule_data, cpu).s_timer, r_time);
|
||||
}
|
||||
|
||||
|
||||
static void bvt_sleep(struct vcpu *v)
|
||||
{
|
||||
if ( per_cpu(schedule_data, v->processor).curr == v )
|
||||
cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
|
||||
else if ( __task_on_runqueue(v) )
|
||||
__del_from_runqueue(v);
|
||||
}
|
||||
|
||||
|
||||
static int bvt_set_affinity(struct vcpu *v, cpumask_t *affinity)
|
||||
{
|
||||
if ( v == current )
|
||||
return cpu_isset(v->processor, *affinity) ? 0 : -EBUSY;
|
||||
|
||||
vcpu_pause(v);
|
||||
v->cpu_affinity = *affinity;
|
||||
v->processor = first_cpu(v->cpu_affinity);
|
||||
EBVT_INFO(v)->migrated = 1;
|
||||
vcpu_unpause(v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* bvt_destroy_domain - free BVT private structures for a domain.
|
||||
*/
|
||||
static void bvt_destroy_domain(struct domain *d)
|
||||
{
|
||||
struct bvt_dom_info *inf = BVT_INFO(d);
|
||||
|
||||
ASSERT(inf != NULL);
|
||||
|
||||
kill_timer(&inf->warp_timer);
|
||||
kill_timer(&inf->unwarp_timer);
|
||||
|
||||
xfree(inf);
|
||||
}
|
||||
|
||||
/* Control the scheduler. */
|
||||
static int bvt_ctl(struct sched_ctl_cmd *cmd)
|
||||
{
|
||||
struct bvt_ctl *params = &cmd->u.bvt;
|
||||
|
||||
if ( cmd->direction == SCHED_INFO_PUT )
|
||||
ctx_allow = params->ctx_allow;
|
||||
else
|
||||
{
|
||||
if ( ctx_allow < CTX_MIN )
|
||||
ctx_allow = CTX_MIN;
|
||||
params->ctx_allow = ctx_allow;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Adjust scheduling parameter for a given domain. */
|
||||
static int bvt_adjdom(
|
||||
struct domain *d, struct sched_adjdom_cmd *cmd)
|
||||
{
|
||||
struct bvt_adjdom *params = &cmd->u.bvt;
|
||||
|
||||
if ( cmd->direction == SCHED_INFO_PUT )
|
||||
{
|
||||
u32 mcu_adv = params->mcu_adv;
|
||||
u32 warpback = params->warpback;
|
||||
s32 warpvalue = params->warpvalue;
|
||||
s_time_t warpl = params->warpl;
|
||||
s_time_t warpu = params->warpu;
|
||||
|
||||
struct bvt_dom_info *inf = BVT_INFO(d);
|
||||
|
||||
/* Sanity -- this can avoid divide-by-zero. */
|
||||
if ( (mcu_adv == 0) || (warpl < 0) || (warpu < 0) )
|
||||
return -EINVAL;
|
||||
|
||||
inf->mcu_advance = mcu_adv;
|
||||
inf->warpback = warpback;
|
||||
/* The warp should be the same as warpback */
|
||||
inf->warp = warpback;
|
||||
inf->warp_value = warpvalue;
|
||||
inf->warpl = MILLISECS(warpl);
|
||||
inf->warpu = MILLISECS(warpu);
|
||||
|
||||
/* If the unwarp timer set up it needs to be removed */
|
||||
stop_timer(&inf->unwarp_timer);
|
||||
/* If we stop warping the warp timer needs to be removed */
|
||||
if ( !warpback )
|
||||
stop_timer(&inf->warp_timer);
|
||||
}
|
||||
else if ( cmd->direction == SCHED_INFO_GET )
|
||||
{
|
||||
struct bvt_dom_info *inf = BVT_INFO(d);
|
||||
params->mcu_adv = inf->mcu_advance;
|
||||
params->warpvalue = inf->warp_value;
|
||||
params->warpback = inf->warpback;
|
||||
params->warpl = inf->warpl;
|
||||
params->warpu = inf->warpu;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The main function
|
||||
* - deschedule the current domain.
|
||||
* - pick a new domain.
|
||||
* i.e., the domain with lowest EVT.
|
||||
* The runqueue should be ordered by EVT so that is easy.
|
||||
*/
|
||||
static struct task_slice bvt_do_schedule(s_time_t now)
|
||||
{
|
||||
struct domain *d;
|
||||
struct vcpu *prev = current, *next = NULL, *next_prime, *ed;
|
||||
int cpu = prev->processor;
|
||||
s32 r_time; /* time for new dom to run */
|
||||
u32 next_evt, next_prime_evt, min_avt;
|
||||
struct bvt_dom_info *prev_inf = BVT_INFO(prev->domain);
|
||||
struct bvt_vcpu_info *prev_einf = EBVT_INFO(prev);
|
||||
struct bvt_vcpu_info *p_einf = NULL;
|
||||
struct bvt_vcpu_info *next_einf = NULL;
|
||||
struct bvt_vcpu_info *next_prime_einf = NULL;
|
||||
struct task_slice ret;
|
||||
|
||||
ASSERT(prev->sched_priv != NULL);
|
||||
ASSERT(prev_einf != NULL);
|
||||
ASSERT(__task_on_runqueue(prev));
|
||||
|
||||
if ( likely(!is_idle_vcpu(prev)) )
|
||||
{
|
||||
prev_einf->avt = calc_avt(prev, now);
|
||||
prev_einf->evt = calc_evt(prev, prev_einf->avt);
|
||||
|
||||
if(prev_inf->warpback && prev_inf->warpl > 0)
|
||||
stop_timer(&prev_inf->warp_timer);
|
||||
|
||||
__del_from_runqueue(prev);
|
||||
|
||||
if ( vcpu_runnable(prev) )
|
||||
__add_to_runqueue_tail(prev);
|
||||
}
|
||||
|
||||
|
||||
/* We should at least have the idle task */
|
||||
ASSERT(!list_empty(RUNQUEUE(cpu)));
|
||||
|
||||
/*
|
||||
* scan through the run queue and pick the task with the lowest evt
|
||||
* *and* the task the second lowest evt.
|
||||
* this code is O(n) but we expect n to be small.
|
||||
*/
|
||||
next_einf = EBVT_INFO(per_cpu(schedule_data, cpu).idle);
|
||||
next_prime_einf = NULL;
|
||||
|
||||
next_evt = ~0U;
|
||||
next_prime_evt = ~0U;
|
||||
min_avt = ~0U;
|
||||
|
||||
list_for_each_entry ( p_einf, RUNQUEUE(cpu), run_list )
|
||||
{
|
||||
if ( p_einf->evt < next_evt )
|
||||
{
|
||||
next_prime_einf = next_einf;
|
||||
next_prime_evt = next_evt;
|
||||
next_einf = p_einf;
|
||||
next_evt = p_einf->evt;
|
||||
}
|
||||
else if ( next_prime_evt == ~0U )
|
||||
{
|
||||
next_prime_evt = p_einf->evt;
|
||||
next_prime_einf = p_einf;
|
||||
}
|
||||
else if ( p_einf->evt < next_prime_evt )
|
||||
{
|
||||
next_prime_evt = p_einf->evt;
|
||||
next_prime_einf = p_einf;
|
||||
}
|
||||
|
||||
/* Determine system virtual time. */
|
||||
if ( p_einf->avt < min_avt )
|
||||
min_avt = p_einf->avt;
|
||||
}
|
||||
|
||||
if ( next_einf->inf->warp && next_einf->inf->warpl > 0 )
|
||||
set_timer(&next_einf->inf->warp_timer, now + next_einf->inf->warpl);
|
||||
|
||||
/* Extract the domain pointers from the dom infos */
|
||||
next = next_einf->vcpu;
|
||||
next_prime = next_prime_einf->vcpu;
|
||||
|
||||
/* Update system virtual time. */
|
||||
if ( min_avt != ~0U )
|
||||
CPU_SVT(cpu) = min_avt;
|
||||
|
||||
/* check for virtual time overrun on this cpu */
|
||||
if ( CPU_SVT(cpu) >= 0xf0000000 )
|
||||
{
|
||||
ASSERT(!local_irq_is_enabled());
|
||||
|
||||
write_lock(&domlist_lock);
|
||||
|
||||
for_each_domain ( d )
|
||||
{
|
||||
for_each_vcpu (d, ed) {
|
||||
if ( ed->processor == cpu )
|
||||
{
|
||||
p_einf = EBVT_INFO(ed);
|
||||
p_einf->evt -= 0xe0000000;
|
||||
p_einf->avt -= 0xe0000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write_unlock(&domlist_lock);
|
||||
|
||||
CPU_SVT(cpu) -= 0xe0000000;
|
||||
}
|
||||
|
||||
/* work out time for next run through scheduler */
|
||||
if ( is_idle_vcpu(next) )
|
||||
{
|
||||
r_time = ctx_allow;
|
||||
goto sched_done;
|
||||
}
|
||||
|
||||
if ( (next_prime == NULL) || is_idle_vcpu(next_prime) )
|
||||
{
|
||||
/* We have only one runnable task besides the idle task. */
|
||||
r_time = 10 * ctx_allow; /* RN: random constant */
|
||||
goto sched_done;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are here then we have two runnable tasks.
|
||||
* Work out how long 'next' can run till its evt is greater than
|
||||
* 'next_prime's evt. Take context switch allowance into account.
|
||||
*/
|
||||
ASSERT(next_prime_einf->evt >= next_einf->evt);
|
||||
|
||||
r_time = ((next_prime_einf->evt - next_einf->evt)/next_einf->inf->mcu_advance)
|
||||
+ ctx_allow;
|
||||
|
||||
ASSERT(r_time >= ctx_allow);
|
||||
|
||||
sched_done:
|
||||
ret.task = next;
|
||||
ret.time = r_time;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void bvt_dump_runq_el(struct vcpu *p)
|
||||
{
|
||||
struct bvt_vcpu_info *inf = EBVT_INFO(p);
|
||||
|
||||
printk("mcua=%d ev=0x%08X av=0x%08X ",
|
||||
inf->inf->mcu_advance, inf->evt, inf->avt);
|
||||
}
|
||||
|
||||
static void bvt_dump_settings(void)
|
||||
{
|
||||
printk("BVT: mcu=0x%08Xns ctx_allow=0x%08Xns ", (u32)MCU, (s32)ctx_allow );
|
||||
}
|
||||
|
||||
static void bvt_dump_cpu_state(int i)
|
||||
{
|
||||
struct list_head *queue;
|
||||
int loop = 0;
|
||||
struct bvt_vcpu_info *vcpu_inf;
|
||||
struct vcpu *v;
|
||||
|
||||
printk("svt=0x%08lX ", CPU_SVT(i));
|
||||
|
||||
queue = RUNQUEUE(i);
|
||||
printk("QUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
|
||||
(unsigned long) queue->next, (unsigned long) queue->prev);
|
||||
|
||||
list_for_each_entry ( vcpu_inf, queue, run_list )
|
||||
{
|
||||
v = vcpu_inf->vcpu;
|
||||
printk("%3d: %u has=%c ", loop++, v->domain->domain_id,
|
||||
test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F');
|
||||
bvt_dump_runq_el(v);
|
||||
printk(" l: %p n: %p p: %p\n",
|
||||
&vcpu_inf->run_list, vcpu_inf->run_list.next,
|
||||
vcpu_inf->run_list.prev);
|
||||
}
|
||||
}
|
||||
|
||||
struct scheduler sched_bvt_def = {
|
||||
.name = "Borrowed Virtual Time",
|
||||
.opt_name = "bvt",
|
||||
.sched_id = SCHED_BVT,
|
||||
|
||||
.init_vcpu = bvt_init_vcpu,
|
||||
.destroy_domain = bvt_destroy_domain,
|
||||
|
||||
.do_schedule = bvt_do_schedule,
|
||||
.control = bvt_ctl,
|
||||
.adjdom = bvt_adjdom,
|
||||
.dump_settings = bvt_dump_settings,
|
||||
.dump_cpu_state = bvt_dump_cpu_state,
|
||||
.sleep = bvt_sleep,
|
||||
.wake = bvt_wake,
|
||||
.set_affinity = bvt_set_affinity
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -49,11 +49,9 @@ static void poll_timer_fn(void *data);
|
||||
/* This is global for now so that private implementations can reach it */
|
||||
DEFINE_PER_CPU(struct schedule_data, schedule_data);
|
||||
|
||||
extern struct scheduler sched_bvt_def;
|
||||
extern struct scheduler sched_sedf_def;
|
||||
extern struct scheduler sched_credit_def;
|
||||
static struct scheduler *schedulers[] = {
|
||||
&sched_bvt_def,
|
||||
&sched_sedf_def,
|
||||
&sched_credit_def,
|
||||
NULL
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#define __XEN_PUBLIC_SCHED_CTL_H__
|
||||
|
||||
/* Scheduler types. */
|
||||
#define SCHED_BVT 0
|
||||
#define SCHED_SEDF 4
|
||||
#define SCHED_CREDIT 5
|
||||
|
||||
@@ -23,11 +22,6 @@
|
||||
struct sched_ctl_cmd {
|
||||
uint32_t sched_id;
|
||||
uint32_t direction;
|
||||
union {
|
||||
struct bvt_ctl {
|
||||
uint32_t ctx_allow;
|
||||
} bvt;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct sched_adjdom_cmd {
|
||||
@@ -35,13 +29,6 @@ struct sched_adjdom_cmd {
|
||||
uint32_t direction;
|
||||
domid_t domain;
|
||||
union {
|
||||
struct bvt_adjdom {
|
||||
uint32_t mcu_adv; /* mcu advance: inverse of weight */
|
||||
uint32_t warpback; /* warp? */
|
||||
int32_t warpvalue; /* warp value */
|
||||
int64_t warpl; /* warp limit */
|
||||
int64_t warpu; /* unwarp time requirement */
|
||||
} bvt;
|
||||
struct sedf_adjdom {
|
||||
uint64_t period;
|
||||
uint64_t slice;
|
||||
|
||||