--- 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 }