kernel-janitors.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
@ 2007-12-26 15:21 Julia Lawall
  2007-12-26 17:48 ` H. Peter Anvin
  2007-12-26 19:58 ` Ray Lee
  0 siblings, 2 replies; 10+ messages in thread
From: Julia Lawall @ 2007-12-26 15:21 UTC (permalink / raw)
  To: hpa, autofs, linux-kernel, kernel-janitors

From: Julia Lawall <julia@diku.dk>

The functions time_before, time_before_eq, time_after, and time_after_eq
are more robust for comparing jiffies against other values.

A simplified version of the semantic patch making this change is as follows:
(http://www.emn.fr/x-info/coccinelle/)

// <smpl>
@ change_compare_np @
expression E;
@@

(
- jiffies <= E
+ time_before_eq(jiffies,E)
|
- jiffies >= E
+ time_after_eq(jiffies,E)
|
- jiffies < E
+ time_before(jiffies,E)
|
- jiffies > E
+ time_after(jiffies,E)
)

@ include depends on change_compare_np @
@@

#include <linux/jiffies.h>

@ no_include depends on !include && change_compare_np @
@@

  #include <linux/...>
+ #include <linux/jiffies.h>
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>
---

diff -u -p linux-2.6/fs/autofs/dirhash.c linuxcopy/fs/autofs/dirhash.c
--- linux-2.6/fs/autofs/dirhash.c	2006-11-30 19:05:26.000000000 +0100
+++ linuxcopy/fs/autofs/dirhash.c	2007-12-25 20:53:48.000000000 +0100
@@ -47,7 +47,7 @@ struct autofs_dir_ent *autofs_expire(str
 			return NULL;	/* No entries */
 		/* We keep the list sorted by last_usage and want old stuff */
 		ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp);
-		if (jiffies - ent->last_usage < timeout)
+		if (time_before(jiffies, ent->last_usage + timeout))
 			break;
 		/* Move to end of list in case expiry isn't desirable */
 		autofs_update_usage(dh, ent);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-26 15:21 [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc Julia Lawall
@ 2007-12-26 17:48 ` H. Peter Anvin
  2007-12-26 19:19   ` Julia Lawall
  2007-12-26 19:58 ` Ray Lee
  1 sibling, 1 reply; 10+ messages in thread
From: H. Peter Anvin @ 2007-12-26 17:48 UTC (permalink / raw)
  To: Julia Lawall; +Cc: autofs, linux-kernel, kernel-janitors

Julia Lawall wrote:
> From: Julia Lawall <julia@diku.dk>
> 
> The functions time_before, time_before_eq, time_after, and time_after_eq
> are more robust for comparing jiffies against other values.
> 

More robust, how?  You already almost introduced a bug here...

	-hpa

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-26 17:48 ` H. Peter Anvin
@ 2007-12-26 19:19   ` Julia Lawall
  0 siblings, 0 replies; 10+ messages in thread
From: Julia Lawall @ 2007-12-26 19:19 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: autofs, linux-kernel, kernel-janitors

On Wed, 26 Dec 2007, H. Peter Anvin wrote:

> Julia Lawall wrote:
> > From: Julia Lawall <julia@diku.dk>
> > 
> > The functions time_before, time_before_eq, time_after, and time_after_eq
> > are more robust for comparing jiffies against other values.
> > 
> 
> More robust, how?  You already almost introduced a bug here...

I'm just summarizing the comment that goes with the definition of the 
time_after etc functions:

include/linux/jiffies.h:88
/*
 *	These inlines deal with timer wrapping correctly. You are 
 *	strongly encouraged to use them
 *	1. Because people otherwise forget
 *	2. Because if the timer wrap changes in future you won't have to
 *	   alter your driver code.
 *

julia

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-26 15:21 [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc Julia Lawall
  2007-12-26 17:48 ` H. Peter Anvin
@ 2007-12-26 19:58 ` Ray Lee
  2007-12-26 20:45   ` H. Peter Anvin
  2007-12-28 14:21   ` [autofs] " Fabio Olive Leite
  1 sibling, 2 replies; 10+ messages in thread
From: Ray Lee @ 2007-12-26 19:58 UTC (permalink / raw)
  To: Julia Lawall; +Cc: hpa, autofs, linux-kernel, kernel-janitors

On Dec 26, 2007 7:21 AM, Julia Lawall <julia@diku.dk> wrote:
> -               if (jiffies - ent->last_usage < timeout)
> +               if (time_before(jiffies, ent->last_usage + timeout))

I don't think this is a safe change? subtraction is always safe (if
you think about it as 'distance'), addition isn't always safe unless
you know the range. The time_before macro will expand that out to
(effectively):

  if ( (long)(ent->last_usage + timeout) - (long)(jiffies) < 0 )

which seems to introduce an overflow condition in the first term.

Dunno, I may be wrong (happens often), but at the very least what
you've transformed it into is no longer obviously correct, and so it's
not a great change.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-26 19:58 ` Ray Lee
@ 2007-12-26 20:45   ` H. Peter Anvin
  2007-12-27  7:08     ` Julia Lawall
  2007-12-28  9:27     ` [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc Julia Lawall
  2007-12-28 14:21   ` [autofs] " Fabio Olive Leite
  1 sibling, 2 replies; 10+ messages in thread
From: H. Peter Anvin @ 2007-12-26 20:45 UTC (permalink / raw)
  To: Ray Lee; +Cc: Julia Lawall, autofs, linux-kernel, kernel-janitors

Ray Lee wrote:
> On Dec 26, 2007 7:21 AM, Julia Lawall <julia@diku.dk> wrote:
>> -               if (jiffies - ent->last_usage < timeout)
>> +               if (time_before(jiffies, ent->last_usage + timeout))
> 
> I don't think this is a safe change? subtraction is always safe (if
> you think about it as 'distance'), addition isn't always safe unless
> you know the range. The time_before macro will expand that out to
> (effectively):
> 
>   if ( (long)(ent->last_usage + timeout) - (long)(jiffies) < 0 )
> 
> which seems to introduce an overflow condition in the first term.
> 
> Dunno, I may be wrong (happens often), but at the very least what
> you've transformed it into is no longer obviously correct, and so it's
> not a great change.

Indeed.  The bottom form will have overflow issues at time 
jiffies_wraparound/2, whereas the top form will have overflow issues 
only near jiffies_wraparound/1.

	-hpa

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-26 20:45   ` H. Peter Anvin
@ 2007-12-27  7:08     ` Julia Lawall
  2007-12-28  1:39       ` 
  2007-12-28  4:34       ` [autofs] [PATCH 1/4] fs/autofs: Use time_before, Ian Kent
  2007-12-28  9:27     ` [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc Julia Lawall
  1 sibling, 2 replies; 10+ messages in thread
From: Julia Lawall @ 2007-12-27  7:08 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Ray Lee, autofs, linux-kernel, kernel-janitors

On Wed, 26 Dec 2007, H. Peter Anvin wrote:

> Ray Lee wrote:
> > On Dec 26, 2007 7:21 AM, Julia Lawall <julia@diku.dk> wrote:
> > > -               if (jiffies - ent->last_usage < timeout)
> > > +               if (time_before(jiffies, ent->last_usage + timeout))
> > 
> > I don't think this is a safe change? subtraction is always safe (if
> > you think about it as 'distance'), addition isn't always safe unless
> > you know the range. The time_before macro will expand that out to
> > (effectively):
> > 
> >   if ( (long)(ent->last_usage + timeout) - (long)(jiffies) < 0 )
> > 
> > which seems to introduce an overflow condition in the first term.
> > 
> > Dunno, I may be wrong (happens often), but at the very least what
> > you've transformed it into is no longer obviously correct, and so it's
> > not a great change.
> 
> Indeed.  The bottom form will have overflow issues at time
> jiffies_wraparound/2, whereas the top form will have overflow issues only near
> jiffies_wraparound/1.

OK, so it seems like it is not such a good idea.

There are, however, over 200 files that contain calls to the various time 
functions that follow this pattern, eg:

arch/arm/kernel/ecard.c:563
if (!last || time_after(jiffies, last + 5*HZ)) {

Perhaps they should be coverted to use a subtraction as well?

julia


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-27  7:08     ` Julia Lawall
@ 2007-12-28  1:39       ` 
  2007-12-28  4:34       ` [autofs] [PATCH 1/4] fs/autofs: Use time_before, Ian Kent
  1 sibling, 0 replies; 10+ messages in thread
From:  @ 2007-12-28  1:39 UTC (permalink / raw)
  To: julia; +Cc: hpa, ray-lk, autofs, linux-kernel, kernel-janitors, yoshfuji

In article <Pine.LNX.4.64.0712270805370.6952@ask.diku.dk> (at Thu, 27 Dec 2007 08:08:53 +0100 (CET)), Julia Lawall <julia@diku.dk> says:

> On Wed, 26 Dec 2007, H. Peter Anvin wrote:
> 
> > Ray Lee wrote:
> > > On Dec 26, 2007 7:21 AM, Julia Lawall <julia@diku.dk> wrote:
> > > > -               if (jiffies - ent->last_usage < timeout)
> > > > +               if (time_before(jiffies, ent->last_usage + timeout))
> > > 
> > > I don't think this is a safe change? subtraction is always safe (if
> > > you think about it as 'distance'), addition isn't always safe unless
> > > you know the range. The time_before macro will expand that out to
> > > (effectively):
> > > 
> > >   if ( (long)(ent->last_usage + timeout) - (long)(jiffies) < 0 )
> > > 
> > > which seems to introduce an overflow condition in the first term.
> > > 
> > > Dunno, I may be wrong (happens often), but at the very least what
> > > you've transformed it into is no longer obviously correct, and so it's
> > > not a great change.
> > 
> > Indeed.  The bottom form will have overflow issues at time
> > jiffies_wraparound/2, whereas the top form will have overflow issues only near
> > jiffies_wraparound/1.
> 
> OK, so it seems like it is not such a good idea.
> 
> There are, however, over 200 files that contain calls to the various time 
> functions that follow this pattern, eg:
> 
> arch/arm/kernel/ecard.c:563
> if (!last || time_after(jiffies, last + 5*HZ)) {
> 
> Perhaps they should be coverted to use a subtraction as well?

No, use time_after() etc., unless you have very good reason not using them.
And above is not a good reason at all.
Frequency is not a problem.  If we have longer timeout which could
result in wrap-around, we must use another method, e.g. 64bit jiffies,
anyway.

--yoshfuji

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [autofs] [PATCH 1/4] fs/autofs: Use time_before,
  2007-12-27  7:08     ` Julia Lawall
  2007-12-28  1:39       ` 
@ 2007-12-28  4:34       ` Ian Kent
  1 sibling, 0 replies; 10+ messages in thread
From: Ian Kent @ 2007-12-28  4:34 UTC (permalink / raw)
  To: Julia Lawall
  Cc: H. Peter Anvin, Ray Lee, autofs, kernel-janitors, linux-kernel

On Thu, 2007-12-27 at 08:08 +0100, Julia Lawall wrote:
> On Wed, 26 Dec 2007, H. Peter Anvin wrote:
> 
> > Ray Lee wrote:
> > > On Dec 26, 2007 7:21 AM, Julia Lawall <julia@diku.dk> wrote:
> > > > -               if (jiffies - ent->last_usage < timeout)
> > > > +               if (time_before(jiffies, ent->last_usage + timeout))
> > > 
> > > I don't think this is a safe change? subtraction is always safe (if
> > > you think about it as 'distance'), addition isn't always safe unless
> > > you know the range. The time_before macro will expand that out to
> > > (effectively):

I don't see how subtraction is any different in this case as that could
just as easily underflow leading to the same issue.

> > > 
> > >   if ( (long)(ent->last_usage + timeout) - (long)(jiffies) < 0 )
> > > 
> > > which seems to introduce an overflow condition in the first term.
> > > 
> > > Dunno, I may be wrong (happens often), but at the very least what
> > > you've transformed it into is no longer obviously correct, and so it's
> > > not a great change.
> > 
> > Indeed.  The bottom form will have overflow issues at time
> > jiffies_wraparound/2, whereas the top form will have overflow issues only near
> > jiffies_wraparound/1.
> 
> OK, so it seems like it is not such a good idea.
> 
> There are, however, over 200 files that contain calls to the various time 
> functions that follow this pattern, eg:
> 
> arch/arm/kernel/ecard.c:563
> if (!last || time_after(jiffies, last + 5*HZ)) {

Including autofs4.

> 
> Perhaps they should be coverted to use a subtraction as well?

Thinking about the cases involved always makes my head ache.

Ian



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-26 20:45   ` H. Peter Anvin
  2007-12-27  7:08     ` Julia Lawall
@ 2007-12-28  9:27     ` Julia Lawall
  1 sibling, 0 replies; 10+ messages in thread
From: Julia Lawall @ 2007-12-28  9:27 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Ray Lee, autofs, linux-kernel, kernel-janitors, yoshfuji

On Wed, 26 Dec 2007, H. Peter Anvin wrote:

> Ray Lee wrote:
> > On Dec 26, 2007 7:21 AM, Julia Lawall <julia@diku.dk> wrote:
> > > -               if (jiffies - ent->last_usage < timeout)
> > > +               if (time_before(jiffies, ent->last_usage + timeout))
> > 
> > I don't think this is a safe change? subtraction is always safe (if
> > you think about it as 'distance'), addition isn't always safe unless
> > you know the range. The time_before macro will expand that out to
> > (effectively):
> > 
> >   if ( (long)(ent->last_usage + timeout) - (long)(jiffies) < 0 )
> > 
> > which seems to introduce an overflow condition in the first term.
> > 
> > Dunno, I may be wrong (happens often), but at the very least what
> > you've transformed it into is no longer obviously correct, and so it's
> > not a great change.
> 
> Indeed.  The bottom form will have overflow issues at time
> jiffies_wraparound/2, whereas the top form will have overflow issues only near
> jiffies_wraparound/1.

Isn't this only the case if timeout is a potentially large number? In this 
case, timeout may ultimately depend on a value that come from the user 
level, so I don't know what ranges are expected, but in many other cases 
one of the summands is a constant multiplied by HZ.  If the constant is 
small, then I guess that the likelihood that jiffies overflows and the 
likelihood that the sum overflows are essentially the same.  One then has 
to consider whether:

overflowed - correct </>/<=/>= small constant

is more or less desirable than

time_before/after/before_eq/after_eq(correct, overflowed_by_small_constant)

julia


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [autofs] [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc.
  2007-12-26 19:58 ` Ray Lee
  2007-12-26 20:45   ` H. Peter Anvin
@ 2007-12-28 14:21   ` Fabio Olive Leite
  1 sibling, 0 replies; 10+ messages in thread
From: Fabio Olive Leite @ 2007-12-28 14:21 UTC (permalink / raw)
  To: Ray Lee; +Cc: Julia Lawall, autofs, kernel-janitors, linux-kernel, hpa

On Wed, Dec 26, 2007 at 11:58:56AM -0800, Ray Lee wrote:
> 
> On Dec 26, 2007 7:21 AM, Julia Lawall <julia@diku.dk> wrote:
> > -               if (jiffies - ent->last_usage < timeout)
> > +               if (time_before(jiffies, ent->last_usage + timeout))
> 
> I don't think this is a safe change? subtraction is always safe (if
> you think about it as 'distance'), addition isn't always safe unless
> you know the range.

This thinking is wrong, and is exactly the kind of wrong thinking that
led to the time_{before,after}{,_eq} macros. If jiffies just wrapped,
your safe subtraction will underflow, and you'll be comparing very
different unsigned values.

This is only a concern for 32bit architectures, of course. With 64bit
jiffies, even if HZ is set to 1000000 in the far future, this
civilization will still not outlive the jiffies counter (insert
shocking soundtrack!) as it will wrap in half a million years.

Sadly with 32bit jiffies it currently wraps every 50 days, and the
sign (if cast to signed) changes every 25 days.

> The time_before macro will expand that out to
> (effectively):
> 
>   if ( (long)(ent->last_usage + timeout) - (long)(jiffies) < 0 )

After contemplating this for a very long time (for an NFS fix at the
time) I _think_ the magic is in the casts to signed. The construct
manages to compare correctly any given jiffie values within 2^31 of
each other (on 32bit arches) even with wraps, assuming you really have
timestamps where the second one is taken less than 2^31 jiffies after
the first.

Of course, if the highest jiffies bit wraps twice between the first
and second timestamps, you'll be comparing apples and oranges. If the
timing is right this can happen if you compare two timestamps i.e. 26
days from each other, but I think only NFS is wicked enough to produce
such long living (and stale) kernel data structures.

So in summary: don't question time_after and friends. Not without a
very good analysis and testing with a matrix of timestamps. :)

Cheers!
Fábio Olivé
-- 
ex sed lex awk yacc, e pluribus unix, amem
-
To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-12-28 14:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-26 15:21 [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc Julia Lawall
2007-12-26 17:48 ` H. Peter Anvin
2007-12-26 19:19   ` Julia Lawall
2007-12-26 19:58 ` Ray Lee
2007-12-26 20:45   ` H. Peter Anvin
2007-12-27  7:08     ` Julia Lawall
2007-12-28  1:39       ` 
2007-12-28  4:34       ` [autofs] [PATCH 1/4] fs/autofs: Use time_before, Ian Kent
2007-12-28  9:27     ` [PATCH 1/4] fs/autofs: Use time_before, time_before_eq, etc Julia Lawall
2007-12-28 14:21   ` [autofs] " Fabio Olive Leite

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).