All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <drjones@redhat.com>
To: Beata Michalska <beata.michalska@linaro.org>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Richard Henderson <richard.henderson@linaro.org>,
	qemu-devel@nongnu.org, armbru@redhat.com, eric.auger@redhat.com,
	qemu-arm@nongnu.org, imammedo@redhat.com, Dave.Martin@arm.com
Subject: Re: [PATCH v5 1/9] target/arm/monitor: Introduce qmp_query_cpu_model_expansion
Date: Wed, 16 Oct 2019 15:50:25 +0200	[thread overview]
Message-ID: <20191016135025.k4szpqwgkhfnd6dl@kamzik.brq.redhat.com> (raw)
In-Reply-To: <CADSWDzs9sdjE+-1AedPnU6o7U5XjTk=dcHf-BXQXQQkrp2O=Bw@mail.gmail.com>

On Wed, Oct 16, 2019 at 02:24:50PM +0100, Beata Michalska wrote:
> On Tue, 15 Oct 2019 at 12:56, Beata Michalska
> <beata.michalska@linaro.org> wrote:
> >
> > On Tue, 15 Oct 2019 at 11:56, Andrew Jones <drjones@redhat.com> wrote:
> > >
> > > On Tue, Oct 15, 2019 at 10:59:16AM +0100, Beata Michalska wrote:
> > > > On Tue, 1 Oct 2019 at 14:04, Andrew Jones <drjones@redhat.com> wrote:
> > > > > +
> > > > > +    obj = object_new(object_class_get_name(oc));
> > > > > +
> > > > > +    if (qdict_in) {
> > > > > +        Visitor *visitor;
> > > > > +        Error *err = NULL;
> > > > > +
> > > > > +        visitor = qobject_input_visitor_new(model->props);
> > > > > +        visit_start_struct(visitor, NULL, NULL, 0, &err);
> > > > > +        if (err) {
> > > > > +            object_unref(obj);
> > > >
> > > > Shouldn't we free the 'visitor' here as well ?
> > >
> > > Yes. Good catch. So we also need to fix
> > > target/s390x/cpu_models.c:cpu_model_from_info(), which has the same
> > > construction (the construction from which I derived this)
> > >
> > > >
> > > > > +            error_propagate(errp, err);
> > > > > +            return NULL;
> > > > > +        }
> > > > > +
> > >
> > > What about the rest of the patch? With that fixed for v6 can I
> > > add your r-b?
> > >
> >
> > I still got this feeling that we could optimize that a bit - which I'm
> > currently on, so hopefully I'll be able to add more comments soon if
> > that proves to be the case.
> >
> > BR
> > Beata
> 
> I think there are few options that might be considered though the gain
> is not huge .. but it's always smth:
> 
> > +CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
> > +                                                     CpuModelInfo *model,
> > +                                                     Error **errp)
> > +{
> > +    CpuModelExpansionInfo *expansion_info;
> > +    const QDict *qdict_in = NULL;
> > +    QDict *qdict_out;
> > +    ObjectClass *oc;
> > +    Object *obj;
> > +    const char *name;
> > +    int i;
> > +
> > +    if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
> > +        error_setg(errp, "The requested expansion type is not supported");
> > +        return NULL;
> > +    }
> > +
> > +    if (!kvm_enabled() && !strcmp(model->name, "host")) {
> > +        error_setg(errp, "The CPU type '%s' requires KVM", model->name);
> > +        return NULL;
> > +    }
> > +
> > +    oc = cpu_class_by_name(TYPE_ARM_CPU, model->name);
> > +    if (!oc) {
> > +        error_setg(errp, "The CPU type '%s' is not a recognized ARM CPU type",
> > +                   model->name);
> > +        return NULL;
> > +    }
> > +
> > +    if (kvm_enabled()) {
> > +        const char *cpu_type = current_machine->cpu_type;
> > +        int len = strlen(cpu_type) - strlen(ARM_CPU_TYPE_SUFFIX);
> > +        bool supported = false;
> > +
> > +        if (!strcmp(model->name, "host") || !strcmp(model->name, "max")) {
> > +            /* These are kvmarm's recommended cpu types */
> > +            supported = true;
> > +        } else if (strlen(model->name) == len &&
> > +                   !strncmp(model->name, cpu_type, len)) {
> > +            /* KVM is enabled and we're using this type, so it works. */
> > +            supported = true;
> > +        }
> > +        if (!supported) {
> > +            error_setg(errp, "We cannot guarantee the CPU type '%s' works "
> > +                             "with KVM on this host", model->name);
> > +            return NULL;
> > +        }
> > +    }
> > +
> 
> The above section can be slightly reduced and rearranged - preferably
> moved to a separate function
> -> get_cpu_model (...) ?
> 
> * You can check the 'host' model first and then validate the accelerator ->
>     if ( !strcmp(model->name, "host")
>         if (!kvm_enabled())
>             log_error & leave
>        else
>           goto cpu_class_by_name /*cpu_class_by_name moved after the
> final model check @see below */
> 
> * the kvm_enabled section can be than slightly improved (dropping the
> second compare against 'host')
> 
>       if (kvm_enabled() && strcmp(model->name, "max") {
>            /*Validate the current_machine->cpu_type against the
> model->name and report error case mismatch
>           /* otherwise just fall through */
>       }
>  * cpu_class_by_name moved here ...
> > +    if (model->props) {
> MInor: the CPUModelInfo seems to have dedicated field for that
> verification -> has_props
> 
> > +        qdict_in = qobject_to(QDict, model->props);
> > +        if (!qdict_in) {
> > +            error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
> > +            return NULL;
> > +        }
> > +    }
> > +
> > +    obj = object_new(object_class_get_name(oc));
> > +
> > +    if (qdict_in) {
> > +        Visitor *visitor;
> > +        Error *err = NULL;
> > +
> > +        visitor = qobject_input_visitor_new(model->props);
> > +        visit_start_struct(visitor, NULL, NULL, 0, &err);
> > +        if (err) {
> > +            object_unref(obj);
> > +            error_propagate(errp, err);
> > +            return NULL;
> > +        }
> > +
> > +        i = 0;
> > +        while ((name = cpu_model_advertised_features[i++]) != NULL) {
> > +            if (qdict_get(qdict_in, name)) {
> > +                object_property_set(obj, visitor, name, &err);
> > +                if (err) {
> > +                    break;
> > +                }
> > +            }
> > +        }
> > +
> > +        if (!err) {
> > +            visit_check_struct(visitor, &err);
> > +        }
> > +        visit_end_struct(visitor, NULL);
> > +        visit_free(visitor);
> > +        if (err) {
> > +            object_unref(obj);
> > +            error_propagate(errp, err);
> > +            return NULL;
> > +        }
> > +    }
> 
> The both >> if (err) << blocks could be extracted and moved at the end
> of the function
> to mark a 'cleanup section'  and both here and few lines before
> (with the visit_start_struct failure) could use goto.
> Easier to maintain and to make sure we make the proper cleanup in any case.
> 
> > +
> > +    expansion_info = g_new0(CpuModelExpansionInfo, 1);
> > +    expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
> > +    expansion_info->model->name = g_strdup(model->name);
> > +
> > +    qdict_out = qdict_new();
> > +
> > +    i = 0;
> > +    while ((name = cpu_model_advertised_features[i++]) != NULL) {
> > +        ObjectProperty *prop = object_property_find(obj, name, NULL);
> > +        if (prop) {
> > +            Error *err = NULL;
> > +            QObject *value;
> > +
> > +            assert(prop->get);
> > +            value = object_property_get_qobject(obj, name, &err);
> > +            assert(!err);
> > +
> > +            qdict_put_obj(qdict_out, name, value);
> > +        }
> > +    }
> > +
> 
> This could be merged with the first iteration over the features,
> smth like:
> 
>     while () {
>         if ((value = qdict_get(qdict_in, name))) {
>             object_property_set ...
>            if (!err)
>                qobject_ref(value) /* we have the weak reference */
>             else
>                 break;
>         } else {
>              value = object_property_get_qobject()
>         }
>         if (value) qdict_put_object(qdict_out, name, value)
>     }
> 
> This way you iterate over the table once and you do not query
> for the same property twice by getting the value from the qdict_in.
> If the value is not acceptable we will fail either way so should be all good.
> 
> 
> > +    if (!qdict_size(qdict_out)) {
> > +        qobject_unref(qdict_out);
> > +    } else {
> > +        expansion_info->model->props = QOBJECT(qdict_out);
> > +        expansion_info->model->has_props = true;
> > +    }
> > +
> > +    object_unref(obj);
> > +
> > +    return expansion_info;
> 
> Mentioned earlier cleanup section:
> cleanup:
>    object_unref(obj);
>    qobject_unref(qdict_out) ; /* if single loop is used */
>    error_propagate(errp,err);
>    return NULL;
> 
> > +}
> > --
> > 2.20.1
> >
> 
> Hope I haven't missed anything.
> What do you think ?
>

I think you need to post an entire function that incorporates all the
proposed changes, or at least a diff that I can apply in order to get
the entirely changed function. I also think that it's fine the way
it is, so it would take a justification stronger than a potential
micro optimization to get me to change it.

Thanks,
drew


  reply	other threads:[~2019-10-16 13:51 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-01 12:58 [PATCH v5 0/9] target/arm/kvm: enable SVE in guests Andrew Jones
2019-10-01 12:58 ` [PATCH v5 1/9] target/arm/monitor: Introduce qmp_query_cpu_model_expansion Andrew Jones
2019-10-15  9:59   ` Beata Michalska
2019-10-15 10:56     ` Andrew Jones
2019-10-15 11:56       ` Beata Michalska
2019-10-16 13:24         ` Beata Michalska
2019-10-16 13:50           ` Andrew Jones [this message]
2019-10-16 15:16             ` Beata Michalska
2019-10-16 16:16               ` Andrew Jones
2019-10-21 15:07                 ` Beata Michalska
2019-10-22 13:43                   ` Andrew Jones
2019-10-22 15:49                     ` Beata Michalska
2019-10-01 12:58 ` [PATCH v5 2/9] tests: arm: Introduce cpu feature tests Andrew Jones
2019-10-01 12:58 ` [PATCH v5 3/9] target/arm: Allow SVE to be disabled via a CPU property Andrew Jones
2019-10-01 12:58 ` [PATCH v5 4/9] target/arm/cpu64: max cpu: Introduce sve<N> properties Andrew Jones
2019-10-01 17:47   ` Richard Henderson
2019-10-07  7:22   ` Auger Eric
2019-10-07  8:35   ` Alex Bennée
2019-10-07 12:41     ` Andrew Jones
2019-10-09 14:01   ` Beata Michalska
2019-10-16  8:10     ` Andrew Jones
2019-10-01 12:58 ` [PATCH v5 5/9] target/arm/kvm64: Add kvm_arch_get/put_sve Andrew Jones
2019-10-01 13:52   ` Andrew Jones
2019-10-01 13:58     ` Andrew Jones
2019-10-01 17:52   ` Richard Henderson
2019-10-07  7:22   ` Auger Eric
2019-10-01 12:58 ` [PATCH v5 6/9] target/arm/kvm64: max cpu: Enable SVE when available Andrew Jones
2019-10-01 12:58 ` [PATCH v5 7/9] target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features Andrew Jones
2019-10-01 12:58 ` [PATCH v5 8/9] target/arm/cpu64: max cpu: Support sve properties with KVM Andrew Jones
2019-10-01 17:58   ` Richard Henderson
2019-10-01 12:58 ` [PATCH v5 9/9] target/arm/kvm: host cpu: Add support for sve<N> properties Andrew Jones
2019-10-01 17:59   ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191016135025.k4szpqwgkhfnd6dl@kamzik.brq.redhat.com \
    --to=drjones@redhat.com \
    --cc=Dave.Martin@arm.com \
    --cc=armbru@redhat.com \
    --cc=beata.michalska@linaro.org \
    --cc=eric.auger@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.