Message ID | 20240708-auto-v2-1-f4908b953f05@daynix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | virtio-net: Convert feature properties to OnOffAuto | expand |
On Mon, Jul 08, 2024 at 04:38:06PM +0900, Akihiko Odaki wrote: > DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO() > as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference > is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of > bool. > > Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> There are a bunch of compatibility issues here. One is that PROP_BIT accepts different values: bool qapi_bool_parse(const char *name, const char *value, bool *obj, Error **errp) { if (g_str_equal(value, "on") || g_str_equal(value, "yes") || g_str_equal(value, "true") || g_str_equal(value, "y")) { *obj = true; return true; } if (g_str_equal(value, "off") || g_str_equal(value, "no") || g_str_equal(value, "false") || g_str_equal(value, "n")) { *obj = false; return true; } error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'"); return false; } Another is that query now no longer reports the actual bit value, it reports "auto". > --- > include/hw/qdev-properties.h | 18 ++++++++++++ > hw/core/qdev-properties.c | 65 +++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 82 insertions(+), 1 deletion(-) > > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h > index 09aa04ca1e27..afec53a48470 100644 > --- a/include/hw/qdev-properties.h > +++ b/include/hw/qdev-properties.h > @@ -43,11 +43,22 @@ struct PropertyInfo { > ObjectPropertyRelease *release; > }; > > +/** > + * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements. > + * @on_bits: Bitmap of elements with "on". > + * @auto_bits: Bitmap of elements with "auto". > + */ > +typedef struct OnOffAutoBit64 { > + uint64_t on_bits; > + uint64_t auto_bits; > +} OnOffAutoBit64; > + > > /*** qdev-properties.c ***/ > > extern const PropertyInfo qdev_prop_bit; > extern const PropertyInfo qdev_prop_bit64; > +extern const PropertyInfo qdev_prop_on_off_auto_bit64; > extern const PropertyInfo qdev_prop_bool; > extern const PropertyInfo qdev_prop_enum; > extern const PropertyInfo qdev_prop_uint8; > @@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link; > .set_default = true, \ > .defval.u = (bool)_defval) > > +#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \ > + DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64, \ > + OnOffAutoBit64, \ > + .bitnr = (_bit), \ > + .set_default = true, \ > + .defval.i = (OnOffAuto)_defval) > + > #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \ > DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \ > .set_default = true, \ > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c > index 86a583574dd0..e1c336435e05 100644 > --- a/hw/core/qdev-properties.c > +++ b/hw/core/qdev-properties.c > @@ -187,7 +187,8 @@ const PropertyInfo qdev_prop_bit = { > > static uint64_t qdev_get_prop_mask64(Property *prop) > { > - assert(prop->info == &qdev_prop_bit64); > + assert(prop->info == &qdev_prop_bit64 || > + prop->info == &qdev_prop_on_off_auto_bit64); > return 0x1ull << prop->bitnr; > } > > @@ -232,6 +233,68 @@ const PropertyInfo qdev_prop_bit64 = { > .set_default_value = set_default_value_bool, > }; > > +static void prop_get_on_off_auto_bit64(Object *obj, Visitor *v, > + const char *name, void *opaque, > + Error **errp) > +{ > + Property *prop = opaque; > + OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop); > + int value; > + uint64_t mask = qdev_get_prop_mask64(prop); > + > + if (p->auto_bits & mask) { > + value = ON_OFF_AUTO_AUTO; > + } else if (p->on_bits & mask) { > + value = ON_OFF_AUTO_ON; > + } else { > + value = ON_OFF_AUTO_OFF; > + } > + > + visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp); > +} > + > +static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v, > + const char *name, void *opaque, > + Error **errp) > +{ > + Property *prop = opaque; > + OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop); > + int value; > + uint64_t mask = qdev_get_prop_mask64(prop); > + > + if (!visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp)) { > + return; > + } > + > + switch (value) { > + case ON_OFF_AUTO_AUTO: > + p->on_bits &= ~mask; > + p->auto_bits |= mask; > + break; > + > + case ON_OFF_AUTO_ON: > + p->on_bits |= mask; > + p->auto_bits &= ~mask; > + break; > + > + case ON_OFF_AUTO_OFF: > + p->on_bits &= ~mask; > + p->auto_bits &= ~mask; > + break; > + } > +} > + > +const PropertyInfo qdev_prop_on_off_auto_bit64 = { > + .name = "OnOffAuto", > + .description = "on/off/auto", > + .enum_table = &OnOffAuto_lookup, > + .get = qdev_propinfo_get_enum, > + .set = qdev_propinfo_set_enum, > + .get = prop_get_on_off_auto_bit64, > + .set = prop_set_on_off_auto_bit64, > + .set_default_value = qdev_propinfo_set_default_value_enum, > +}; > + > /* --- bool --- */ > > static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque, > > -- > 2.45.2
On Mon, Jul 08, 2024 at 06:43:02AM -0400, Michael S. Tsirkin wrote: > On Mon, Jul 08, 2024 at 04:38:06PM +0900, Akihiko Odaki wrote: > > DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO() > > as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference > > is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of > > bool. > > > > Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> > > There are a bunch of compatibility issues here. > One is that PROP_BIT accepts different values: > > > bool qapi_bool_parse(const char *name, const char *value, bool *obj, Error **errp) > { > if (g_str_equal(value, "on") || > g_str_equal(value, "yes") || > g_str_equal(value, "true") || > g_str_equal(value, "y")) { > *obj = true; > return true; > } > if (g_str_equal(value, "off") || > g_str_equal(value, "no") || > g_str_equal(value, "false") || > g_str_equal(value, "n")) { > *obj = false; > return true; > } > > error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, > "'on' or 'off'"); > return false; > } That's just in relation to the CLI string parsing behaviour. It is also broken at the JSON level, since "rss": true no longer works with device_add / -device JSON syntax. With regards, Daniel
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 09aa04ca1e27..afec53a48470 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -43,11 +43,22 @@ struct PropertyInfo { ObjectPropertyRelease *release; }; +/** + * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements. + * @on_bits: Bitmap of elements with "on". + * @auto_bits: Bitmap of elements with "auto". + */ +typedef struct OnOffAutoBit64 { + uint64_t on_bits; + uint64_t auto_bits; +} OnOffAutoBit64; + /*** qdev-properties.c ***/ extern const PropertyInfo qdev_prop_bit; extern const PropertyInfo qdev_prop_bit64; +extern const PropertyInfo qdev_prop_on_off_auto_bit64; extern const PropertyInfo qdev_prop_bool; extern const PropertyInfo qdev_prop_enum; extern const PropertyInfo qdev_prop_uint8; @@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link; .set_default = true, \ .defval.u = (bool)_defval) +#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \ + DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64, \ + OnOffAutoBit64, \ + .bitnr = (_bit), \ + .set_default = true, \ + .defval.i = (OnOffAuto)_defval) + #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \ DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \ .set_default = true, \ diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 86a583574dd0..e1c336435e05 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -187,7 +187,8 @@ const PropertyInfo qdev_prop_bit = { static uint64_t qdev_get_prop_mask64(Property *prop) { - assert(prop->info == &qdev_prop_bit64); + assert(prop->info == &qdev_prop_bit64 || + prop->info == &qdev_prop_on_off_auto_bit64); return 0x1ull << prop->bitnr; } @@ -232,6 +233,68 @@ const PropertyInfo qdev_prop_bit64 = { .set_default_value = set_default_value_bool, }; +static void prop_get_on_off_auto_bit64(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + Property *prop = opaque; + OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop); + int value; + uint64_t mask = qdev_get_prop_mask64(prop); + + if (p->auto_bits & mask) { + value = ON_OFF_AUTO_AUTO; + } else if (p->on_bits & mask) { + value = ON_OFF_AUTO_ON; + } else { + value = ON_OFF_AUTO_OFF; + } + + visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp); +} + +static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + Property *prop = opaque; + OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop); + int value; + uint64_t mask = qdev_get_prop_mask64(prop); + + if (!visit_type_enum(v, name, &value, &OnOffAuto_lookup, errp)) { + return; + } + + switch (value) { + case ON_OFF_AUTO_AUTO: + p->on_bits &= ~mask; + p->auto_bits |= mask; + break; + + case ON_OFF_AUTO_ON: + p->on_bits |= mask; + p->auto_bits &= ~mask; + break; + + case ON_OFF_AUTO_OFF: + p->on_bits &= ~mask; + p->auto_bits &= ~mask; + break; + } +} + +const PropertyInfo qdev_prop_on_off_auto_bit64 = { + .name = "OnOffAuto", + .description = "on/off/auto", + .enum_table = &OnOffAuto_lookup, + .get = qdev_propinfo_get_enum, + .set = qdev_propinfo_set_enum, + .get = prop_get_on_off_auto_bit64, + .set = prop_set_on_off_auto_bit64, + .set_default_value = qdev_propinfo_set_default_value_enum, +}; + /* --- bool --- */ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO() as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of bool. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> --- include/hw/qdev-properties.h | 18 ++++++++++++ hw/core/qdev-properties.c | 65 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-)