[libvirt] [PATCH 3/4] Add cputune support to libxl driver
Jim Fehlig
jfehlig at novell.com
Thu Apr 7 18:31:51 UTC 2011
Markus Groß wrote:
> The nodeGetInfo code had to be moved into a helper
> function to reuse it without a virConnectPtr.
>
Sounds good.
> ---
> src/libxl/libxl_driver.c | 143 ++++++++++++++++++++++++++++++++++------------
> 1 files changed, 107 insertions(+), 36 deletions(-)
>
> diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
> index c760a23..1539385 100644
> --- a/src/libxl/libxl_driver.c
> +++ b/src/libxl/libxl_driver.c
> @@ -199,6 +199,46 @@ libxlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED,
> virDomainObjUnlock(vm);
> }
>
> +static int
> +libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info)
> +{
> + libxl_physinfo phy_info;
> + const libxl_version_info* ver_info;
> + struct utsname utsname;
> +
> + if (libxl_get_physinfo(&driver->ctx, &phy_info)) {
> + libxlError(VIR_ERR_INTERNAL_ERROR,
> + _("libxl_get_physinfo_info failed"));
> + return -1;
> + }
> +
> + if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) {
> + libxlError(VIR_ERR_INTERNAL_ERROR,
> + _("libxl_get_version_info failed"));
> + return -1;
> + }
> +
> + uname(&utsname);
> + if (virStrncpy(info->model,
> + utsname.machine,
> + strlen(utsname.machine),
> + sizeof(info->model)) == NULL) {
> + libxlError(VIR_ERR_INTERNAL_ERROR,
> + _("machine type %s too big for destination"),
> + utsname.machine);
> + return -1;
> + }
> +
> + info->memory = phy_info.total_pages * (ver_info->pagesize / 1024);
> + info->cpus = phy_info.nr_cpus;
> + info->nodes = phy_info.nr_nodes;
> + info->cores = phy_info.cores_per_socket;
> + info->threads = phy_info.threads_per_core;
> + info->sockets = 1;
> + info->mhz = phy_info.cpu_khz / 1000;
> + return 0;
> +}
> +
> /*
> * Cleanup function for domain that has reached shutoff state.
> *
> @@ -391,6 +431,62 @@ error:
> return -1;
> }
>
> +static int
> +libxlDomainSetVcpuAffinites(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
> +{
> + libxlDomainObjPrivatePtr priv = vm->privateData;
> + virDomainDefPtr def = vm->def;
> + libxl_cpumap map;
> + uint8_t *cpumask = NULL;
> + uint8_t *cpumap = NULL;
> + virNodeInfo nodeinfo;
> + size_t cpumaplen;
> + unsigned int pos;
> + int vcpu, i;
> + int ret = -1;
> +
> + if (libxlDoNodeGetInfo(driver, &nodeinfo) < 0)
> + goto cleanup;
> +
> + cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
> +
> + for (vcpu = 0; vcpu < def->cputune.nvcpupin; ++vcpu) {
> + if (vcpu != def->cputune.vcpupin[vcpu]->vcpuid)
> + continue;
> +
> + if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) {
> + virReportOOMError();
> + goto cleanup;
> + }
> +
> + cpumask = (uint8_t*) def->cputune.vcpupin[vcpu]->cpumask;
> +
> + for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; ++i) {
> + if (cpumask[i]) {
> + pos = i / 8;
> + cpumap[pos] |= 1 << (i % 8);
> + }
> + }
> +
> + map.size = cpumaplen;
> + map.map = cpumap;
> +
> + if (libxl_set_vcpuaffinity(&priv->ctx, def->id, vcpu, &map) != 0) {
> + libxlError(VIR_ERR_INTERNAL_ERROR,
> + _("Failed to pin vcpu '%d' with libxenlight"), vcpu);
> + goto cleanup;
> + }
> +
> + VIR_FREE(cpumap);
> + }
> +
> + ret = 0;
> +
> +cleanup:
> + VIR_FREE(cpumap);
> + return ret;
> +}
> +
> /*
> * Start a domain through libxenlight.
> *
> @@ -440,6 +536,9 @@ libxlVmStart(libxlDriverPrivatePtr driver,
> if (libxlCreateDomEvents(vm) < 0)
> goto error;
>
> + if (libxlDomainSetVcpuAffinites(driver, vm) < 0)
> + goto error;
> +
> if (!start_paused) {
> libxl_domain_unpause(&priv->ctx, domid);
> vm->state = VIR_DOMAIN_RUNNING;
> @@ -869,42 +968,7 @@ libxlGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED)
> static int
> libxlNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
> {
> - libxl_physinfo phy_info;
> - const libxl_version_info* ver_info;
> - libxlDriverPrivatePtr driver = conn->privateData;
> - struct utsname utsname;
> -
> - if (libxl_get_physinfo(&driver->ctx, &phy_info)) {
> - libxlError(VIR_ERR_INTERNAL_ERROR,
> - _("libxl_get_physinfo_info failed"));
> - return -1;
> - }
> -
> - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) {
> - libxlError(VIR_ERR_INTERNAL_ERROR,
> - _("libxl_get_version_info failed"));
> - return -1;
> - }
> -
> - uname(&utsname);
> - if (virStrncpy(info->model,
> - utsname.machine,
> - strlen(utsname.machine),
> - sizeof(info->model)) == NULL) {
> - libxlError(VIR_ERR_INTERNAL_ERROR,
> - _("machine type %s too big for destination"),
> - utsname.machine);
> - return -1;
> - }
> -
> - info->memory = phy_info.total_pages * (ver_info->pagesize / 1024);
> - info->cpus = phy_info.nr_cpus;
> - info->nodes = phy_info.nr_nodes;
> - info->cores = phy_info.cores_per_socket;
> - info->threads = phy_info.threads_per_core;
> - info->sockets = 1;
> - info->mhz = phy_info.cpu_khz / 1000;
> - return 0;
> + return libxlDoNodeGetInfo(conn->privateData, info);
> }
>
> static char *
> @@ -1712,6 +1776,13 @@ libxlDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap,
> _("Failed to pin vcpu '%d' with libxenlight"), vcpu);
> goto cleanup;
> }
> +
> + if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu) < 0) {
> + libxlError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("failed to update or add vcpupin xml"));
> + goto cleanup;
> + }
> +
>
I'm not sure about this hunk. The cputune info is in memory but not
saved anywhere. E.g.
# virsh start domU
# virsh vcpupin domU 0 0,1,2
# virsh dumpxml domU | grep vcpupin
<vcpupin vcpu='0' cpuset='0-2'/>
# restart libvirtd
# virsh dumpxml domU | grep vcpupin
#
I think config in driver->stateDir needs updated to handle this case.
# virsh start domU
# virsh vcpuping domU 0 0,1,2
# virsh shutdown domU
# wait for shutdown
# virsh dumpxml domU | grep vcpupin
<vcpupin vcpu='0' cpuset='0-2'/>
# restart libvirtd
# virsh dumpxml domU | grep vcpupin
#
Once the domain is shutdown, the affinitiy config should be removed
right? Documentation for virDomainPinVcpu states: "This command only
changes the runtime configuration of the domain, so can only be called
on an active domain".
Regards,
Jim
More information about the libvir-list
mailing list