mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
libxc: get and set soft and hard affinity
by using the flag and the new cpumap arguments introduced in
the parameters of the DOMCTL_{get,set}_vcpuaffinity hypercalls.
Now, both xc_vcpu_setaffinity() and xc_vcpu_getaffinity() have
a new flag parameter, to specify whether the user wants to
set/get hard affinity, soft affinity or both. They also have
two cpumap parameters instead of only one. This way, it is
possible to set/get both hard and soft affinity at the same
time (and, in case of set, each one to its own value).
In xc_vcpu_setaffinity(), the cpumaps are IN/OUT parameters,
as it is for the corresponding arguments of the
DOMCTL_set_vcpuaffinity hypercall. What Xen puts there is the
hard and soft effective affinity, that is what Xen will actually
use for scheduling.
In-tree callers are also fixed to cope with the new interface.
Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
1 parent
d172e6b648
commit
6cc89d3101
5 files changed
+111
-32
No files matched your search
+44
-24
@@ -202,10 +202,15 @@ int xc_domain_node_getaffinity(xc_interface *xch,
|
||||
int xc_vcpu_setaffinity(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
xc_cpumap_t cpumap)
|
||||
xc_cpumap_t cpumap_hard_inout,
|
||||
xc_cpumap_t cpumap_soft_inout,
|
||||
uint32_t flags)
|
||||
{
|
||||
DECLARE_DOMCTL;
|
||||
DECLARE_HYPERCALL_BUFFER(uint8_t, local);
|
||||
DECLARE_HYPERCALL_BOUNCE(cpumap_hard_inout, 0,
|
||||
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
|
||||
DECLARE_HYPERCALL_BOUNCE(cpumap_soft_inout, 0,
|
||||
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
|
||||
int ret = -1;
|
||||
int cpusize;
|
||||
|
||||
@@ -213,32 +218,37 @@ int xc_vcpu_setaffinity(xc_interface *xch,
|
||||
if (cpusize <= 0)
|
||||
{
|
||||
PERROR("Could not get number of cpus");
|
||||
goto out;
|
||||
return -1;
|
||||
}
|
||||
|
||||
local = xc_hypercall_buffer_alloc(xch, local, cpusize);
|
||||
if ( local == NULL )
|
||||
HYPERCALL_BOUNCE_SET_SIZE(cpumap_hard_inout, cpusize);
|
||||
HYPERCALL_BOUNCE_SET_SIZE(cpumap_soft_inout, cpusize);
|
||||
|
||||
if ( xc_hypercall_bounce_pre(xch, cpumap_hard_inout) ||
|
||||
xc_hypercall_bounce_pre(xch, cpumap_soft_inout) )
|
||||
{
|
||||
PERROR("Could not allocate memory for setvcpuaffinity domctl hypercall");
|
||||
PERROR("Could not allocate hcall buffers for DOMCTL_setvcpuaffinity");
|
||||
goto out;
|
||||
}
|
||||
|
||||
domctl.cmd = XEN_DOMCTL_setvcpuaffinity;
|
||||
domctl.domain = (domid_t)domid;
|
||||
domctl.u.vcpuaffinity.vcpu = vcpu;
|
||||
domctl.u.vcpuaffinity.flags = XEN_VCPUAFFINITY_HARD;
|
||||
|
||||
memcpy(local, cpumap, cpusize);
|
||||
|
||||
set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap_hard.bitmap, local);
|
||||
domctl.u.vcpuaffinity.flags = flags;
|
||||
|
||||
set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap_hard.bitmap,
|
||||
cpumap_hard_inout);
|
||||
domctl.u.vcpuaffinity.cpumap_hard.nr_bits = cpusize * 8;
|
||||
set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap_soft.bitmap,
|
||||
cpumap_soft_inout);
|
||||
domctl.u.vcpuaffinity.cpumap_soft.nr_bits = cpusize * 8;
|
||||
|
||||
ret = do_domctl(xch, &domctl);
|
||||
|
||||
xc_hypercall_buffer_free(xch, local);
|
||||
|
||||
out:
|
||||
xc_hypercall_bounce_post(xch, cpumap_hard_inout);
|
||||
xc_hypercall_bounce_post(xch, cpumap_soft_inout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -246,10 +256,13 @@ int xc_vcpu_setaffinity(xc_interface *xch,
|
||||
int xc_vcpu_getaffinity(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
xc_cpumap_t cpumap)
|
||||
xc_cpumap_t cpumap_hard,
|
||||
xc_cpumap_t cpumap_soft,
|
||||
uint32_t flags)
|
||||
{
|
||||
DECLARE_DOMCTL;
|
||||
DECLARE_HYPERCALL_BUFFER(uint8_t, local);
|
||||
DECLARE_HYPERCALL_BOUNCE(cpumap_hard, 0, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
|
||||
DECLARE_HYPERCALL_BOUNCE(cpumap_soft, 0, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
|
||||
int ret = -1;
|
||||
int cpusize;
|
||||
|
||||
@@ -257,30 +270,37 @@ int xc_vcpu_getaffinity(xc_interface *xch,
|
||||
if (cpusize <= 0)
|
||||
{
|
||||
PERROR("Could not get number of cpus");
|
||||
goto out;
|
||||
return -1;
|
||||
}
|
||||
|
||||
local = xc_hypercall_buffer_alloc(xch, local, cpusize);
|
||||
if (local == NULL)
|
||||
HYPERCALL_BOUNCE_SET_SIZE(cpumap_hard, cpusize);
|
||||
HYPERCALL_BOUNCE_SET_SIZE(cpumap_soft, cpusize);
|
||||
|
||||
if ( xc_hypercall_bounce_pre(xch, cpumap_hard) ||
|
||||
xc_hypercall_bounce_pre(xch, cpumap_soft) )
|
||||
{
|
||||
PERROR("Could not allocate memory for getvcpuaffinity domctl hypercall");
|
||||
PERROR("Could not allocate hcall buffers for DOMCTL_getvcpuaffinity");
|
||||
goto out;
|
||||
}
|
||||
|
||||
domctl.cmd = XEN_DOMCTL_getvcpuaffinity;
|
||||
domctl.domain = (domid_t)domid;
|
||||
domctl.u.vcpuaffinity.vcpu = vcpu;
|
||||
domctl.u.vcpuaffinity.flags = XEN_VCPUAFFINITY_HARD;
|
||||
domctl.u.vcpuaffinity.flags = flags;
|
||||
|
||||
set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap_hard.bitmap, local);
|
||||
set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap_hard.bitmap,
|
||||
cpumap_hard);
|
||||
domctl.u.vcpuaffinity.cpumap_hard.nr_bits = cpusize * 8;
|
||||
set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap_soft.bitmap,
|
||||
cpumap_soft);
|
||||
domctl.u.vcpuaffinity.cpumap_soft.nr_bits = cpusize * 8;
|
||||
|
||||
ret = do_domctl(xch, &domctl);
|
||||
|
||||
memcpy(cpumap, local, cpusize);
|
||||
out:
|
||||
xc_hypercall_bounce_post(xch, cpumap_hard);
|
||||
xc_hypercall_bounce_post(xch, cpumap_soft);
|
||||
|
||||
xc_hypercall_buffer_free(xch, local);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+53
-2
@@ -600,14 +600,65 @@ int xc_domain_node_getaffinity(xc_interface *xch,
|
||||
uint32_t domind,
|
||||
xc_nodemap_t nodemap);
|
||||
|
||||
/**
|
||||
* This function specifies the CPU affinity for a vcpu.
|
||||
*
|
||||
* There are two kinds of affinity. Soft affinity is on what CPUs a vcpu
|
||||
* prefers to run. Hard affinity is on what CPUs a vcpu is allowed to run.
|
||||
* If flags contains XEN_VCPUAFFINITY_SOFT, the soft affinity it is set to
|
||||
* what cpumap_soft_inout contains. If flags contains XEN_VCPUAFFINITY_HARD,
|
||||
* the hard affinity is set to what cpumap_hard_inout contains. Both flags
|
||||
* can be set at the same time, in which case both soft and hard affinity are
|
||||
* set to what the respective parameter contains.
|
||||
*
|
||||
* The function also returns the effective hard or/and soft affinity, still
|
||||
* via the cpumap_soft_inout and cpumap_hard_inout parameters. Effective
|
||||
* affinity is, in case of soft affinity, the intersection of soft affinity,
|
||||
* hard affinity and the cpupool's online CPUs for the domain, and is returned
|
||||
* in cpumap_soft_inout, if XEN_VCPUAFFINITY_SOFT is set in flags. In case of
|
||||
* hard affinity, it is the intersection between hard affinity and the
|
||||
* cpupool's online CPUs, and is returned in cpumap_hard_inout, if
|
||||
* XEN_VCPUAFFINITY_HARD is set in flags. If both flags are set, both soft
|
||||
* and hard affinity are returned in the respective parameter.
|
||||
*
|
||||
* We do report it back as effective affinity is what the Xen scheduler will
|
||||
* actually use, and we thus allow checking whether or not that matches with,
|
||||
* or at least is good enough for, the caller's purposes.
|
||||
*
|
||||
* @param xch a handle to an open hypervisor interface.
|
||||
* @param domid the id of the domain to which the vcpu belongs
|
||||
* @param vcpu the vcpu id wihin the domain
|
||||
* @param cpumap_hard_inout specifies(/returns) the (effective) hard affinity
|
||||
* @param cpumap_soft_inout specifies(/returns) the (effective) soft affinity
|
||||
* @param flags what we want to set
|
||||
*/
|
||||
int xc_vcpu_setaffinity(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
xc_cpumap_t cpumap);
|
||||
xc_cpumap_t cpumap_hard_inout,
|
||||
xc_cpumap_t cpumap_soft_inout,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* This function retrieves hard and soft CPU affinity of a vcpu,
|
||||
* depending on what flags are set.
|
||||
*
|
||||
* Soft affinity is returned in cpumap_soft if XEN_VCPUAFFINITY_SOFT is set.
|
||||
* Hard affinity is returned in cpumap_hard if XEN_VCPUAFFINITY_HARD is set.
|
||||
*
|
||||
* @param xch a handle to an open hypervisor interface.
|
||||
* @param domid the id of the domain to which the vcpu belongs
|
||||
* @param vcpu the vcpu id wihin the domain
|
||||
* @param cpumap_hard is where hard affinity is returned
|
||||
* @param cpumap_soft is where soft affinity is returned
|
||||
* @param flags what we want get
|
||||
*/
|
||||
int xc_vcpu_getaffinity(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
xc_cpumap_t cpumap);
|
||||
xc_cpumap_t cpumap_hard,
|
||||
xc_cpumap_t cpumap_soft,
|
||||
uint32_t flags);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+4
-2
@@ -4611,7 +4611,8 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,
|
||||
goto err;
|
||||
}
|
||||
if (xc_vcpu_getaffinity(ctx->xch, domid, *nr_vcpus_out,
|
||||
ptr->cpumap.map) == -1) {
|
||||
ptr->cpumap.map, NULL,
|
||||
XEN_VCPUAFFINITY_HARD) == -1) {
|
||||
LOGE(ERROR, "getting vcpu affinity");
|
||||
goto err;
|
||||
}
|
||||
@@ -4635,7 +4636,8 @@ err:
|
||||
int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid,
|
||||
libxl_bitmap *cpumap)
|
||||
{
|
||||
if (xc_vcpu_setaffinity(ctx->xch, domid, vcpuid, cpumap->map)) {
|
||||
if (xc_vcpu_setaffinity(ctx->xch, domid, vcpuid, cpumap->map, NULL,
|
||||
XEN_VCPUAFFINITY_HARD)) {
|
||||
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "setting vcpu affinity");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
@@ -438,7 +438,9 @@ CAMLprim value stub_xc_vcpu_setaffinity(value xch, value domid,
|
||||
c_cpumap[i/8] |= 1 << (i&7);
|
||||
}
|
||||
retval = xc_vcpu_setaffinity(_H(xch), _D(domid),
|
||||
Int_val(vcpu), c_cpumap);
|
||||
Int_val(vcpu),
|
||||
c_cpumap, NULL,
|
||||
XEN_VCPUAFFINITY_HARD);
|
||||
free(c_cpumap);
|
||||
|
||||
if (retval < 0)
|
||||
@@ -460,7 +462,9 @@ CAMLprim value stub_xc_vcpu_getaffinity(value xch, value domid,
|
||||
failwith_xc(_H(xch));
|
||||
|
||||
retval = xc_vcpu_getaffinity(_H(xch), _D(domid),
|
||||
Int_val(vcpu), c_cpumap);
|
||||
Int_val(vcpu),
|
||||
c_cpumap, NULL,
|
||||
XEN_VCPUAFFINITY_HARD);
|
||||
if (retval < 0) {
|
||||
free(c_cpumap);
|
||||
failwith_xc(_H(xch));
|
||||
|
||||
@@ -256,7 +256,8 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
|
||||
}
|
||||
}
|
||||
|
||||
if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
|
||||
if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap,
|
||||
NULL, XEN_VCPUAFFINITY_HARD) != 0 )
|
||||
{
|
||||
free(cpumap);
|
||||
return pyxc_error_to_exception(self->xc_handle);
|
||||
@@ -403,7 +404,8 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self,
|
||||
if(cpumap == NULL)
|
||||
return pyxc_error_to_exception(self->xc_handle);
|
||||
|
||||
rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, cpumap);
|
||||
rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, cpumap,
|
||||
NULL, XEN_VCPUAFFINITY_HARD);
|
||||
if ( rc < 0 )
|
||||
{
|
||||
free(cpumap);
|
||||
|
||||