All of lore.kernel.org
 help / color / mirror / Atom feed
From: Willy Tarreau <willy@w.ods.org>
To: Andrew Morton <akpm@osdl.org>
Cc: davidel@xmailserver.org, nacc@us.ibm.com,
	nish.aravamudan@gmail.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/3] 2.6.14-rc2-mm1: fixes for overflow msec_to_jiffies()
Date: Sat, 1 Oct 2005 19:39:47 +0200	[thread overview]
Message-ID: <20051001173946.GA26174@alpha.home.local> (raw)
In-Reply-To: <20050929125207.52c6a1b8.akpm@osdl.org>

Hi Andrew,

On Thu, Sep 29, 2005 at 12:52:07PM -0700, Andrew Morton wrote:
> > On Thu, Sep 29, 2005 at 02:43:12AM -0700, Andrew Morton wrote:
> > > Willy Tarreau <willy@w.ods.org> wrote:
> > > >
> > > > +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
> > > >  +#  define MAX_MSEC_OFFSET \
> > > >  +	(ULONG_MAX - (MSEC_PER_SEC / HZ) + 1)
> > > 
> > > That generates numbers which don't fit into unsigned ints, yielding vast
> > > numbers of
> > > 
> > > include/linux/jiffies.h: In function `msecs_to_jiffies':
> > > include/linux/jiffies.h:310: warning: comparison is always false due to limited range of data type
> > > include/linux/jiffies.h: In function `usecs_to_jiffies':
> > > include/linux/jiffies.h:323: warning: comparison is always false due to limited range of data type
> > > 
> 
> This was a ppc64 build, gcc-3.3.3, CONFIG_HZ=250
> 
> Look a the value which MAX_MSEC_OFFSET will take (it's 2^63 minus a bit). 
> Comparing that to an unsigned int will generate the always-true or
> always-false warning.

OK, this was not trivial because gcc is smart enough to detect that even
after a cast, the comparison is still always false. So I had to cut the
comparison in two parts : one which tests whether we need to compare, and
one which does the test on the unsigned int part if necessary. It has shut
the warnings on my alpha (HZ=1024) and on my ultrasparc (HZ=250). I've
noticed that the code in previous patch could still overflow in the cases
where a multiply was used first, because the common type was still int. My
test case in user-space used MSEC_PER_SEC = 1000UL so it did not happen.
I've fixed this too.

I've also checked the code produced on x86 (because alpha code is unreadable
to me), and it resumes to this :

  - HZ=1000 : no code generated
  - HZ=250  : comparison, add, right shift
  - HZ=100  : comparison, add, divide
  - HZ=1024 : comparison, left shift, add, mul, right shift

I tried to compile on ppc64, but unfortunately, the kernel does not build
there because sizeof(long) == 4 ! I guess this is because gcc's target is
powerpc-linux-gnu. I'm trying to recompile it with powerpc64-linux-gnu.
Could you send me the output of gcc -v on your ppc64, please ?

I've also added missing parenthesis in the #defines which might have caused
trouble to external users of MAX_?SEC_OFFSET (none at the moment).

Here's the new patch, I've build everything on 2.6.14-rc2-mm1 but verified
that this code was not touched in -mm2 and the patch still applies.

Could you please retest it on your ppc64 and apply it if you're OK with it ?

Thanks,
Willy



Signed-off-by: Willy Tarreau <willy@w.ods.org>

--- linux-2.6.14-rc2-mm1/include/linux/jiffies.h	Thu Sep 29 23:04:49 2005
+++ linux-2.6.14-rc2-mm1-jiffies2/include/linux/jiffies.h	Sat Oct  1 19:12:13 2005
@@ -246,6 +246,37 @@
 
 #endif
 
+
+/*
+ * We define MAX_MSEC_OFFSET and MAX_USEC_OFFSET as maximal values that can be
+ * accepted by msecs_to_jiffies() and usec_to_jiffies() respectively, without
+ * risking a multiply overflow. Those functions return MAX_JIFFY_OFFSET for
+ * arguments above those values.
+ */
+
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+#  define MAX_MSEC_OFFSET \
+	(ULONG_MAX - (MSEC_PER_SEC / HZ) + 1)
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+#  define MAX_MSEC_OFFSET \
+	(ULONG_MAX / (HZ / MSEC_PER_SEC))
+#else
+#  define MAX_MSEC_OFFSET \
+	((ULONG_MAX - (MSEC_PER_SEC - 1)) / HZ)
+#endif
+
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+#  define MAX_USEC_OFFSET \
+	(ULONG_MAX - (USEC_PER_SEC / HZ) + 1)
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+#  define MAX_USEC_OFFSET \
+	(ULONG_MAX / (HZ / USEC_PER_SEC))
+#else
+#  define MAX_USEC_OFFSET \
+	((ULONG_MAX - (USEC_PER_SEC - 1)) / HZ)
+#endif
+
+
 /*
  * Convert jiffies to milliseconds and back.
  *
@@ -276,27 +307,29 @@
 
 static inline unsigned long msecs_to_jiffies(const unsigned int m)
 {
-	if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+	if (MAX_MSEC_OFFSET < UINT_MAX && m > (unsigned int)MAX_MSEC_OFFSET)
 		return MAX_JIFFY_OFFSET;
 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
-	return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
+	return ((unsigned long)m + (MSEC_PER_SEC / HZ) - 1) /
+		(MSEC_PER_SEC / HZ);
 #elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
-	return m * (HZ / MSEC_PER_SEC);
+	return (unsigned long)m * (HZ / MSEC_PER_SEC);
 #else
-	return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;
+	return ((unsigned long)m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;
 #endif
 }
 
 static inline unsigned long usecs_to_jiffies(const unsigned int u)
 {
-	if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
+	if (MAX_USEC_OFFSET < UINT_MAX && u > (unsigned int)MAX_USEC_OFFSET)
 		return MAX_JIFFY_OFFSET;
 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
-	return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
+	return ((unsigned long)u + (USEC_PER_SEC / HZ) - 1) /
+		(USEC_PER_SEC / HZ);
 #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
-	return u * (HZ / USEC_PER_SEC);
+	return (unsigned long)u * (HZ / USEC_PER_SEC);
 #else
-	return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC;
+	return ((unsigned long)u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC;
 #endif
 }
 


  parent reply	other threads:[~2005-10-01 17:46 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-23 18:13 [patch] sys_epoll_wait() timeout saga Davide Libenzi
2005-09-23 18:24 ` Nish Aravamudan
2005-09-24  4:05 ` Willy Tarreau
2005-09-24  4:44   ` Nish Aravamudan
2005-09-24  6:15     ` Willy Tarreau
2005-09-24  7:33       ` Vadim Lobanov
2005-09-24  7:51         ` Willy Tarreau
2005-09-24 15:10       ` Davide Libenzi
2005-09-24 17:20         ` Willy Tarreau
2005-09-24 18:19           ` Davide Libenzi
2005-09-25  6:05             ` Andrew Morton
2005-09-25  6:20               ` Willy Tarreau
2005-09-25  6:32                 ` Andrew Morton
2005-09-25  7:08               ` Vadim Lobanov
2005-09-25  8:03                 ` Willy Tarreau
2005-09-24 17:19       ` Nishanth Aravamudan
2005-09-24 18:25         ` Davide Libenzi
2005-09-24 19:38           ` [PATCH 0/3] fixes for overflow in poll(), epoll(), and msec_to_jiffies() Willy Tarreau
2005-09-24 19:44             ` [PATCH 1/3] 2.6.14-rc2-mm1: fixes for overflow msec_to_jiffies() Willy Tarreau
2005-09-29  9:43               ` Andrew Morton
2005-09-29 19:41                 ` Willy Tarreau
2005-09-29 19:52                   ` Andrew Morton
2005-09-29 20:55                     ` Willy Tarreau
2005-10-01 17:39                     ` Willy Tarreau [this message]
2005-09-24 19:47             ` [PATCH 2/3] 2.6.14-rc2-mm1: fixes for overflow in epoll() Willy Tarreau
2005-09-24 19:52             ` [PATCH 3/3] 2.6.14-rc2-mm1 : fixes for overflow in sys_poll() Willy Tarreau
2005-10-01 20:39               ` Willy Tarreau
2005-09-24 20:08             ` [PATCH 0/3] fixes for overflow in poll(), epoll(), and msec_to_jiffies() Davide Libenzi
2005-09-24 20:21               ` Willy TARREAU
2005-09-25 20:55             ` Nishanth Aravamudan
2005-09-25 22:06               ` Willy Tarreau
2005-09-24 21:25           ` [patch] sys_epoll_wait() timeout saga Vadim Lobanov
2005-09-24 18:30         ` Willy Tarreau

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=20051001173946.GA26174@alpha.home.local \
    --to=willy@w.ods.org \
    --cc=akpm@osdl.org \
    --cc=davidel@xmailserver.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nacc@us.ibm.com \
    --cc=nish.aravamudan@gmail.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.