All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Cc: "fam@euphon.net" <fam@euphon.net>,
	"peter.maydell@linaro.org" <peter.maydell@linaro.org>,
	"mst@redhat.com" <mst@redhat.com>,
	"codyprime@gmail.com" <codyprime@gmail.com>,
	"mark.cave-ayland@ilande.co.uk" <mark.cave-ayland@ilande.co.uk>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	"armbru@redhat.com" <armbru@redhat.com>,
	"kraxel@redhat.com" <kraxel@redhat.com>,
	"mreitz@redhat.com" <mreitz@redhat.com>,
	Eric Blake <eblake@redhat.com>,
	"qemu-block@nongnu.org" <qemu-block@nongnu.org>,
	"quintela@redhat.com" <quintela@redhat.com>,
	"david@redhat.com" <david@redhat.com>,
	"mdroth@linux.vnet.ibm.com" <mdroth@linux.vnet.ibm.com>,
	"pasic@linux.ibm.com" <pasic@linux.ibm.com>,
	"borntraeger@de.ibm.com" <borntraeger@de.ibm.com>,
	"marcandre.lureau@redhat.com" <marcandre.lureau@redhat.com>,
	"rth@twiddle.net" <rth@twiddle.net>,
	"farman@linux.ibm.com" <farman@linux.ibm.com>,
	"groug@kaod.org" <groug@kaod.org>,
	"dgilbert@redhat.com" <dgilbert@redhat.com>,
	"alex.williamson@redhat.com" <alex.williamson@redhat.com>,
	"qemu-arm@nongnu.org" <qemu-arm@nongnu.org>,
	"stefanha@redhat.com" <stefanha@redhat.com>,
	"jsnow@redhat.com" <jsnow@redhat.com>,
	"david@gibson.dropbear.id.au" <david@gibson.dropbear.id.au>,
	"berrange@redhat.com" <berrange@redhat.com>,
	"cohuck@redhat.com" <cohuck@redhat.com>,
	"qemu-s390x@nongnu.org" <qemu-s390x@nongnu.org>,
	"sundeep.lkml@gmail.com" <sundeep.lkml@gmail.com>,
	"qemu-ppc@nongnu.org" <qemu-ppc@nongnu.org>,
	"pbonzini@redhat.com" <pbonzini@redhat.com>
Subject: Re: [Qemu-arm] [RFC] error: auto propagated local_err
Date: Thu, 19 Sep 2019 16:34:41 +0200	[thread overview]
Message-ID: <20190919143441.GH10163@localhost.localdomain> (raw)
In-Reply-To: <35c972e1-bdb5-cbcb-ed45-6a51f19af98c@virtuozzo.com>

Am 19.09.2019 um 16:13 hat Vladimir Sementsov-Ogievskiy geschrieben:
> 19.09.2019 16:40, Eric Blake wrote:
> > On 9/19/19 4:17 AM, Kevin Wolf wrote:
> >> Am 18.09.2019 um 19:10 hat Eric Blake geschrieben:
> >>> On 9/18/19 8:02 AM, Vladimir Sementsov-Ogievskiy wrote:
> >>>> + */
> >>>> +#define MAKE_ERRP_SAFE(errp) \
> >>>> +g_auto(ErrorPropagationStruct) (__auto_errp_prop) = {.errp = (errp)}; \
> >>>> +if ((errp) == NULL || *(errp) == error_abort || *(errp) == error_fatal) { \
> >>>> +    (errp) = &__auto_errp_prop.local_err; \
> >>>> +}
> >>>
> >>> Not written to take a trailing semicolon in the caller.
> >>>
> >>> You could even set __auto_errp_prop unconditionally rather than trying
> >>> to reuse incoming errp (the difference being that error_propagate() gets
> >>> called more frequently).
> >>
> >> I think this difference is actually a problem.
> >>
> >> When debugging things, I hate error_propagate(). It means that the Error
> >> (specifically its fields src/func/line) points to the outermost
> >> error_propagate() rather than the place where the error really happened.
> >> It also makes error_abort completely useless because at the point where
> >> the process gets aborted, the interesting information is already lost.
> > 
> > Okay, based on that, I see the following desirable semantics:
> > 
> > Caller: one of 4 calling paradigms:
> > 
> > pass errp=NULL (we don't care about failures)
> > pass errp=&error_abort (we want to abort() as soon as possible as close
> > to the real problem as possible)
> > pass errp=&error_fatal (we want to exit(), but only after collecting as
> > much information as possible)
> > pass errp = anything else (we are collecting an error for other reasons,
> > we may report it or let the caller decide or ...)
> > 
> > Callee: we want a SINGLE paradigm:
> > 
> > func (Error **errp)
> > {
> >      MAKE_ERRP_SAFE();
> > 
> >      now we can pass errp to any child function, test '*errp', or do
> > anything else, and we DON'T have to call error_propagate.
> > 
> > I think that means we need:
> > 
> > #define MAKE_ERRP_SAFE() \
> >    g_auto(...) __auto_errp = { .errp = errp }; \
> >    do { \
> >      if (!errp || errp == &error_fatal) { errp = &__auto_errp.local; } \
> >    } while (0)
> > 
> > So back to the caller semantics:
> > 
> > if the caller passed NULL, we've redirected errp locally so that we can
> > use *errp at will; the auto-cleanup will free our local error.
> > 
> > if the caller passed &error_abort, we keep errp unchanged.  *errp tests
> > will never trigger, because we'll have already aborted in the child on
> > the original errp, giving developers the best stack trace.
> > 
> > if the caller passed &error_fatal, we redirect errp.  auto-cleanup will
> > then error_propagate that back to the caller, producing as much nice
> > information as possible.
> > 
> > if the caller passed anything else, we keep errp unchanged, so no extra
> > error_propagate in the mix.
> > 
> >>
> >> So I'd really like to restrict the use of error_propagate() to places
> >> where it's absolutely necessary. Unless, of course, you can fix these
> >> practical problems that error_propagate() causes for debugging.
> >>
> >> In fact, in the context of Greg's series, I think we really only need to
> >> support hints for error_fatal, which are cases that users are supposed
> >> to see. We should exclude error_abort in MAKE_ERRP_SAFE() because these
> >> are things that are never supposed to happen. A good stack trace is more
> >> important there than adding a hint to the message.
> > 
> > We also want to handle the caller passing NULL, so that we no longer
> > have to introduce 'Error *local_error = NULL' everywhere.
> > 
> 
> With my plan of two different macro, I at least messed the case when we need
> both dereferencing and hints, which means third macro, or one macro with parameters,
> saying what to wrap.
> 
> And my aim was to follow the idea of "do propagation only if it really necessary in this case".
> 
> But may be you are right, and we shouldn't care so much.
> 
> 1. What is bad, if we wrap NULL, when we only want to use hints?
> Seems nothing. Some extra actions on error path, but who cares about it?
> 
> 2. What is bad, if we wrap error_fatal, when we only want to dereference, and don't use hints?
> Seems nothing again, on error path we will return from higher level, and a bit of extra work, but nothing worse..
> 
> So I tend to agree. But honestly, I didn't understand first part of Kevin's paragraph against propagation,
> so, may be he have more reasons to minimize number of cases when we propagate.

I think my concerns were really only about error_abort and "normal"
non-NULL errp losing some information about the origin of the error. And
from this thread, it seems that I misremebered and the normal one is
actually supposed to just work.

In any case, wrapping NULL and error_fatal should be fine, so I agree
that a single macro should do.

> To the same topic, of minimization: should we always call MAKE_ERRP_SAFE at function top, or only
> in block, where it is needed (assume, we dereference it only inside some "if" or "while"?

Hm, I think it's more obviously correct if done at the top, but I also
can't see any reason why using it only in a block wouldn't work. So I'd
put it at the top just as a matter of style.

> Kevin, is something bad in propagation, when it not related to error_abort?

Probably not, unless I didn't misremember, but we misread the code.

Kevin

WARNING: multiple messages have this Message-ID (diff)
From: Kevin Wolf <kwolf@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Cc: "fam@euphon.net" <fam@euphon.net>,
	"peter.maydell@linaro.org" <peter.maydell@linaro.org>,
	"mst@redhat.com" <mst@redhat.com>,
	"codyprime@gmail.com" <codyprime@gmail.com>,
	"mark.cave-ayland@ilande.co.uk" <mark.cave-ayland@ilande.co.uk>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	"armbru@redhat.com" <armbru@redhat.com>,
	"kraxel@redhat.com" <kraxel@redhat.com>,
	"mreitz@redhat.com" <mreitz@redhat.com>,
	"qemu-block@nongnu.org" <qemu-block@nongnu.org>,
	"quintela@redhat.com" <quintela@redhat.com>,
	"david@redhat.com" <david@redhat.com>,
	"mdroth@linux.vnet.ibm.com" <mdroth@linux.vnet.ibm.com>,
	"pasic@linux.ibm.com" <pasic@linux.ibm.com>,
	"borntraeger@de.ibm.com" <borntraeger@de.ibm.com>,
	"marcandre.lureau@redhat.com" <marcandre.lureau@redhat.com>,
	"rth@twiddle.net" <rth@twiddle.net>,
	"farman@linux.ibm.com" <farman@linux.ibm.com>,
	"groug@kaod.org" <groug@kaod.org>,
	"dgilbert@redhat.com" <dgilbert@redhat.com>,
	"alex.williamson@redhat.com" <alex.williamson@redhat.com>,
	"qemu-arm@nongnu.org" <qemu-arm@nongnu.org>,
	"stefanha@redhat.com" <stefanha@redhat.com>,
	"jsnow@redhat.com" <jsnow@redhat.com>,
	"david@gibson.dropbear.id.au" <david@gibson.dropbear.id.au>,
	"berrange@redhat.com" <berrange@redhat.com>,
	"cohuck@redhat.com" <cohuck@redhat.com>,
	"qemu-s390x@nongnu.org" <qemu-s390x@nongnu.org>,
	"sundeep.lkml@gmail.com" <sundeep.lkml@gmail.com>,
	"qemu-ppc@nongnu.org" <qemu-ppc@nongnu.org>,
	"pbonzini@redhat.com" <pbonzini@redhat.com>
Subject: Re: [RFC] error: auto propagated local_err
Date: Thu, 19 Sep 2019 16:34:41 +0200	[thread overview]
Message-ID: <20190919143441.GH10163@localhost.localdomain> (raw)
In-Reply-To: <35c972e1-bdb5-cbcb-ed45-6a51f19af98c@virtuozzo.com>

Am 19.09.2019 um 16:13 hat Vladimir Sementsov-Ogievskiy geschrieben:
> 19.09.2019 16:40, Eric Blake wrote:
> > On 9/19/19 4:17 AM, Kevin Wolf wrote:
> >> Am 18.09.2019 um 19:10 hat Eric Blake geschrieben:
> >>> On 9/18/19 8:02 AM, Vladimir Sementsov-Ogievskiy wrote:
> >>>> + */
> >>>> +#define MAKE_ERRP_SAFE(errp) \
> >>>> +g_auto(ErrorPropagationStruct) (__auto_errp_prop) = {.errp = (errp)}; \
> >>>> +if ((errp) == NULL || *(errp) == error_abort || *(errp) == error_fatal) { \
> >>>> +    (errp) = &__auto_errp_prop.local_err; \
> >>>> +}
> >>>
> >>> Not written to take a trailing semicolon in the caller.
> >>>
> >>> You could even set __auto_errp_prop unconditionally rather than trying
> >>> to reuse incoming errp (the difference being that error_propagate() gets
> >>> called more frequently).
> >>
> >> I think this difference is actually a problem.
> >>
> >> When debugging things, I hate error_propagate(). It means that the Error
> >> (specifically its fields src/func/line) points to the outermost
> >> error_propagate() rather than the place where the error really happened.
> >> It also makes error_abort completely useless because at the point where
> >> the process gets aborted, the interesting information is already lost.
> > 
> > Okay, based on that, I see the following desirable semantics:
> > 
> > Caller: one of 4 calling paradigms:
> > 
> > pass errp=NULL (we don't care about failures)
> > pass errp=&error_abort (we want to abort() as soon as possible as close
> > to the real problem as possible)
> > pass errp=&error_fatal (we want to exit(), but only after collecting as
> > much information as possible)
> > pass errp = anything else (we are collecting an error for other reasons,
> > we may report it or let the caller decide or ...)
> > 
> > Callee: we want a SINGLE paradigm:
> > 
> > func (Error **errp)
> > {
> >      MAKE_ERRP_SAFE();
> > 
> >      now we can pass errp to any child function, test '*errp', or do
> > anything else, and we DON'T have to call error_propagate.
> > 
> > I think that means we need:
> > 
> > #define MAKE_ERRP_SAFE() \
> >    g_auto(...) __auto_errp = { .errp = errp }; \
> >    do { \
> >      if (!errp || errp == &error_fatal) { errp = &__auto_errp.local; } \
> >    } while (0)
> > 
> > So back to the caller semantics:
> > 
> > if the caller passed NULL, we've redirected errp locally so that we can
> > use *errp at will; the auto-cleanup will free our local error.
> > 
> > if the caller passed &error_abort, we keep errp unchanged.  *errp tests
> > will never trigger, because we'll have already aborted in the child on
> > the original errp, giving developers the best stack trace.
> > 
> > if the caller passed &error_fatal, we redirect errp.  auto-cleanup will
> > then error_propagate that back to the caller, producing as much nice
> > information as possible.
> > 
> > if the caller passed anything else, we keep errp unchanged, so no extra
> > error_propagate in the mix.
> > 
> >>
> >> So I'd really like to restrict the use of error_propagate() to places
> >> where it's absolutely necessary. Unless, of course, you can fix these
> >> practical problems that error_propagate() causes for debugging.
> >>
> >> In fact, in the context of Greg's series, I think we really only need to
> >> support hints for error_fatal, which are cases that users are supposed
> >> to see. We should exclude error_abort in MAKE_ERRP_SAFE() because these
> >> are things that are never supposed to happen. A good stack trace is more
> >> important there than adding a hint to the message.
> > 
> > We also want to handle the caller passing NULL, so that we no longer
> > have to introduce 'Error *local_error = NULL' everywhere.
> > 
> 
> With my plan of two different macro, I at least messed the case when we need
> both dereferencing and hints, which means third macro, or one macro with parameters,
> saying what to wrap.
> 
> And my aim was to follow the idea of "do propagation only if it really necessary in this case".
> 
> But may be you are right, and we shouldn't care so much.
> 
> 1. What is bad, if we wrap NULL, when we only want to use hints?
> Seems nothing. Some extra actions on error path, but who cares about it?
> 
> 2. What is bad, if we wrap error_fatal, when we only want to dereference, and don't use hints?
> Seems nothing again, on error path we will return from higher level, and a bit of extra work, but nothing worse..
> 
> So I tend to agree. But honestly, I didn't understand first part of Kevin's paragraph against propagation,
> so, may be he have more reasons to minimize number of cases when we propagate.

I think my concerns were really only about error_abort and "normal"
non-NULL errp losing some information about the origin of the error. And
from this thread, it seems that I misremebered and the normal one is
actually supposed to just work.

In any case, wrapping NULL and error_fatal should be fine, so I agree
that a single macro should do.

> To the same topic, of minimization: should we always call MAKE_ERRP_SAFE at function top, or only
> in block, where it is needed (assume, we dereference it only inside some "if" or "while"?

Hm, I think it's more obviously correct if done at the top, but I also
can't see any reason why using it only in a block wouldn't work. So I'd
put it at the top just as a matter of style.

> Kevin, is something bad in propagation, when it not related to error_abort?

Probably not, unless I didn't misremember, but we misread the code.

Kevin


  parent reply	other threads:[~2019-09-19 14:46 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-18 13:02 [Qemu-arm] [RFC] error: auto propagated local_err Vladimir Sementsov-Ogievskiy
2019-09-18 13:02 ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-18 17:10 ` Eric Blake
2019-09-18 17:46   ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-18 17:46     ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-18 18:05     ` Eric Blake
2019-09-18 18:32       ` [Qemu-arm] " Eric Blake
2019-09-18 18:32         ` [Qemu-devel] " Eric Blake
2019-09-19  6:47         ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19  6:47           ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19 13:29           ` [Qemu-arm] " Eric Blake
2019-09-19 13:29             ` [Qemu-devel] " Eric Blake
2019-09-19  9:17   ` [Qemu-arm] " Kevin Wolf
2019-09-19  9:17     ` [Qemu-devel] " Kevin Wolf
2019-09-19  9:47     ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19  9:47       ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19 10:09     ` Daniel P. Berrangé
2019-09-19 10:21       ` Vladimir Sementsov-Ogievskiy
2019-09-19 11:55         ` [Qemu-arm] " Daniel P. Berrangé
2019-09-19 11:55           ` Daniel P. Berrangé
2019-09-19 12:00     ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19 12:00       ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19 13:03       ` [Qemu-arm] " Kevin Wolf
2019-09-19 13:03         ` [Qemu-devel] " Kevin Wolf
2019-09-19 13:17         ` Vladimir Sementsov-Ogievskiy
2019-09-19 13:44         ` Eric Blake
2019-09-19 13:40     ` [Qemu-arm] " Eric Blake
2019-09-19 13:40       ` [Qemu-devel] " Eric Blake
2019-09-19 14:13       ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19 14:13         ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19 14:26         ` [Qemu-arm] " Eric Blake
2019-09-19 14:26           ` Eric Blake
2019-09-19 14:30         ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19 14:30           ` Vladimir Sementsov-Ogievskiy
2019-09-19 14:44           ` [Qemu-arm] " Eric Blake
2019-09-19 14:44             ` Eric Blake
2019-09-19 14:49             ` [Qemu-arm] " Daniel P. Berrangé
2019-09-19 14:49               ` Daniel P. Berrangé
2019-09-19 15:24               ` Eric Blake
2019-09-19 15:37                 ` Vladimir Sementsov-Ogievskiy
2019-09-19 15:50                 ` Daniel P. Berrangé
2019-09-19 16:16                   ` Vladimir Sementsov-Ogievskiy
2019-09-19 16:51                     ` Daniel P. Berrangé
2019-09-19 16:51                       ` Daniel P. Berrangé
2019-09-20 12:58                   ` Eric Blake
2019-09-19 15:12             ` Vladimir Sementsov-Ogievskiy
2019-09-19 14:34         ` Kevin Wolf [this message]
2019-09-19 14:34           ` Kevin Wolf
2019-09-19  1:54 ` [Qemu-arm] [Qemu-devel] " no-reply
2019-09-19  1:54   ` no-reply
2019-09-19  7:32 ` [Qemu-arm] " David Hildenbrand
2019-09-19  7:32   ` [Qemu-devel] " David Hildenbrand
2019-09-19  7:41   ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19  7:41     ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19  7:53     ` [Qemu-arm] " David Hildenbrand
2019-09-19  7:53       ` [Qemu-devel] " David Hildenbrand
2019-09-19  8:20       ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19  8:20         ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19  8:23         ` [Qemu-arm] " David Hildenbrand
2019-09-19  8:23           ` [Qemu-devel] " David Hildenbrand
2019-09-19  8:59 ` [Qemu-arm] " Greg Kurz
2019-09-19  8:59   ` [Qemu-devel] " Greg Kurz
2019-09-19  9:28   ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19  9:28     ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19 10:08     ` Greg Kurz
2019-09-19  8:59 ` Max Reitz
2019-09-19  9:14   ` [Qemu-arm] " Vladimir Sementsov-Ogievskiy
2019-09-19  9:14     ` [Qemu-devel] " Vladimir Sementsov-Ogievskiy
2019-09-19  9:33     ` [Qemu-arm] " Max Reitz
2019-09-19  9:33       ` [Qemu-devel] " Max Reitz
2019-09-19 10:03       ` Vladimir Sementsov-Ogievskiy
2019-09-19 11:52         ` [Qemu-arm] " Max Reitz
2019-09-19 11:52           ` [Qemu-devel] " Max Reitz
2019-09-20 11:46 ` Vladimir Sementsov-Ogievskiy
2019-09-20 11:46   ` Vladimir Sementsov-Ogievskiy

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=20190919143441.GH10163@localhost.localdomain \
    --to=kwolf@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=borntraeger@de.ibm.com \
    --cc=codyprime@gmail.com \
    --cc=cohuck@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=david@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=eblake@redhat.com \
    --cc=fam@euphon.net \
    --cc=farman@linux.ibm.com \
    --cc=groug@kaod.org \
    --cc=jsnow@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=mreitz@redhat.com \
    --cc=mst@redhat.com \
    --cc=pasic@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=rth@twiddle.net \
    --cc=stefanha@redhat.com \
    --cc=sundeep.lkml@gmail.com \
    --cc=vsementsov@virtuozzo.com \
    /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.