[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 1/2] qom/object, qdev: move globals functions to object.c
From: |
Daniel P . Berrangé |
Subject: |
Re: [PATCH v2 1/2] qom/object, qdev: move globals functions to object.c |
Date: |
Fri, 26 Jul 2024 17:42:37 +0100 |
User-agent: |
Mutt/2.2.12 (2023-09-09) |
CC: Markus since he's had opinions on stuff related to -global in
the past.
On Wed, Jul 03, 2024 at 05:41:48PM -0300, Daniel Henrique Barboza wrote:
> Next patch will add Accel globals support. This means that globals won't be
> qdev exclusive logic since it'll have to deal with TYPE_ACCEL objects.
>
> Move all globals related functions and declarations to object.c. Each
> function is renamed from 'qdev_' to 'object_':
>
> - qdev_prop_register_global() is now object_prop_register_global()
> - qdev_find_global_prop() is now object_find_global_prop()
> - qdev_prop_check_globals() is now object_prop_check_globals()
> - qdev_prop_set_globals() is now object_prop_set_globals()
>
> For object_prop_set_globals() an additional change was made: the function
> was hardwired to be used with DeviceState, where dev->hotplugged is checked
> to determine if object_apply_global_props() will receive a NULL or an
> &error_fatal errp. The function now receives an Object and an errp, and
> logic using dev->hotplugged is moved to its caller (device_post_init()).
>
> Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> hw/core/cpu-common.c | 2 +-
> hw/core/qdev-properties-system.c | 2 +-
> hw/core/qdev-properties.c | 71 -----------------------------
> hw/core/qdev.c | 2 +-
> include/hw/qdev-core.h | 27 -----------
> include/hw/qdev-properties.h | 5 --
> include/qom/object.h | 34 ++++++++++++++
> qom/object.c | 70 ++++++++++++++++++++++++++++
> system/vl.c | 6 +--
> target/i386/cpu.c | 2 +-
> target/sparc/cpu.c | 2 +-
> tests/unit/test-qdev-global-props.c | 4 +-
> 12 files changed, 114 insertions(+), 113 deletions(-)
>
> diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
> index f131cde2c0..794b18f7c5 100644
> --- a/hw/core/cpu-common.c
> +++ b/hw/core/cpu-common.c
> @@ -182,7 +182,7 @@ static void cpu_common_parse_features(const char
> *typename, char *features,
> prop->driver = typename;
> prop->property = g_strdup(featurestr);
> prop->value = g_strdup(val);
> - qdev_prop_register_global(prop);
> + object_prop_register_global(prop);
> } else {
> error_setg(errp, "Expected key=value format, found %s.",
> featurestr);
> diff --git a/hw/core/qdev-properties-system.c
> b/hw/core/qdev-properties-system.c
> index f13350b4fb..5d30ee6257 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -41,7 +41,7 @@ static bool check_prop_still_unset(Object *obj, const char
> *name,
> const void *old_val, const char *new_val,
> bool allow_override, Error **errp)
> {
> - const GlobalProperty *prop = qdev_find_global_prop(obj, name);
> + const GlobalProperty *prop = object_find_global_prop(obj, name);
>
> if (!old_val || (!prop && allow_override)) {
> return true;
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 86a583574d..9cba33c311 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -855,77 +855,6 @@ void qdev_prop_set_array(DeviceState *dev, const char
> *name, QList *values)
> qobject_unref(values);
> }
>
> -static GPtrArray *global_props(void)
> -{
> - static GPtrArray *gp;
> -
> - if (!gp) {
> - gp = g_ptr_array_new();
> - }
> -
> - return gp;
> -}
> -
> -void qdev_prop_register_global(GlobalProperty *prop)
> -{
> - g_ptr_array_add(global_props(), prop);
> -}
> -
> -const GlobalProperty *qdev_find_global_prop(Object *obj,
> - const char *name)
> -{
> - GPtrArray *props = global_props();
> - const GlobalProperty *p;
> - int i;
> -
> - for (i = 0; i < props->len; i++) {
> - p = g_ptr_array_index(props, i);
> - if (object_dynamic_cast(obj, p->driver)
> - && !strcmp(p->property, name)) {
> - return p;
> - }
> - }
> - return NULL;
> -}
> -
> -int qdev_prop_check_globals(void)
> -{
> - int i, ret = 0;
> -
> - for (i = 0; i < global_props()->len; i++) {
> - GlobalProperty *prop;
> - ObjectClass *oc;
> - DeviceClass *dc;
> -
> - prop = g_ptr_array_index(global_props(), i);
> - if (prop->used) {
> - continue;
> - }
> - oc = object_class_by_name(prop->driver);
> - oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
> - if (!oc) {
> - warn_report("global %s.%s has invalid class name",
> - prop->driver, prop->property);
> - ret = 1;
> - continue;
> - }
> - dc = DEVICE_CLASS(oc);
> - if (!dc->hotpluggable && !prop->used) {
> - warn_report("global %s.%s=%s not used",
> - prop->driver, prop->property, prop->value);
> - ret = 1;
> - continue;
> - }
> - }
> - return ret;
> -}
> -
> -void qdev_prop_set_globals(DeviceState *dev)
> -{
> - object_apply_global_props(OBJECT(dev), global_props(),
> - dev->hotplugged ? NULL : &error_fatal);
> -}
> -
> /* --- 64bit unsigned int 'size' type --- */
>
> static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index f3a996f57d..894372b776 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -673,7 +673,7 @@ static void device_post_init(Object *obj)
> * precedence.
> */
> object_apply_compat_props(obj);
> - qdev_prop_set_globals(DEVICE(obj));
> + object_prop_set_globals(obj, DEVICE(obj)->hotplugged ? NULL :
> &error_fatal);
> }
This is pretty awkward :-(
If we're generalizing this global properties concept, then we want
object_prop_set_globals to be called from the Object base class
code. We can't do that given this need to check the 'hotplugged'
property.
That check, however, is total insanity. Pre-existing problem,
not your fault.
I imagine the rationale is that we don't want to kill QEMU
if setting a global fails, and we're in middle of device_add
on a running VM.
Throwing away errors though is unacceptable IMHO. device_add
can report errors and we should be propagating them. Likewise
for object_add, or any object HMP command creating QOM types.
The trouble is that we're about 4-5 levels deep in a call
chain that lacks "Error **errp".
The root problem is that none of object_new, object_new_with_class
and object_new_with_type have a "Error *errp" parameter.
object_new_with_props and object_new_with_propv both *do* have
a "Error *errp" parameter, but then they call into object_new_with_type
and can't get errors back from that.
IMHO we need to fix this inability to report errors from object
construction. It will certainly be a painful refactoring job,
but I think its neccessary in order to support global props
without this horrible hack checking the "hotpluggable" flag.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|