[libvirt] [PATCH 33/34] qemu: iothread: Aggregate code to set IOTrhead tuning

John Ferlan jferlan at redhat.com
Tue Jan 19 17:27:24 UTC 2016



On 01/14/2016 11:27 AM, Peter Krempa wrote:
> Rather than iterating 3 times for various settings this function
> aggregates all the code into single place. One of the other advantages
> is that it can then be reused for properly setting IOThread info on
> hotplug.
> ---
>  src/qemu/qemu_cgroup.c  |  93 -----------------------------
>  src/qemu/qemu_cgroup.h  |   1 -
>  src/qemu/qemu_process.c | 154 ++++++++++++++++++++++++++++++++----------------
>  src/qemu/qemu_process.h |   2 +
>  4 files changed, 105 insertions(+), 145 deletions(-)
> 

Like 31/34 lots going on here - might be nice to be a bit more verbose
especially w/r/t what's added/fixed...

> diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
> index 827401e..eff059c 100644
> --- a/src/qemu/qemu_cgroup.c
> +++ b/src/qemu/qemu_cgroup.c
> @@ -1071,99 +1071,6 @@ qemuSetupCgroupForEmulator(virDomainObjPtr vm)
>      return -1;
>  }
> 
> -int
> -qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
> -{
> -    virCgroupPtr cgroup_iothread = NULL;
> -    qemuDomainObjPrivatePtr priv = vm->privateData;
> -    virDomainDefPtr def = vm->def;
> -    size_t i;
> -    unsigned long long period = vm->def->cputune.period;
> -    long long quota = vm->def->cputune.quota;
> -    char *mem_mask = NULL;
> -    virDomainNumatuneMemMode mem_mode;
> -
> -    if (def->niothreadids == 0)
> -        return 0;
> -
> -    if ((period || quota) &&
> -        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
> -        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> -                       _("cgroup cpu is required for scheduler tuning"));
> -        return -1;
> -    }
> -
> -    /*
> -     * If CPU cgroup controller is not initialized here, then we need
> -     * neither period nor quota settings.  And if CPUSET controller is
> -     * not initialized either, then there's nothing to do anyway.
> -     */
> -    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) &&
> -        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
> -        return 0;
> -
> -    if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
> -        mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
> -        virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
> -                                            priv->autoNodeset,
> -                                            &mem_mask, -1) < 0)
> -        goto cleanup;
> -
> -    for (i = 0; i < def->niothreadids; i++) {
> -        /* IOThreads are numbered 1..n, although the array is 0..n-1,
> -         * so we will account for that here
> -         */
> -        if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
> -                               def->iothreadids[i]->iothread_id,
> -                               true, &cgroup_iothread) < 0)
> -            goto cleanup;
> -
> -        if (period || quota) {
> -            if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
> -                goto cleanup;
> -        }
> -
> -        /* Set iothreadpin in cgroup if iothreadpin xml is provided */
> -        if (virCgroupHasController(priv->cgroup,
> -                                   VIR_CGROUP_CONTROLLER_CPUSET)) {
> -            virBitmapPtr cpumask = NULL;
> -
> -            if (mem_mask &&
> -                virCgroupSetCpusetMems(cgroup_iothread, mem_mask) < 0)
> -                goto cleanup;
> -
> -            if (def->iothreadids[i]->cpumask)
> -                cpumask = def->iothreadids[i]->cpumask;
> -            else if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
> -                cpumask = priv->autoCpuset;
> -            else
> -                cpumask = def->cpumask;
> -
> -            if (cpumask &&
> -                qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
> -                goto cleanup;
> -        }
> -
> -        /* move the thread for iothread to sub dir */
> -        if (virCgroupAddTask(cgroup_iothread,
> -                             def->iothreadids[i]->thread_id) < 0)
> -            goto cleanup;
> -
> -        virCgroupFree(&cgroup_iothread);
> -    }
> -    VIR_FREE(mem_mask);
> -
> -    return 0;
> -
> - cleanup:
> -    if (cgroup_iothread) {
> -        virCgroupRemove(cgroup_iothread);
> -        virCgroupFree(&cgroup_iothread);
> -    }
> -    VIR_FREE(mem_mask);
> -
> -    return -1;
> -}
> 
>  int
>  qemuRemoveCgroup(virQEMUDriverPtr driver,
> diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
> index fa3353a..a9718b5 100644
> --- a/src/qemu/qemu_cgroup.h
> +++ b/src/qemu/qemu_cgroup.h
> @@ -53,7 +53,6 @@ int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup,
>                            unsigned long long period,
>                            long long quota);
>  int qemuSetupCgroupCpusetCpus(virCgroupPtr cgroup, virBitmapPtr cpumask);
> -int qemuSetupCgroupForIOThreads(virDomainObjPtr vm);
>  int qemuSetupCgroupForEmulator(virDomainObjPtr vm);
>  int qemuRemoveCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm);
>  int qemuAddToCgroup(virDomainObjPtr vm);
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 2a783e5..f5a806b 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -2178,47 +2178,6 @@ qemuProcessSetEmulatorAffinity(virDomainObjPtr vm)
>      return ret;
>  }
> 
> -/* Set CPU affinities for IOThreads threads. */
> -static int
> -qemuProcessSetIOThreadsAffinity(virDomainObjPtr vm)
> -{
> -    virDomainDefPtr def = vm->def;
> -    size_t i;
> -    int ret = -1;
> -
> -    for (i = 0; i < def->niothreadids; i++) {
> -        /* set affinity only for existing iothreads */
> -        if (!def->iothreadids[i]->cpumask)
> -            continue;
> -
> -        if (virProcessSetAffinity(def->iothreadids[i]->thread_id,
> -                                  def->iothreadids[i]->cpumask) < 0)
> -            goto cleanup;
> -    }
> -    ret = 0;
> -
> - cleanup:
> -    return ret;
> -}
> -
> -static int
> -qemuProcessSetSchedulers(virDomainObjPtr vm)
> -{
> -    size_t i = 0;
> -
> -    for (i = 0; i < vm->def->niothreadids; i++) {
> -        virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];
> -
> -        if (info->sched.policy == VIR_PROC_POLICY_NONE)
> -            continue;
> -
> -        if (virProcessSetScheduler(info->thread_id, info->sched.policy,
> -                                   info->sched.priority) < 0)
> -            return -1;
> -    }
> -
> -    return 0;
> -}
> 
>  static int
>  qemuProcessInitPasswords(virConnectPtr conn,
> @@ -4498,6 +4457,107 @@ qemuProcessSetupVcpus(virDomainObjPtr vm)
>  }
> 
> 
> +int
> +qemuProcessSetupIOThread(virDomainObjPtr vm,
> +                         virDomainIOThreadIDDefPtr iothread)
> +{

Simimlar to 31/34 - might be nice to have some function comments
indicating inputs, expectations, and assumptions.

> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    unsigned long long period = vm->def->cputune.period;
> +    long long quota = vm->def->cputune.quota;
> +    virDomainNumatuneMemMode mem_mode;
> +    char *mem_mask = NULL;
> +    virCgroupPtr cgroup_iothread = NULL;
> +    virBitmapPtr cpumask = NULL;
> +    int ret = -1;
> +
> +    if ((period || quota) &&
> +        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                       _("cgroup cpu is required for scheduler tuning"));
> +        return -1;
> +    }
> +
> +    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) ||
> +        virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
> +        if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
> +            mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
> +            virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
> +                                                priv->autoNodeset,
> +                                                &mem_mask, -1) < 0)
> +            goto cleanup;
> +
> +        if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
> +                               iothread->iothread_id,
> +                               true, &cgroup_iothread) < 0)
> +            goto cleanup;
> +    }
> +
> +    if (iothread->cpumask)
> +        cpumask = iothread->cpumask;
> +    else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
> +        cpumask = priv->autoCpuset;
> +    else
> +        cpumask = vm->def->cpumask;
> +
> +    if (period || quota) {
> +        if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
> +            goto cleanup;
> +    }
> +
> +    if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
> +        if (mem_mask &&
> +            virCgroupSetCpusetMems(cgroup_iothread, mem_mask) < 0)
> +            goto cleanup;
> +
> +        if (cpumask &&
> +            qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
> +            goto cleanup;
> +    }
> +
> +    if (cpumask) {
> +        if (virProcessSetAffinity(iothread->thread_id, cpumask) < 0)


Could be:

    if (cpumask && virProcess..."

Similar note to 31/34 w/r/t cpumask could be sourced from autoCpuset;
whereas, previous code would only set if there was iothreadpin data.

Not that this change is wrong, but it is different.

ACK in general though

John
> +            goto cleanup;
> +    }
> +
> +    if (cgroup_iothread &&
> +        virCgroupAddTask(cgroup_iothread, iothread->thread_id) < 0)
> +        goto cleanup;
> +
> +    if (iothread->sched.policy != VIR_PROC_POLICY_NONE &&
> +        virProcessSetScheduler(iothread->thread_id, iothread->sched.policy,
> +                               iothread->sched.priority) < 0)
> +        goto cleanup;
> +
> +    ret = 0;
> +
> + cleanup:
> +    if (cgroup_iothread) {
> +        if (ret < 0)
> +            virCgroupRemove(cgroup_iothread);
> +        virCgroupFree(&cgroup_iothread);
> +    }
> +
> +    VIR_FREE(mem_mask);
> +    return ret;
> +}
> +
> +
> +static int
> +qemuProcessSetupIOThreads(virDomainObjPtr vm)
> +{
> +    size_t i;
> +
> +    for (i = 0; i < vm->def->niothreadids; i++) {
> +        virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];
> +
> +        if (qemuProcessSetupIOThread(vm, info) < 0)
> +            return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +
>  /**
>   * qemuProcessLaunch:
>   *
> @@ -4973,16 +5033,8 @@ qemuProcessLaunch(virConnectPtr conn,
>      if (qemuProcessSetupVcpus(vm) < 0)
>          goto cleanup;
> 
> -    VIR_DEBUG("Setting cgroup for each IOThread (if required)");
> -    if (qemuSetupCgroupForIOThreads(vm) < 0)
> -        goto cleanup;
> -
> -    VIR_DEBUG("Setting affinity of IOThread threads");
> -    if (qemuProcessSetIOThreadsAffinity(vm) < 0)
> -        goto cleanup;
> -
> -    VIR_DEBUG("Setting scheduler parameters");
> -    if (qemuProcessSetSchedulers(vm) < 0)
> +    VIR_DEBUG("Setting IOThread tuning/settings");
> +    if (qemuProcessSetupIOThreads(vm) < 0)
>          goto cleanup;
> 
>      VIR_DEBUG("Setting any required VM passwords");
> diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
> index a2663a0..ff7a722 100644
> --- a/src/qemu/qemu_process.h
> +++ b/src/qemu/qemu_process.h
> @@ -158,5 +158,7 @@ int qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm);
> 
>  int qemuProcessSetupVcpu(virDomainObjPtr vm,
>                           unsigned int vcpuid);
> +int qemuProcessSetupIOThread(virDomainObjPtr vm,
> +                             virDomainIOThreadIDDefPtr iothread);
> 
>  #endif /* __QEMU_PROCESS_H__ */
> 




More information about the libvir-list mailing list