All of lore.kernel.org
 help / color / mirror / Atom feed
From: Damien Hedde <damien.hedde@greensocs.com>
To: qemu-devel@nongnu.org
Cc: Damien Hedde <damien.hedde@greensocs.com>,
	peter.maydell@linaro.org, berrange@redhat.com,
	ehabkost@redhat.com,
	Richard Henderson <richard.henderson@linaro.org>,
	cohuck@redhat.com, mark.burton@greensocs.com,
	qemu-s390x@nongnu.org, edgari@xilinx.com, pbonzini@redhat.com,
	philmd@redhat.com, david@gibson.dropbear.id.au
Subject: [PATCH v7 05/11] hw/core/resettable: add support for changing parent
Date: Wed, 15 Jan 2020 13:36:14 +0100	[thread overview]
Message-ID: <20200115123620.250132-6-damien.hedde@greensocs.com> (raw)
In-Reply-To: <20200115123620.250132-1-damien.hedde@greensocs.com>

Add a function resettable_change_parent() to do the required
plumbing when changing the parent a of Resettable object.

We need to make sure that the reset state of the object remains
coherent with the reset state of the new parent.

We make the 2 following hypothesis:
+ when an object is put in a parent under reset, the object goes in
reset.
+ when an object is removed from a parent under reset, the object
leaves reset.

The added function avoids any glitch if both old and new parent are
already in reset.

Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/resettable.h | 16 +++++++++++
 hw/core/resettable.c    | 62 +++++++++++++++++++++++++++++++++++++++--
 hw/core/trace-events    |  1 +
 3 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/include/hw/resettable.h b/include/hw/resettable.h
index 58b3df4c22..3c87ab86c7 100644
--- a/include/hw/resettable.h
+++ b/include/hw/resettable.h
@@ -194,6 +194,22 @@ void resettable_release_reset(Object *obj, ResetType type);
  */
 bool resettable_is_in_reset(Object *obj);
 
+/**
+ * resettable_change_parent:
+ * Indicate that the parent of Ressettable @obj is changing from @oldp to @newp.
+ * All 3 objects must implement resettable interface. @oldp or @newp may be
+ * NULL.
+ *
+ * This function will adapt the reset state of @obj so that it is coherent
+ * with the reset state of @newp. It may trigger @resettable_assert_reset()
+ * or @resettable_release_reset(). It will do such things only if the reset
+ * state of @newp and @oldp are different.
+ *
+ * When using this function during reset, it must only be called during
+ * a hold phase method. Calling this during enter or exit phase is an error.
+ */
+void resettable_change_parent(Object *obj, Object *newp, Object *oldp);
+
 /**
  * resettable_class_set_parent_phases:
  *
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
index 9133208487..e99bb30058 100644
--- a/hw/core/resettable.c
+++ b/hw/core/resettable.c
@@ -28,12 +28,16 @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type);
  * enter_phase_in_progress:
  * True if we are currently in reset enter phase.
  *
- * Note: This flag is only used to guarantee (using asserts) that the reset
- * API is used correctly. We can use a global variable because we rely on the
+ * exit_phase_in_progress:
+ * count the number of exit phase we are in.
+ *
+ * Note: These flags are only used to guarantee (using asserts) that the reset
+ * API is used correctly. We can use global variables because we rely on the
  * iothread mutex to ensure only one reset operation is in a progress at a
  * given time.
  */
 static bool enter_phase_in_progress;
+static unsigned exit_phase_in_progress;
 
 void resettable_reset(Object *obj, ResetType type)
 {
@@ -65,7 +69,9 @@ void resettable_release_reset(Object *obj, ResetType type)
     trace_resettable_reset_release_begin(obj, type);
     assert(!enter_phase_in_progress);
 
+    exit_phase_in_progress += 1;
     resettable_phase_exit(obj, NULL, type);
+    exit_phase_in_progress -= 1;
 
     trace_resettable_reset_release_end(obj);
 }
@@ -206,6 +212,58 @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type)
     trace_resettable_phase_exit_end(obj, obj_typename, s->count);
 }
 
+/*
+ * resettable_get_count:
+ * Get the count of the Resettable object @obj. Return 0 if @obj is NULL.
+ */
+static uint32_t resettable_get_count(Object *obj)
+{
+    if (obj) {
+        ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
+        return rc->get_state(obj)->count;
+    }
+    return 0;
+}
+
+void resettable_change_parent(Object *obj, Object *newp, Object *oldp)
+{
+    ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
+    ResettableState *s = rc->get_state(obj);
+    uint32_t newp_count = resettable_get_count(newp);
+    uint32_t oldp_count = resettable_get_count(oldp);
+
+    /*
+     * Ensure we do not change parent when in enter or exit phase.
+     * During these phases, the reset subtree being updated is partly in reset
+     * and partly not in reset (it depends on the actual position in
+     * resettable_child_foreach()s). We are not able to tell in which part is a
+     * leaving or arriving device. Thus we cannot set the reset count of the
+     * moving device to the proper value.
+     */
+    assert(!enter_phase_in_progress && !exit_phase_in_progress);
+    trace_resettable_change_parent(obj, oldp, oldp_count, newp, newp_count);
+
+    /*
+     * At most one of the two 'for' loops will be executed below
+     * in order to cope with the difference between the two counts.
+     */
+    /* if newp is more reset than oldp */
+    for (uint32_t i = oldp_count; i < newp_count; i++) {
+        resettable_assert_reset(obj, RESET_TYPE_COLD);
+    }
+    /*
+     * if obj is leaving a bus under reset, we need to ensure
+     * hold phase is not pending.
+     */
+    if (oldp_count && s->hold_phase_pending) {
+        resettable_phase_hold(obj, NULL, RESET_TYPE_COLD);
+    }
+    /* if oldp is more reset than newp */
+    for (uint32_t i = newp_count; i < oldp_count; i++) {
+        resettable_release_reset(obj, RESET_TYPE_COLD);
+    }
+}
+
 void resettable_class_set_parent_phases(ResettableClass *rc,
                                         ResettableEnterPhase enter,
                                         ResettableHoldPhase hold,
diff --git a/hw/core/trace-events b/hw/core/trace-events
index a2e43f1120..80e6325ab0 100644
--- a/hw/core/trace-events
+++ b/hw/core/trace-events
@@ -16,6 +16,7 @@ resettable_reset_assert_begin(void *obj, int cold) "obj=%p cold=%d"
 resettable_reset_assert_end(void *obj) "obj=%p"
 resettable_reset_release_begin(void *obj, int cold) "obj=%p cold=%d"
 resettable_reset_release_end(void *obj) "obj=%p"
+resettable_change_parent(void *obj, void *o, uint32_t oc, void *n, uint32_t nc) "obj=%p from=%p(%" PRIu32 ") to=%p(%" PRIu32 ")"
 resettable_phase_enter_begin(void *obj, const char *objtype, uint32_t count, int type) "obj=%p(%s) count=%" PRIu32 " type=%d"
 resettable_phase_enter_exec(void *obj, const char *objtype, int type, int has_method) "obj=%p(%s) type=%d method=%d"
 resettable_phase_enter_end(void *obj, const char *objtype, uint32_t count) "obj=%p(%s) count=%" PRIu32
-- 
2.24.1



  parent reply	other threads:[~2020-01-15 12:49 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-15 12:36 [PATCH v7 00/11] Multi-phase reset mechanism Damien Hedde
2020-01-15 12:36 ` [PATCH v7 01/11] add device_legacy_reset function to prepare for reset api change Damien Hedde
2020-01-18  6:48   ` Philippe Mathieu-Daudé
2020-01-15 12:36 ` [PATCH v7 02/11] hw/core/qdev: add trace events to help with resettable transition Damien Hedde
2020-01-16  2:04   ` Philippe Mathieu-Daudé
2020-01-15 12:36 ` [PATCH v7 03/11] hw/core: create Resettable QOM interface Damien Hedde
2020-01-16  1:59   ` Philippe Mathieu-Daudé
2020-01-16  2:12     ` Philippe Mathieu-Daudé
2020-01-16  8:53     ` Damien Hedde
2020-01-16  8:57       ` Philippe Mathieu-Daudé
2020-01-18  6:35   ` Philippe Mathieu-Daudé
2020-01-20  8:50     ` Damien Hedde
2020-01-18  6:42   ` Philippe Mathieu-Daudé
2020-01-20  9:08     ` Damien Hedde
2020-01-20  9:18       ` Philippe Mathieu-Daudé
2020-01-15 12:36 ` [PATCH v7 04/11] hw/core: add Resettable support to BusClass and DeviceClass Damien Hedde
2020-01-16  2:02   ` Philippe Mathieu-Daudé
2020-01-15 12:36 ` Damien Hedde [this message]
2020-01-18  6:45   ` [PATCH v7 05/11] hw/core/resettable: add support for changing parent Philippe Mathieu-Daudé
2020-01-15 12:36 ` [PATCH v7 06/11] hw/core/qdev: handle parent bus change regarding resettable Damien Hedde
2020-01-16  2:05   ` Philippe Mathieu-Daudé
2020-01-15 12:36 ` [PATCH v7 07/11] hw/core/qdev: update hotplug reset " Damien Hedde
2020-01-18  6:47   ` Philippe Mathieu-Daudé
2020-01-15 12:36 ` [PATCH v7 08/11] hw/core: deprecate old reset functions and introduce new ones Damien Hedde
2020-01-18  6:47   ` Philippe Mathieu-Daudé
2020-01-15 12:36 ` [PATCH v7 09/11] docs/devel/reset.rst: add doc about Resettable interface Damien Hedde
2020-01-15 12:36 ` [PATCH v7 10/11] vl: replace deprecated qbus_reset_all registration Damien Hedde
2020-01-15 23:44   ` Philippe Mathieu-Daudé
2020-01-16  8:57     ` Damien Hedde
2020-01-15 12:36 ` [PATCH v7 11/11] hw/s390x/ipl: replace deprecated qdev_reset_all registration Damien Hedde

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=20200115123620.250132-6-damien.hedde@greensocs.com \
    --to=damien.hedde@greensocs.com \
    --cc=berrange@redhat.com \
    --cc=cohuck@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=edgari@xilinx.com \
    --cc=ehabkost@redhat.com \
    --cc=mark.burton@greensocs.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@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.