Re: [PATCH v7 07/11] hw/core/qdev: update hotplug reset regarding resettable

2020-01-17 Thread Philippe Mathieu-Daudé

On 1/15/20 1:36 PM, Damien Hedde wrote:

This commit make use of the resettable API to reset the device being
hotplugged when it is realized. Also it ensures it is put in a reset
state coherent with the parent it is plugged into.

Note that there is a difference in the reset. Instead of resetting
only the hotplugged device, we reset also its subtree (switch to
resettable API). This is not expected to be a problem because
sub-buses are just realized too. If a hotplugged device has any
sub-buses it is logical to reset them too at this point.

The recently added should_be_hidden and PCI's partially_hotplugged
mechanisms do not interfere with realize operation:
+ In the should_be_hidden use case, device creation is
delayed.
+ The partially_hotplugged mechanism prevents a device to be
unplugged and unrealized from qdev POV and unrealized.

Signed-off-by: Damien Hedde 
Reviewed-by: Richard Henderson 
---

v7 update: inline resettable_state_clear()

v6 update: clear the reset state before doing any reset. Although it
is apparently highly improbable that a device be realized again after
being unrealized. See here for a discussion about this point and the
partially_hotplugged/shoud_be_hidden cases.
https://lists.nongnu.org/archive/html/qemu-devel/2019-11/msg04897.html
---
  include/hw/resettable.h | 11 +++
  hw/core/qdev.c  | 15 ++-
  2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/hw/resettable.h b/include/hw/resettable.h
index 3c87ab86c7..3f90da5b5b 100644
--- a/include/hw/resettable.h
+++ b/include/hw/resettable.h
@@ -153,6 +153,17 @@ struct ResettableState {
  bool exit_phase_in_progress;
  };
  
+/**

+ * resettable_state_clear:
+ * Clear the state. It puts the state to the initial (zeroed) state required
+ * to reuse an object. Typically used in realize step of base classes
+ * implementing the interface.
+ */
+static inline void resettable_state_clear(ResettableState *state)
+{
+memset(state, 0, sizeof(ResettableState));
+}
+
  /**
   * resettable_reset:
   * Trigger a reset on an object @obj of type @type. @obj must implement
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 310b87e25a..5fac4cd8fc 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -937,6 +937,12 @@ static void device_set_realized(Object *obj, bool value, 
Error **errp)
  }
  }
  
+/*

+ * Clear the reset state, in case the object was previously unrealized
+ * with a dirty state.
+ */
+resettable_state_clear(>reset);
+
  QLIST_FOREACH(bus, >child_bus, sibling) {
  object_property_set_bool(OBJECT(bus), true, "realized",
   _err);
@@ -945,7 +951,14 @@ static void device_set_realized(Object *obj, bool value, 
Error **errp)
  }
  }
  if (dev->hotplugged) {
-device_legacy_reset(dev);
+/*
+ * Reset the device, as well as its subtree which, at this point,
+ * should be realized too.
+ */
+resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
+resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
+ NULL);
+resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
  }
  dev->pending_deleted_event = false;
  



Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 




[PATCH v7 07/11] hw/core/qdev: update hotplug reset regarding resettable

2020-01-15 Thread Damien Hedde
This commit make use of the resettable API to reset the device being
hotplugged when it is realized. Also it ensures it is put in a reset
state coherent with the parent it is plugged into.

Note that there is a difference in the reset. Instead of resetting
only the hotplugged device, we reset also its subtree (switch to
resettable API). This is not expected to be a problem because
sub-buses are just realized too. If a hotplugged device has any
sub-buses it is logical to reset them too at this point.

The recently added should_be_hidden and PCI's partially_hotplugged
mechanisms do not interfere with realize operation:
+ In the should_be_hidden use case, device creation is
delayed.
+ The partially_hotplugged mechanism prevents a device to be
unplugged and unrealized from qdev POV and unrealized.

Signed-off-by: Damien Hedde 
Reviewed-by: Richard Henderson 
---

v7 update: inline resettable_state_clear()

v6 update: clear the reset state before doing any reset. Although it
is apparently highly improbable that a device be realized again after
being unrealized. See here for a discussion about this point and the
partially_hotplugged/shoud_be_hidden cases.
https://lists.nongnu.org/archive/html/qemu-devel/2019-11/msg04897.html
---
 include/hw/resettable.h | 11 +++
 hw/core/qdev.c  | 15 ++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/hw/resettable.h b/include/hw/resettable.h
index 3c87ab86c7..3f90da5b5b 100644
--- a/include/hw/resettable.h
+++ b/include/hw/resettable.h
@@ -153,6 +153,17 @@ struct ResettableState {
 bool exit_phase_in_progress;
 };
 
+/**
+ * resettable_state_clear:
+ * Clear the state. It puts the state to the initial (zeroed) state required
+ * to reuse an object. Typically used in realize step of base classes
+ * implementing the interface.
+ */
+static inline void resettable_state_clear(ResettableState *state)
+{
+memset(state, 0, sizeof(ResettableState));
+}
+
 /**
  * resettable_reset:
  * Trigger a reset on an object @obj of type @type. @obj must implement
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 310b87e25a..5fac4cd8fc 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -937,6 +937,12 @@ static void device_set_realized(Object *obj, bool value, 
Error **errp)
 }
 }
 
+/*
+ * Clear the reset state, in case the object was previously unrealized
+ * with a dirty state.
+ */
+resettable_state_clear(>reset);
+
 QLIST_FOREACH(bus, >child_bus, sibling) {
 object_property_set_bool(OBJECT(bus), true, "realized",
  _err);
@@ -945,7 +951,14 @@ static void device_set_realized(Object *obj, bool value, 
Error **errp)
 }
 }
 if (dev->hotplugged) {
-device_legacy_reset(dev);
+/*
+ * Reset the device, as well as its subtree which, at this point,
+ * should be realized too.
+ */
+resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
+resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
+ NULL);
+resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
 }
 dev->pending_deleted_event = false;
 
-- 
2.24.1