* [PATCH] Illustration of warning explosion silliness
@ 2006-09-28 0:58 Jeff Garzik
2006-09-28 1:35 ` Andrew Morton
0 siblings, 1 reply; 12+ messages in thread
From: Jeff Garzik @ 2006-09-28 0:58 UTC (permalink / raw)
To: linux-scsi, Andrew Morton, Greg KH; +Cc: LKML
The following patch (DO NOT APPLY) illustrates why
device_for_each_child() should not be marked with __must_check.
The function returns the return value of the actor function, and ceases
iteration upon error.
However, _every_ case in drivers/scsi has a hardcoded return value,
illustrating how it is quite valid to not check the return value of this
function.
Not-signed-off-by: Jeff Garzik <jeff@garzik.org>
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index d6743b9..4816c42 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2166,11 +2166,13 @@ target_block(struct device *dev, void *d
void
scsi_target_block(struct device *dev)
{
+ int dummy;
+
if (scsi_is_target_device(dev))
starget_for_each_device(to_scsi_target(dev), NULL,
device_block);
else
- device_for_each_child(dev, NULL, target_block);
+ dummy = device_for_each_child(dev, NULL, target_block);
}
EXPORT_SYMBOL_GPL(scsi_target_block);
@@ -2192,11 +2194,13 @@ target_unblock(struct device *dev, void
void
scsi_target_unblock(struct device *dev)
{
+ int dummy;
+
if (scsi_is_target_device(dev))
starget_for_each_device(to_scsi_target(dev), NULL,
device_unblock);
else
- device_for_each_child(dev, NULL, target_unblock);
+ dummy = device_for_each_child(dev, NULL, target_unblock);
}
EXPORT_SYMBOL_GPL(scsi_target_unblock);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index e7fe565..520ec13 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -803,6 +803,7 @@ static int __remove_child (struct device
void scsi_remove_target(struct device *dev)
{
struct device *rdev;
+ int dummy;
if (scsi_is_target_device(dev)) {
__scsi_remove_target(to_scsi_target(dev));
@@ -810,7 +811,7 @@ void scsi_remove_target(struct device *d
}
rdev = get_device(dev);
- device_for_each_child(dev, NULL, __remove_child);
+ dummy = device_for_each_child(dev, NULL, __remove_child);
put_device(rdev);
}
EXPORT_SYMBOL(scsi_remove_target);
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index b5b0c2c..4370244 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -211,8 +211,10 @@ static int do_sas_phy_delete(struct devi
*/
void sas_remove_children(struct device *dev)
{
- device_for_each_child(dev, (void *)0, do_sas_phy_delete);
- device_for_each_child(dev, (void *)1, do_sas_phy_delete);
+ int dummy;
+
+ dummy = device_for_each_child(dev, (void *)0, do_sas_phy_delete);
+ dummy = device_for_each_child(dev, (void *)1, do_sas_phy_delete);
}
EXPORT_SYMBOL(sas_remove_children);
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 9f070f0..6cc79e5 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -372,8 +372,9 @@ static ssize_t
store_spi_revalidate(struct class_device *cdev, const char *buf, size_t count)
{
struct scsi_target *starget = transport_class_to_starget(cdev);
+ int dummy;
- device_for_each_child(&starget->dev, NULL, child_iter);
+ dummy = device_for_each_child(&starget->dev, NULL, child_iter);
return count;
}
static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 0:58 [PATCH] Illustration of warning explosion silliness Jeff Garzik
@ 2006-09-28 1:35 ` Andrew Morton
2006-09-28 1:48 ` Jeff Garzik
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Morton @ 2006-09-28 1:35 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-scsi, Greg KH, LKML
On Wed, 27 Sep 2006 20:58:30 -0400
Jeff Garzik <jeff@garzik.org> wrote:
> The following patch (DO NOT APPLY) illustrates why
> device_for_each_child() should not be marked with __must_check.
>
> The function returns the return value of the actor function, and ceases
> iteration upon error.
>
> However, _every_ case in drivers/scsi has a hardcoded return value,
> illustrating how it is quite valid to not check the return value of this
> function.
>
What does "has a hardcoded return value" mean?
AFICT the problem here is that (for example) (going up the call stack in
the callee->caller direction):
scsi_internal_device_block() returns an error code
but device_block() drops that on the floor
so target_block() drops it on the floor too
so scsi_target_block() drops it on the floor too
It's a small matter of (correct kernel) programming to correctly propagate
the scsi_internal_device_block() error code all the way back out of
scsi_target_block().
It all looks rather sloppy?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 1:35 ` Andrew Morton
@ 2006-09-28 1:48 ` Jeff Garzik
2006-09-28 3:34 ` Andrew Morton
0 siblings, 1 reply; 12+ messages in thread
From: Jeff Garzik @ 2006-09-28 1:48 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
Andrew Morton wrote:
> On Wed, 27 Sep 2006 20:58:30 -0400
> Jeff Garzik <jeff@garzik.org> wrote:
>
>> The following patch (DO NOT APPLY) illustrates why
>> device_for_each_child() should not be marked with __must_check.
>>
>> The function returns the return value of the actor function, and ceases
>> iteration upon error.
>>
>> However, _every_ case in drivers/scsi has a hardcoded return value,
>> illustrating how it is quite valid to not check the return value of this
>> function.
>>
>
> What does "has a hardcoded return value" mean?
Reference the sentence before that. The return value of the actor
passed to device_for_each_child() is always either zero (for some
actors) or one (for another actor). In all cases, it is never variable.
> AFICT the problem here is that (for example) (going up the call stack in
> the callee->caller direction):
>
> scsi_internal_device_block() returns an error code
>
> but device_block() drops that on the floor
>
> so target_block() drops it on the floor too
>
> so scsi_target_block() drops it on the floor too
>
>
> It's a small matter of (correct kernel) programming to correctly propagate
> the scsi_internal_device_block() error code all the way back out of
> scsi_target_block().
>
> It all looks rather sloppy?
Quite sloppy. But that doesn't change the fact that
device_for_each_child()'s actor _may_ hardcode the return value. It's a
valid usage model for that function.
If you are doing a simple collection of data -- adding items to a
preallocating list or bitmap -- or doing a search, as with
__remove_child() in drivers/scsi/scsi_sysfs.c, the return value can be
quite useless.
The usage model should not be _forced_ upon the caller, since it might
not be needed.
Jeff
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 1:48 ` Jeff Garzik
@ 2006-09-28 3:34 ` Andrew Morton
2006-09-28 4:19 ` Jeff Garzik
2006-09-28 23:18 ` Jeff Garzik
0 siblings, 2 replies; 12+ messages in thread
From: Andrew Morton @ 2006-09-28 3:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
On Wed, 27 Sep 2006 21:48:42 -0400
Jeff Garzik <jeff@garzik.org> wrote:
> The usage model should not be _forced_ upon the caller, since it might
> not be needed.
IMO: tough titty.
This isn't some random crappy perl script. Nor is it even some random
crappy sound card driver. This is our scsi stack. The heart of our
MissionCriticalEnterpriseReadyCoreOfAThirtyBillionDollarIndustry operating
system. Picture yourself telling a Fortune 100 CTO why his kernel is
cheerily discarding errors (and hence his reliability and possibly data)
all over the place. Take a peek at spi_dv_device() and its callees...
I was astonished at the number of ignored errors all over the
sysfs/driver-model code. And that's only there to detect programming
errors. That's nothing compared to these bugs.
Discarding already-detected hardware or software errors in the storage
stack is toe-curlingly lame, and completely trumps the inconvenience of
developers seeing a few warnings, or having to put artificial warning
shutter-uppers in a few places.
Now I'm sure I'm about to be flooded with long-winded explanations about
why all of this can never happen. But y'know what? I don't care.
Hardware errors can sometimes happen. As can programming errors, as can
memory-corruption and dropped-bit errors and all the other things we
regularly see. The kernel should be robust in the presence of unexpected
events. *Particularly* those parts which are handling storage. Any
void-returning function in a driver or a mid-layer is a huge red flag.
And it's not sufficient to say "gee, I can't think of any reason why this
handler would return an error, so I'll design its callers to assume that".
It is _much_ better to design the callers to assume that callees _can_
fail, and to stick the `return 0;' into the terminal callee. Because
things can change.
There, I feel better now. If you want to see the other warnings, set
CONFIG_ENABLE_MUST_CHECK=n.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 3:34 ` Andrew Morton
@ 2006-09-28 4:19 ` Jeff Garzik
2006-09-28 4:36 ` Andrew Morton
2006-09-28 23:18 ` Jeff Garzik
1 sibling, 1 reply; 12+ messages in thread
From: Jeff Garzik @ 2006-09-28 4:19 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
Andrew Morton wrote:
> And it's not sufficient to say "gee, I can't think of any reason why this
> handler would return an error, so I'll design its callers to assume that".
> It is _much_ better to design the callers to assume that callees _can_
> fail, and to stick the `return 0;' into the terminal callee. Because
> things can change.
huh? You're going off on a tangent. I agree with the above, just like
I already agreed that SCSI needs better error checking.
You're ignoring the API issue at hand. Let me say it again for the
cheap seats: "search" You search a list, and stick a pointer somewhere
when found. No hardware touched. No allocations. Real world. There
is an example of usage in the kernel today.
Yes, SCSI needs better error checking. Yes, device_for_each_child()
actors _may_ return errors. No, that doesn't imply
device_for_each_child() actors must be FORCED BY DESIGN to return error
codes. It's just walking a list. The current implementation and API is
fine... save for the "__must_check" marker itself. The actor CAN return
an error code via the current API.
CAN, not MUST. (using RFC language)
Jeff
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 4:19 ` Jeff Garzik
@ 2006-09-28 4:36 ` Andrew Morton
2006-09-28 4:42 ` Jeff Garzik
2006-09-28 4:44 ` Andrew Morton
0 siblings, 2 replies; 12+ messages in thread
From: Andrew Morton @ 2006-09-28 4:36 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
On Thu, 28 Sep 2006 00:19:36 -0400
Jeff Garzik <jeff@garzik.org> wrote:
> Andrew Morton wrote:
> > And it's not sufficient to say "gee, I can't think of any reason why this
> > handler would return an error, so I'll design its callers to assume that".
> > It is _much_ better to design the callers to assume that callees _can_
> > fail, and to stick the `return 0;' into the terminal callee. Because
> > things can change.
>
> huh? You're going off on a tangent. I agree with the above, just like
> I already agreed that SCSI needs better error checking.
No I'm not. I'm saying that the bugs which this exposed are a far, far
more serious matter than a few false-positive warnings which need
workarounds.
> You're ignoring the API issue at hand. Let me say it again for the
> cheap seats: "search" You search a list, and stick a pointer somewhere
> when found. No hardware touched. No allocations. Real world. There
> is an example of usage in the kernel today.
If it's called in that fashion then the caller should still check the
device_for_each_child() return value to find out if it actually got a
match.
Now it could be that the mysterious caller to which you refer uses the
non-NULLness of some pointer to work out if a match occurred. Well shrug -
add a BUG_ON(!device_for_each_child_return_value) or something.
Or write a new version of device_for_each_child() which returns void and
don't tell anyone about it.
But let's not encourage error-ignoring.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 4:36 ` Andrew Morton
@ 2006-09-28 4:42 ` Jeff Garzik
2006-09-28 4:47 ` Andrew Morton
2006-09-28 4:44 ` Andrew Morton
1 sibling, 1 reply; 12+ messages in thread
From: Jeff Garzik @ 2006-09-28 4:42 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
Andrew Morton wrote:
>> You're ignoring the API issue at hand. Let me say it again for the
>> cheap seats: "search" You search a list, and stick a pointer somewhere
>> when found. No hardware touched. No allocations. Real world. There
>> is an example of usage in the kernel today.
>
> If it's called in that fashion then the caller should still check the
> device_for_each_child() return value to find out if it actually got a
> match.
Or in the case of scsi_sysfs.c, it simply <does something>.
Oh well, whatever. This thing introduces endless build noise we won't
kill for years, making it much harder to spot much more serious stuff.
Jeff
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 4:36 ` Andrew Morton
2006-09-28 4:42 ` Jeff Garzik
@ 2006-09-28 4:44 ` Andrew Morton
2006-09-28 4:54 ` Jeff Garzik
1 sibling, 1 reply; 12+ messages in thread
From: Andrew Morton @ 2006-09-28 4:44 UTC (permalink / raw)
To: Jeff Garzik, linux-scsi, Greg KH, LKML, Linus Torvalds
On Wed, 27 Sep 2006 21:36:28 -0700
Andrew Morton <akpm@osdl.org> wrote:
> device_for_each_child()
All that being said, device_for_each_child() is rather broken by design.
It walks a list of items applying a function to them and bales out on
first-error.
There's no way in which the caller can know which items have been operated
on, nor which items have yet to be operated on, nor which item experienced
the failure. Any caller which is serious about error recovery presumably
won't use it, unless the callback function happens to be something which
makes no state changes.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 4:42 ` Jeff Garzik
@ 2006-09-28 4:47 ` Andrew Morton
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Morton @ 2006-09-28 4:47 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
On Thu, 28 Sep 2006 00:42:24 -0400
Jeff Garzik <jeff@garzik.org> wrote:
> This thing introduces endless build noise we won't
> kill for years, making it much harder to spot much more serious stuff.
That's true, and it hurt. But there are a lot of real bugs in there.
I thought of adding a stricter __must_check like
#ifdef CONFIG_MUST_CHECK_ANAL
#define __must_check_anal __must_check
#else
#define __must_check_anal
#endif
which we can still do, of course.
But it'd be better to fix the bugs...
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 4:44 ` Andrew Morton
@ 2006-09-28 4:54 ` Jeff Garzik
2006-09-28 5:04 ` Andrew Morton
0 siblings, 1 reply; 12+ messages in thread
From: Jeff Garzik @ 2006-09-28 4:54 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
Andrew Morton wrote:
> On Wed, 27 Sep 2006 21:36:28 -0700
> Andrew Morton <akpm@osdl.org> wrote:
>
>> device_for_each_child()
>
> All that being said, device_for_each_child() is rather broken by design.
> It walks a list of items applying a function to them and bales out on
> first-error.
Or, like scsi_sysfs.c, it stops when it meets the first match. Which is
a common thing to do.
> There's no way in which the caller can know which items have been operated
> on, nor which items have yet to be operated on, nor which item experienced
> the failure. Any caller which is serious about error recovery presumably
> won't use it, unless the callback function happens to be something which
> makes no state changes.
A simple integer return error doesn't tell you all that information
either. The actor must obviously store that additional information
somewhere, if it cares.
But whatever. I give up. I'm going back to working on the libata
warnings each build spits out (iomap).
Jeff
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 4:54 ` Jeff Garzik
@ 2006-09-28 5:04 ` Andrew Morton
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Morton @ 2006-09-28 5:04 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
On Thu, 28 Sep 2006 00:54:31 -0400
Jeff Garzik <jeff@garzik.org> wrote:
> Andrew Morton wrote:
> > On Wed, 27 Sep 2006 21:36:28 -0700
> > Andrew Morton <akpm@osdl.org> wrote:
> >
> >> device_for_each_child()
> >
> > All that being said, device_for_each_child() is rather broken by design.
> > It walks a list of items applying a function to them and bales out on
> > first-error.
>
> Or, like scsi_sysfs.c, it stops when it meets the first match. Which is
> a common thing to do.
That code is flakey. Trace through all the called functions, see all the
errors which get ignored.
>
> > There's no way in which the caller can know which items have been operated
> > on, nor which items have yet to be operated on, nor which item experienced
> > the failure. Any caller which is serious about error recovery presumably
> > won't use it, unless the callback function happens to be something which
> > makes no state changes.
>
> A simple integer return error doesn't tell you all that information
> either. The actor must obviously store that additional information
> somewhere, if it cares.
Yup.
> But whatever. I give up.
That's the spirit ;)
> I'm going back to working on the libata
> warnings each build spits out (iomap).
Thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Illustration of warning explosion silliness
2006-09-28 3:34 ` Andrew Morton
2006-09-28 4:19 ` Jeff Garzik
@ 2006-09-28 23:18 ` Jeff Garzik
1 sibling, 0 replies; 12+ messages in thread
From: Jeff Garzik @ 2006-09-28 23:18 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-scsi, Greg KH, LKML, Linus Torvalds
Andrew Morton wrote:
> There, I feel better now. If you want to see the other warnings, set
> CONFIG_ENABLE_MUST_CHECK=n.
While Googling around for Hobson's Choice[1], I realized that we are
presented with the utterly apropos Morton's Fork:
http://en.wikipedia.org/wiki/Morton's_Fork
With CONFIG_ENABLE_MUST_CHECK warning explosion, we must choose between
seeing warnings in our own code, but missing __must_check bugs, and
seeing all the __must_check bugs but obscuring our own day-to-day devel
problems.
In the future, I would hope that it would be reasonable to merge a
feature like this along with the cleanups that avoid a warning explosion.
Jeff
[1] http://en.wikipedia.org/wiki/Hobson's_choice
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-09-28 23:18 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-09-28 0:58 [PATCH] Illustration of warning explosion silliness Jeff Garzik
2006-09-28 1:35 ` Andrew Morton
2006-09-28 1:48 ` Jeff Garzik
2006-09-28 3:34 ` Andrew Morton
2006-09-28 4:19 ` Jeff Garzik
2006-09-28 4:36 ` Andrew Morton
2006-09-28 4:42 ` Jeff Garzik
2006-09-28 4:47 ` Andrew Morton
2006-09-28 4:44 ` Andrew Morton
2006-09-28 4:54 ` Jeff Garzik
2006-09-28 5:04 ` Andrew Morton
2006-09-28 23:18 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox