On Friday 23 October 2015 17:12:38 Pingbo Wen wrote:
On Monday, October 19, 2015 04:58 PM, Arnd Bergmann wrote:
do_gettimeofday(&tv);
tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec);
tv.tv_usec -= mlc->instart.tv_usec;
if (tv.tv_usec >= mlc->intimeout) goto sched;
tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / USEC_PER_SEC;
if (!tv.tv_usec) goto sched;
mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec);
ktime_get_ts64(&ts64);
ts64.tv_nsec += NSEC_PER_SEC *
(ts64.tv_sec - mlc->instart.tv_sec);
ts64.tv_nsec -= mlc->instart.tv_nsec;
tv_nsec will overflow here for any timeout over 4.3 seconds, where it used to overflow after 4294 seconds. This is almost certainly a bug.
You could work around that by using ktime_get_ns() to get a nanosecond value right away, but a 64-bit number is more expensive to convert to jiffies.
You are right, I didn't notice that tv_nsec is a 32bit variable. Maybe we should use ktime_t here, so that handling sec and nsec separately is needless.
Using jiffies here will need to take more codes to handle jiffies overflow carefully. I think coverting 64bit number to jiffies is the price we must take, if we use 64bit version here.
Handling the jiffies overflow is trivially done through the time_before() and time_after() helpers, like
start = jiffies; ... now = jiffies; timeout = start + HZ * timeout_usec / USEC_PER_SEC; if (time_after(now, start + timeout_jiffies) timeout(); else mod_timer(timer, start + timeout_jiffies);
The time_after function works because unsigned overflow is well-defined in C (unlike signed overflow).
As a side-note, please take the time to delete any lines from the original mail that you are not referencing when you reply.
Arnd