qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@redhat.com>
To: Damien Hedde <damien.hedde@greensocs.com>, qemu-devel@nongnu.org
Cc: 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,
	david@gibson.dropbear.id.au
Subject: Re: [PATCH v7 03/11] hw/core: create Resettable QOM interface
Date: Mon, 20 Jan 2020 10:18:07 +0100	[thread overview]
Message-ID: <3f357f91-277c-1a6a-d007-2990ceac00c9@redhat.com> (raw)
In-Reply-To: <19a6a511-a259-8d25-cba6-7059fbe4fe6f@greensocs.com>

On 1/20/20 10:08 AM, Damien Hedde wrote:
> On 1/18/20 7:42 AM, Philippe Mathieu-Daudé wrote:
>> On 1/15/20 1:36 PM, Damien Hedde wrote:
>>> This commit defines an interface allowing multi-phase reset. This aims
>>> to solve a problem of the actual single-phase reset (built in
>>> DeviceClass and BusClass): reset behavior is dependent on the order
>>> in which reset handlers are called. In particular doing external
>>> side-effect (like setting an qemu_irq) is problematic because receiving
>>> object may not be reset yet.
>>>
>>> The Resettable interface divides the reset in 3 well defined phases.
>>> To reset an object tree, all 1st phases are executed then all 2nd then
>>> all 3rd. See the comments in include/hw/resettable.h for a more complete
>>> description. The interface defines 3 phases to let the future
>>> possibility of holding an object into reset for some time.
>>>
>>> The qdev/qbus reset in DeviceClass and BusClass will be modified in
>>> following commits to use this interface. A mechanism is provided
>>> to allow executing a transitional reset handler in place of the 2nd
>>> phase which is executed in children-then-parent order inside a tree.
>>> This will allow to transition devices and buses smoothly while
>>> keeping the exact current qdev/qbus reset behavior for now.
>>>
>>> Documentation will be added in a following commit.
>>>
>>> Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
>>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>
>>> v7 update: un-nest struct ResettablePhases
>>> ---
>>>    Makefile.objs           |   1 +
>>>    include/hw/resettable.h | 211 +++++++++++++++++++++++++++++++++++
>>>    hw/core/resettable.c    | 238 ++++++++++++++++++++++++++++++++++++++++
>>>    hw/core/Makefile.objs   |   1 +
>>>    hw/core/trace-events    |  17 +++
>>>    5 files changed, 468 insertions(+)
>>>    create mode 100644 include/hw/resettable.h
>>>    create mode 100644 hw/core/resettable.c
>>>
>>> diff --git a/Makefile.objs b/Makefile.objs
>>> index 7c1e50f9d6..9752d549b4 100644
>>> --- a/Makefile.objs
>>> +++ b/Makefile.objs
>>> @@ -191,6 +191,7 @@ trace-events-subdirs += migration
>>>    trace-events-subdirs += net
>>>    trace-events-subdirs += ui
>>>    endif
>>> +trace-events-subdirs += hw/core
>>>    trace-events-subdirs += hw/display
>>>    trace-events-subdirs += qapi
>>>    trace-events-subdirs += qom
>>> diff --git a/include/hw/resettable.h b/include/hw/resettable.h
>>> new file mode 100644
>>> index 0000000000..58b3df4c22
>>> --- /dev/null
>>> +++ b/include/hw/resettable.h
>>> @@ -0,0 +1,211 @@
>>> +/*
>>> + * Resettable interface header.
>>> + *
>>> + * Copyright (c) 2019 GreenSocs SAS
>>> + *
>>> + * Authors:
>>> + *   Damien Hedde
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL, version 2 or
>>> later.
>>> + * See the COPYING file in the top-level directory.
>>> + */
>>> +
>>> +#ifndef HW_RESETTABLE_H
>>> +#define HW_RESETTABLE_H
>>> +
>>> +#include "qom/object.h"
>>> +
>>> +#define TYPE_RESETTABLE_INTERFACE "resettable"
>>> +
>>> +#define RESETTABLE_CLASS(class) \
>>> +    OBJECT_CLASS_CHECK(ResettableClass, (class),
>>> TYPE_RESETTABLE_INTERFACE)
>>> +
>>> +#define RESETTABLE_GET_CLASS(obj) \
>>> +    OBJECT_GET_CLASS(ResettableClass, (obj), TYPE_RESETTABLE_INTERFACE)
>>> +
>>> +typedef struct ResettableState ResettableState;
>>> +
>>> +/**
>>> + * ResetType:
>>> + * Types of reset.
>>> + *
>>> + * + Cold: reset resulting from a power cycle of the object.
>>> + *
>>> + * TODO: Support has to be added to handle more types. In particular,
>>> + * ResettableState structure needs to be expanded.
>>> + */
>>> +typedef enum ResetType {
>>> +    RESET_TYPE_COLD,
>>> +} ResetType;
>>> +
>>> +/*
>>> + * ResettableClass:
>>> + * Interface for resettable objects.
>>> + *
>>> + * See docs/devel/reset.rst for more detailed information about how
>>> QEMU models
>>> + * reset. This whole API must only be used when holding the iothread
>>> mutex.
>>> + *
>>> + * All objects which can be reset must implement this interface;
>>> + * it is usually provided by a base class such as DeviceClass or
>>> BusClass.
>>> + * Every Resettable object must maintain some state tracking the
>>> + * progress of a reset operation by providing a ResettableState
>>> structure.
>>> + * The functions defined in this module take care of updating the
>>> + * state of the reset.
>>> + * The base class implementation of the interface provides this
>>> + * state and implements the associated method: get_state.
>>> + *
>>> + * Concrete object implementations (typically specific devices
>>> + * such as a UART model) should provide the functions
>>> + * for the phases.enter, phases.hold and phases.exit methods, which
>>> + * they can set in their class init function, either directly or
>>> + * by calling resettable_class_set_parent_phases().
>>> + * The phase methods are guaranteed to only only ever be called once
>>> + * for any reset event, in the order 'enter', 'hold', 'exit'.
>>> + * An object will always move quickly from 'enter' to 'hold'
>>> + * but might remain in 'hold' for an arbitrary period of time
>>> + * before eventually reset is deasserted and the 'exit' phase is called.
>>> + * Object implementations should be prepared for functions handling
>>> + * inbound connections from other devices (such as qemu_irq handler
>>> + * functions) to be called at any point during reset after their
>>> + * 'enter' method has been called.
>>> + *
>>> + * Users of a resettable object should not call these methods
>>> + * directly, but instead use the function resettable_reset().
>>> + *
>>> + * @phases.enter: This phase is called when the object enters reset. It
>>> + * should reset local state of the object, but it must not do
>>> anything that
>>> + * has a side-effect on other objects, such as raising or lowering a
>>> qemu_irq
>>> + * line or reading or writing guest memory. It takes the reset's type as
>>> + * argument.
>>> + *
>>> + * @phases.hold: This phase is called for entry into reset, once
>>> every object
>>> + * in the system which is being reset has had its @phases.enter
>>> method called.
>>> + * At this point devices can do actions that affect other objects.
>>> + *
>>> + * @phases.exit: This phase is called when the object leaves the
>>> reset state.
>>> + * Actions affecting other objects are permitted.
>>> + *
>>> + * @get_state: Mandatory method which must return a pointer to a
>>> + * ResettableState.
>>> + *
>>> + * @get_transitional_function: transitional method to handle
>>> Resettable objects
>>> + * not yet fully moved to this interface. It will be removed as soon
>>> as it is
>>> + * not needed anymore. This method is optional and may return a
>>> pointer to a
>>> + * function to be used instead of the phases. If the method exists
>>> and returns
>>> + * a non-NULL function pointer then that function is executed as a
>>> replacement
>>> + * of the 'hold' phase method taking the object as argument. The two
>>> other phase
>>> + * methods are not executed.
>>> + *
>>> + * @child_foreach: Executes a given callback on every Resettable
>>> child. Child
>>> + * in this context means a child in the qbus tree, so the children of
>>> a qbus
>>> + * are the devices on it, and the children of a device are all the
>>> buses it
>>> + * owns. This is not the same as the QOM object hierarchy. The
>>> function takes
>>> + * additional opaque and ResetType arguments which must be passed
>>> unmodified to
>>> + * the callback.
>>> + */
>>> +typedef void (*ResettableEnterPhase)(Object *obj, ResetType type);
>>> +typedef void (*ResettableHoldPhase)(Object *obj);
>>> +typedef void (*ResettableExitPhase)(Object *obj);
>>> +typedef ResettableState * (*ResettableGetState)(Object *obj);
>>> +typedef void (*ResettableTrFunction)(Object *obj);
>>> +typedef ResettableTrFunction (*ResettableGetTrFunction)(Object *obj);
>>> +typedef void (*ResettableChildCallback)(Object *, void *opaque,
>>> +                                        ResetType type);
>>> +typedef void (*ResettableChildForeach)(Object *obj,
>>> +                                       ResettableChildCallback cb,
>>> +                                       void *opaque, ResetType type);
>>> +typedef struct ResettablePhases {
>>> +    ResettableEnterPhase enter;
>>> +    ResettableHoldPhase hold;
>>> +    ResettableExitPhase exit;
>>> +} ResettablePhases;
>>> +typedef struct ResettableClass {
>>> +    InterfaceClass parent_class;
>>> +
>>> +    /* Phase methods */
>>> +    ResettablePhases phases;
>>> +
>>> +    /* State access method */
>>> +    ResettableGetState get_state;
>>> +
>>> +    /* Transitional method for legacy reset compatibility */
>>> +    ResettableGetTrFunction get_transitional_function;
>>> +
>>> +    /* Hierarchy handling method */
>>> +    ResettableChildForeach child_foreach;
>>> +} ResettableClass;
>>> +
>>> +/**
>>> + * ResettableState:
>>> + * Structure holding reset related state. The fields should not be
>>> accessed
>>> + * directly; the definition is here to allow further inclusion into
>>> other
>>> + * objects.
>>> + *
>>> + * @count: Number of reset level the object is into. It is
>>> incremented when
>>> + * the reset operation starts and decremented when it finishes.
>>
>> Maybe you can add this comment and the variable in patch 5/11, that
>> would make patch 5 easier to review.
> 
> The variable is used in this patch so I cannot do that.

Oops you are right o_O ...

>>
>>> + * @hold_phase_pending: flag which indicates that we need to invoke
>>> the 'hold'
>>> + * phase handler for this object.
>>> + * @exit_phase_in_progress: true if we are currently in the exit phase
>>> + */
>>> +struct ResettableState {
>>> +    uint32_t count;
>>
>> Maybe simply 'unsigned'?
>>
> 
> Ok.
> 
> --
> Damien



  reply	other threads:[~2020-01-20  9:19 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é [this message]
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 ` [PATCH v7 05/11] hw/core/resettable: add support for changing parent Damien Hedde
2020-01-18  6:45   ` 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=3f357f91-277c-1a6a-d007-2990ceac00c9@redhat.com \
    --to=philmd@redhat.com \
    --cc=berrange@redhat.com \
    --cc=cohuck@redhat.com \
    --cc=damien.hedde@greensocs.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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).