From: James Bottomley Date: Sat, 24 Jun 2006 16:05:18 +0000 (+0000) Subject: [PARISC] Fix do_gettimeofday() hang X-Git-Tag: v2.6.18-rc1~359^2~1 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61c340166d8c62086b6de00afc7670eea27eb2ab;p=linux-2.6 [PARISC] Fix do_gettimeofday() hang Apparently gettimeoffset can return small negative values (usually in the 100us range). If xtime.tv_nsec is accidentally less than this, though (a fortunately unlikely event) it triggers the loop forever. I've added a test and correct adjustment for this case. It has a warning printk in there which I'd like to leave for the time being just in case this problem implicates some other part of the kernel. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 594930bc4b..eb35e1c0bb 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -157,8 +157,22 @@ do_gettimeofday (struct timeval *tv) usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - while (usec >= 1000000) { - usec -= 1000000; + if (unlikely(usec > LONG_MAX)) { + /* This can happen if the gettimeoffset adjustment is + * negative and xtime.tv_nsec is smaller than the + * adjustment */ + printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec); + usec += USEC_PER_SEC; + --sec; + /* This should never happen, it means the negative + * time adjustment was more than a second, so there's + * something seriously wrong */ + BUG_ON(usec > LONG_MAX); + } + + + while (usec >= USEC_PER_SEC) { + usec -= USEC_PER_SEC; ++sec; }