From: "Eduardo Habkost" <ehabkost@redhat.com>
To: Igor Mammedov <imammedo@redhat.com>
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>,
peter.maydell@linaro.org, mst@redhat.com, somlo@cmu.edu,
qemu-devel@nongnu.org, rjones@redhat.com, pbonzini@redhat.com,
lersek@redhat.com
Subject: Re: [Qemu-devel] [PATCHv7 5/6] fw_cfg: move qdev_init_nofail() from fw_cfg_init1() to callers
Date: Fri, 7 Jul 2017 12:07:07 -0300 [thread overview]
Message-ID: <20170707150707.GJ10776@localhost.localdomain> (raw)
In-Reply-To: <20170707164453.4ba325fd@nial.brq.redhat.com>
On Fri, Jul 07, 2017 at 04:44:53PM +0200, Igor Mammedov wrote:
[...]
> > > taking in account that fwcfg in not user creatable device how about:
> > >
> > > diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
> > > index 316fca9..8f6eef8 100644
> > > --- a/hw/nvram/fw_cfg.c
> > > +++ b/hw/nvram/fw_cfg.c
> > > @@ -1014,7 +1014,10 @@ FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr)
> > >
> > > FWCfgState *fw_cfg_find(void)
> > > {
> > > - return FW_CFG(object_resolve_path(FW_CFG_PATH, NULL));
> > > + bool ambig = false;
> > > + FWCfgState *f = FW_CFG(object_resolve_path_type("", TYPE_FW_CFG, &ambig));
> > > + assert(!ambig);
> > > + return f;
> > > }
> > >
> > > or if we must to print user friendly error and fail realize gracefully
> > > (not sure why) just add errp argument to function so it could report
> > > error back to caller, then places that do not care much about graceful
> > > exit would use error_abort as argument and realize would use
> > > its local_error/errp argument.
> >
> > My understanding from the thread was that we should only use assert()s
> > where there is no other choice so that any failures can be handled in a
> > more friendly manner.
> the rule I use to decide assert vs nice error handling:
> 1: try to avoid crash on hotplug path
> 2: if error could be induced by end user on startup, try to print nice error
> before dying
> 3: when error should not happen just assert or use error_abort
> which would print nice error message before dying.
I would add this to the list:
If returning error instead of aborting is easy, return an error
and let the caller decide if it should use &error_abort or not.
>
> > Now as Laszlo pointed out, fw_cfg_find() is used externally to locate
> > the fw_cfg device in other parts of the QEMU codebase. Yes I agree that
> > it is possible to change the way in which it returns, however I would
> > argue that changing those semantics are outside of the scope of this patch.
> I'd just kill qemu in fw_cfg case, which is small not intrusive change.
>
> [...]
>
> > >>>>
> > >>>> - assert(!fw_cfg_unattached_at_realize());
> > >>>> + if (fw_cfg_unattached_at_realize()) {
> > >>> as I pointed out in v6, this condition will always be false,
> > >>> I suggest to drop 4/6 patch and this hunk here so it won't to confuse
> > >>> readers with assumption that condition might succeed.
> > >>
> > >> Definitely look more closely at the fw_cfg_unattached_at_realize()
> > >> implementation in patch 4. You'll see that the check to determine if the
> > >> device is attached does not check obj->parent but checks to see if the
> > >> device exists under /machine/unattached which is what the
> > >> device_set_realised() does if the device doesn't have a parent.
> > >
> > > looking more fw_cfg_unattached_at_realize(),
> > > returns true if fwcfg is direct child of/machine/unattached
> > > meaning implicit parent assignment.
> > >
> > > As result, above condition essentially forbids having fwcfg under
> > > /machine/unattached and forces user to explicitly set parent
> > > outside of /machine/unattached or be a child of some other device.
> > >
> > > Is this your intent (why)?
> >
> > Yes that is entirely correct. All current fw_cfg users setup the device
> > using fw_cfg_init_io() and fw_cfg_init_mem() which is fine for those
> > cases because these functions attach the fw_cfg device directly to the
> > machine at /machine/fw_cfg. This makes it trivial to determine whether
> > or not an existing fw_cfg has been instantiated and prevent any more
> > instances, which Laszlo has stated is an underlying assumption for
> > fw_cfg_find().
> >
> > In my particular use case for SPARC64, I need to move the fw_cfg device
> > behind a PCI bridge. Therefore in order to allow the QOM tree to reflect
> > the actual hardware DT then the fw_cfg device needs to be attached to
> > the PCI bridge and not the machine. Hence the check for an existing
> > device at /machine/fw_cfg is no longer good enough to determine if a
> > fw_cfg device already exists since if they do, they can be in several
> > different locations in the QOM tree.
> >
> > This explains the change to fw_cfg_find() to make sure that we find any
> > other fw_cfg instances, no matter where they are in the QOM tree.
> without using ambiguous argument object_resolve_path_type() isn't
> returning NULL in case of duplicates in different leafs of tree.
This doesn't sound right. object_resolve_path_type() should
always return NULL if multiple matches are found. See its
documentation.
>
> for reason, see https://www.mail-archive.com/qemu-devel@nongnu.org/msg460692.html
> or look at object_resolve_partial_path() impl.
>
[...]
> > Finally for reference here is the current version of the code in my
> > outstanding sun4u patchset which wires up the fw_cfg device behind a PCI
> > bridge in hw/sparc64/sun4u:
> >
> > dev = qdev_create(NULL, TYPE_FW_CFG_IO);
> > qdev_prop_set_bit(dev, "dma_enabled", false);
> > object_property_add_child(OBJECT(ebus), TYPE_FW_CFG, OBJECT(dev),
> > NULL);
> > qdev_init_nofail(dev);
> > memory_region_add_subregion(pci_address_space_io(ebus),
> > BIOS_CFG_IOPORT,
> > &FW_CFG_IO(dev)->comb_iomem);
> looks fine,
>
> so what I'd do is:
> * drop 4/6
Agreed on this point. But:
> * make fw_cfg_find() use ambiguous argument and error_abort if ambiguous == true
> * from fw_cfg_common_realize() just call
>
> // if fw_cfg_find() returns NULL it means that device isn't in QOM tree
> // which shouldn't ever happen, fw_cfg_find() will abort itself if
> // another instance of device present in QOM tree.
> assert(fw_cfg_find());
That would work, but I don't see why doing that if just returning
NULL would: 1) make the code in fw_cfg_find() simpler and
shorter; 2) make realize error handling friendlier (returning
error instead of aborting). We just need to document that
explicitly in fw_cfg_find() (see find_vmgenid_dev() for an
example).
If you still want to make realize abort instead of returning
error, you don't even need assert(ambiguous) on fw_cfg_find().
All you need is this on realize:
assert(fw_cfg_find() == dev);
--
Eduardo
next prev parent reply other threads:[~2017-07-07 15:07 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-29 14:07 [Qemu-devel] [PATCHv7 0/6] fw_cfg: qdev-related tidy-ups Mark Cave-Ayland
2017-06-29 14:07 ` [Qemu-devel] [PATCHv7 1/6] fw_cfg: don't map the fw_cfg IO ports in fw_cfg_io_realize() Mark Cave-Ayland
2017-06-29 14:07 ` [Qemu-devel] [PATCHv7 2/6] fw_cfg: move setting of FW_CFG_VERSION_DMA bit to fw_cfg_init1() Mark Cave-Ayland
2017-06-29 14:07 ` [Qemu-devel] [PATCHv7 3/6] fw_cfg: switch fw_cfg_find() to locate the fw_cfg device by type rather than path Mark Cave-Ayland
2017-07-03 9:42 ` Igor Mammedov
2017-07-04 18:14 ` Mark Cave-Ayland
2017-06-29 14:07 ` [Qemu-devel] [PATCHv7 4/6] fw_cfg: add assert() to ensure the fw_cfg device has been added as a child property Mark Cave-Ayland
2017-06-29 14:07 ` [Qemu-devel] [PATCHv7 5/6] fw_cfg: move qdev_init_nofail() from fw_cfg_init1() to callers Mark Cave-Ayland
2017-07-03 9:39 ` Igor Mammedov
2017-07-04 18:08 ` Mark Cave-Ayland
2017-07-07 11:33 ` Igor Mammedov
2017-07-07 13:12 ` Mark Cave-Ayland
2017-07-07 13:26 ` Eduardo Habkost
2017-07-07 13:54 ` Mark Cave-Ayland
2017-07-07 14:48 ` Eduardo Habkost
2017-07-07 16:16 ` Mark Cave-Ayland
2017-07-07 14:44 ` Igor Mammedov
2017-07-07 14:50 ` Eduardo Habkost
2017-07-07 15:07 ` Eduardo Habkost [this message]
2017-07-07 16:20 ` Mark Cave-Ayland
2017-07-10 8:01 ` Igor Mammedov
2017-07-10 14:53 ` Eduardo Habkost
2017-07-10 15:23 ` Igor Mammedov
2017-07-10 17:38 ` Eduardo Habkost
2017-07-11 18:05 ` Mark Cave-Ayland
2017-07-10 7:49 ` Igor Mammedov
2017-07-10 14:51 ` Eduardo Habkost
2017-07-07 13:13 ` Eduardo Habkost
2017-07-07 14:58 ` Igor Mammedov
2017-07-07 15:09 ` Eduardo Habkost
2017-07-07 18:18 ` Igor Mammedov
2017-07-07 19:30 ` Eduardo Habkost
2017-07-07 19:54 ` Eduardo Habkost
2017-07-07 20:03 ` Laszlo Ersek
2017-07-07 16:13 ` Mark Cave-Ayland
2017-06-29 14:07 ` [Qemu-devel] [PATCHv7 6/6] fw_cfg: move QOM type defines and fw_cfg types into fw_cfg.h Mark Cave-Ayland
2017-06-29 15:32 ` [Qemu-devel] [PATCHv7 0/6] fw_cfg: qdev-related tidy-ups Gabriel L. Somlo
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=20170707150707.GJ10776@localhost.localdomain \
--to=ehabkost@redhat.com \
--cc=imammedo@redhat.com \
--cc=lersek@redhat.com \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rjones@redhat.com \
--cc=somlo@cmu.edu \
/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).