Wrong use of MAX_JIFFY_OFFSET?
Hi guys,
I saw a couple of places in current kernel have this kind of code:
Quoted 9 lines
static inline unsigned int
elapsed_jiffies_msecs(unsigned long start){ unsigned long end = jiffies; if (end >= start) return jiffies_to_msecs(end - start); return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); }
As you know, jiffies has a type of unsigned long, so if we know which is the end and
which is the start, then (end - start) can simply figure out how much jiffies flies,
without worry about the overflow.
Look at the code above, assume that there is just an overflow happening on
jiffies: end=0 and start=~0UL.
Since end < start, then the return value of the function is jiffies_to_msecs(MAX_JIFFY_OFFSET+2).
But shouldn't the correct value be jiffies_to_msecs(1)?
could someone tell me that am I missing anything?
Thanks,
Yu
Quoted 20 lines · On Wed, 28 Mar 2012 15:12:24 +0800 "Liu Yu" <[email protected]> wrote:
Hi guys,
I saw a couple of places in current kernel have this kind of code:
Quoted 9 lines
static inline unsigned int
elapsed_jiffies_msecs(unsigned long start){ unsigned long end = jiffies; if (end >= start) return jiffies_to_msecs(end - start); return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); }As you know, jiffies has a type of unsigned long, so if we know which is the end and
which is the start, then (end - start) can simply figure out how much jiffies flies,
without worry about the overflow.
Quoted 8 lines
Look at the code above, assume that there is just an overflow happening on
jiffies: end=0 and start=~0UL.
Since end < start, then the return value of the function isjiffies_to_msecs(MAX_JIFFY_OFFSET+2).
But shouldn't the correct value bejiffies_to_msecs(1)?could someone tell me that am I missing anything?
Seems right. The code should be
static inline unsigned long elapsed_jiffies_msecs(unsigned long start)
{
return jiffies_to_msecs(jiffies - start);
}Note the return type. jiffies_to_msecs() currently returns unsigned int. I think it should return unsigned long. Even then, it can still overflow with valid inputs on HZ=100 32-bit machines.
Quoted 7 lines
-----邮件原件-----
发件人: Andrew Morton [mailto:[email protected]] 发送时间: 2012年4月7日 3:05
收件人: Liu Yu
抄送: [email protected]
主题: Re: Wrong use ofMAX_JIFFY_OFFSET?
Quoted 18 lines
Quoted 15 lines · On Wed, 28 Mar 2012 15:12:24 +0800 "Liu Yu" <[email protected]> wrote:
Hi guys,
I saw a couple of places in current kernel have this kind of code:
Quoted 9 lines
static inline unsigned int
elapsed_jiffies_msecs(unsigned long start){ unsigned long end = jiffies; if (end >= start) return jiffies_to_msecs(end - start); return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); }As you know, jiffies has a type of unsigned long, so if we know which is
the
Quoted 6 lines
Quoted 6 lines
end and
which is the start, then (end - start) can simply figure out how much jiffies flies,
without worry about the overflow.Look at the code above, assume that there is just an overflow happening
on
Quoted 10 lines
Quoted 7 lines
jiffies: end=0 and start=~0UL.
Since end < start, then the return value of the function isjiffies_to_msecs(MAX_JIFFY_OFFSET+2).
But shouldn't the correct value bejiffies_to_msecs(1)?could someone tell me that am I missing anything?
Seems right. The code should be
Quoted 8 lines
static inline unsigned long
elapsed_jiffies_msecs(unsigned long start){ return jiffies_to_msecs(jiffies - start); }Note the return type.
jiffies_to_msecs()currently returns unsigned int. I think it should return unsigned long. Even then, it can still overflow with valid inputs on HZ=100 32-bit machines.
Thanks a lot for your reply :)
I saw similar code in
drivers/net/wireless/ipw2x00/libipw_wx.c
net/wireless/scan.c
include/linux/jbd2.h
hope someone can fix this. :)
Thanks,
Yu