[libvirt] [PATCH 29/34] conf: Don't store vcpusched orthogonally to other vcpu info

John Ferlan jferlan at redhat.com
Sat Jan 16 15:23:13 UTC 2016



On 01/14/2016 11:27 AM, Peter Krempa wrote:
> Due to bad design the vcpu sched element is orthogonal to the way how
> the data belongs to the corresponding objects. Now that vcpus are a
> struct that allow to store other info too, let's convert the data to the
> sane structure.
> 
> The helpers for the conversion are made universal so that they can be
> reused for iothreads too.
> 
> This patch also resolves https://bugzilla.redhat.com/show_bug.cgi?id=1235180
> since with the correct storage approach you can't have dangling data.
> ---
>  src/conf/domain_conf.c  | 231 +++++++++++++++++++++++++++++++++++++++---------
>  src/conf/domain_conf.h  |   8 +-
>  src/qemu/qemu_driver.c  |   6 +-
>  src/qemu/qemu_process.c |   8 +-
>  4 files changed, 202 insertions(+), 51 deletions(-)
> 

As noted from my review of 10/34, I'm just noting something Coverity
found - will review more as I get to this later.

> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index b4f6fe9..e2dda9a 100644

[...]

> 
>  static int
> +virDomainFormatSchedDef(virDomainDefPtr def,
> +                        virBufferPtr buf,
> +                        const char *name,
> +                        virDomainThreadSchedParamPtr (*func)(virDomainDefPtr, unsigned int),
> +                        virBitmapPtr resourceMap)
> +{
> +    virBitmapPtr schedMap = NULL;
> +    virBitmapPtr prioMap = NULL;
> +    virDomainThreadSchedParamPtr sched;
> +    char *tmp = NULL;
> +    ssize_t next;
> +    size_t i;
> +    int ret = -1;
> +
> +    if (!(schedMap = virBitmapNew(VIR_DOMAIN_CPUMASK_LEN)) ||
> +        !(prioMap = virBitmapNew(VIR_DOMAIN_CPUMASK_LEN)))
> +        goto cleanup;
> +
> +    for (i = VIR_PROC_POLICY_NONE + 1; i < VIR_PROC_POLICY_LAST; i++) {
> +        virBitmapClearAll(schedMap);
> +
> +        /* find vcpus using a particular scheduler */
> +        next = -1;
> +        while ((next = virBitmapNextSetBit(resourceMap, next)) > -1) {
> +            sched = func(def, next);
> +
> +            if (sched->policy == i)
> +                ignore_value(virBitmapSetBit(schedMap, next));
> +        }
> +
> +        /* it's necessary to discriminate priority levels for schedulers that
> +         * have them */
> +        while (!virBitmapIsAllClear(schedMap)) {
> +            virBitmapPtr currentMap = NULL;
> +            ssize_t nextprio;
> +            bool hasPriority = false;
> +            int priority;
> +
> +            switch ((virProcessSchedPolicy) i) {
> +            case VIR_PROC_POLICY_NONE:
> +            case VIR_PROC_POLICY_BATCH:
> +            case VIR_PROC_POLICY_IDLE:
> +            case VIR_PROC_POLICY_LAST:
> +                currentMap = schedMap;
> +                break;
> +
> +            case VIR_PROC_POLICY_FIFO:
> +            case VIR_PROC_POLICY_RR:
> +                virBitmapClearAll(prioMap);
> +                hasPriority = true;
> +
> +                /* we need to find a subset of vCPUs with the given scheduler
> +                 * that share the priority */
> +                nextprio = virBitmapNextSetBit(schedMap, -1);

Coverity notes that virBitmapNextSetBit can return -1; however, [1]

> +                sched = func(def, nextprio);
> +                priority = sched->priority;
> +
> +                ignore_value(virBitmapSetBit(prioMap, nextprio));

[1] passing a -1 'nextprio' to virBitmapSetBit as 'size_t b' cannot happen.

> +
> +                while ((nextprio = virBitmapNextSetBit(schedMap, nextprio)) > -1) {
> +                    sched = func(def, nextprio);
> +                    if (sched->priority == priority)
> +                        ignore_value(virBitmapSetBit(prioMap, nextprio));
> +                }
> +
> +                currentMap = prioMap;
> +                break;
> +            }
> +
> +            /* now we have the complete group */
> +            if (!(tmp = virBitmapFormat(currentMap)))
> +                goto cleanup;
> +
> +            virBufferAsprintf(buf,
> +                              "<%ssched %ss='%s' scheduler='%s'",
> +                              name, name, tmp,
> +                              virProcessSchedPolicyTypeToString(i));
> +            VIR_FREE(tmp);
> +
> +            if (hasPriority)
> +                virBufferAsprintf(buf, " priority='%d'", priority);
> +
> +            virBufferAddLit(buf, "/>\n");
> +
> +            /* subtract all vCPUs that were already found */
> +            virBitmapSubtract(schedMap, currentMap);
> +        }
> +    }
> +
> +    ret = 0;
> +
> + cleanup:
> +    virBitmapFree(schedMap);
> +    virBitmapFree(prioMap);
> +    return ret;
> +}
> +
> +

[...]




More information about the libvir-list mailing list