All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
@ 2013-05-21 18:43 Bart Van Assche
  2013-05-29 23:01 ` Andrew Morton
  2013-06-28 15:12 ` [tip:timers/core] timer: Fix jiffies wrap behavior of round_jiffies_common() tip-bot for Bart Van Assche
  0 siblings, 2 replies; 9+ messages in thread
From: Bart Van Assche @ 2013-05-21 18:43 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Arjan van de Ven, Stephen Rothwell, linux-kernel

Make sure that the round_jiffies*() functions return a time that is
in the future when the jiffies counter is about to wrap.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
---
 kernel/timer.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/kernel/timer.c b/kernel/timer.c
index 15ffdb3..aa8b964 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -149,9 +149,7 @@ static unsigned long round_jiffies_common(unsigned long j, int cpu,
 	/* now that we have rounded, subtract the extra skew again */
 	j -= cpu * 3;
-	if (j <= jiffies) /* rounding ate our timeout entirely; */
-		return original;
-	return j;
+	return time_is_after_jiffies(j) ? j : original;
 }
  /**
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
  2013-05-21 18:43 [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*() Bart Van Assche
@ 2013-05-29 23:01 ` Andrew Morton
  2013-05-29 23:17   ` Joe Perches
  2013-05-30  6:19   ` Bart Van Assche
  2013-06-28 15:12 ` [tip:timers/core] timer: Fix jiffies wrap behavior of round_jiffies_common() tip-bot for Bart Van Assche
  1 sibling, 2 replies; 9+ messages in thread
From: Andrew Morton @ 2013-05-29 23:01 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Thomas Gleixner, Arjan van de Ven, Stephen Rothwell,
	linux-kernel, Joe Perches

On Tue, 21 May 2013 20:43:50 +0200 Bart Van Assche <bart.vanassche@gmail.com> wrote:

> Make sure that the round_jiffies*() functions return a time that is
> in the future when the jiffies counter is about to wrap.

Actually "when the jiffies counter has recently wrapped".

I assume this was found by inspection?

> @@ -149,9 +149,7 @@ static unsigned long round_jiffies_common(unsigned long j, int cpu,
>  	/* now that we have rounded, subtract the extra skew again */
>  	j -= cpu * 3;
> -	if (j <= jiffies) /* rounding ate our timeout entirely; */

This used to be a very common bug - we've weeded out many instances but
I'm sure more still remain.  We could perhaps have a checkpatch rule
which looks for comparisons against jiffes (and any other
time-measuring variables we can detect) and tells people to use
time_after() and friends, or time_is_*_jiffies().

> -		return original;
> -	return j;
> +	return time_is_after_jiffies(j) ? j : original;
>  }

Your email client mangles patches, btw.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
  2013-05-29 23:01 ` Andrew Morton
@ 2013-05-29 23:17   ` Joe Perches
  2013-05-29 23:38     ` Andrew Morton
  2013-05-30  6:19   ` Bart Van Assche
  1 sibling, 1 reply; 9+ messages in thread
From: Joe Perches @ 2013-05-29 23:17 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Bart Van Assche, Thomas Gleixner, Arjan van de Ven,
	Stephen Rothwell, linux-kernel

On Wed, 2013-05-29 at 16:01 -0700, Andrew Morton wrote:
> On Tue, 21 May 2013 20:43:50 +0200 Bart Van Assche <bart.vanassche@gmail.com> wrote:
> 
> > Make sure that the round_jiffies*() functions return a time that is
> > in the future when the jiffies counter is about to wrap.
> 
> Actually "when the jiffies counter has recently wrapped".
> 
> I assume this was found by inspection?
> 
> > @@ -149,9 +149,7 @@ static unsigned long round_jiffies_common(unsigned long j, int cpu,
> >  	/* now that we have rounded, subtract the extra skew again */
> >  	j -= cpu * 3;
> > -	if (j <= jiffies) /* rounding ate our timeout entirely; */
> 
> This used to be a very common bug - we've weeded out many instances but
> I'm sure more still remain.

This list probably isn't comprehensive.

$ git grep -E "if\s*\((\s*jiffies\s*[\<\>]|.*[\<\>]=?\s*jiffies\b)"
drivers/acpi/acpi_pad.c:                if (last_jiffies + round_robin_time * HZ < jiffies) {
drivers/acpi/acpi_pad.c:                        if (jiffies > expire_time) {
drivers/dma/ioat/dma_v2.c:      if (jiffies > chan->timer.expires && timer_pending(&chan->timer)) {
drivers/infiniband/hw/ipath/ipath_sdma.c:               if (jiffies < dd->ipath_sdma_abort_intr_timeout)
drivers/infiniband/hw/ipath/ipath_sdma.c:       if (jiffies > dd->ipath_sdma_abort_jiffies) {
drivers/infiniband/ulp/ipoib/ipoib_cm.c:                if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE
drivers/infiniband/ulp/ipoib/ipoib_cm.c:                if (time_before_eq(jiffies, p->jiffies + IPOIB_CM_RX_TIMEOUT))
drivers/input/misc/ati_remote2.c:               if (!time_after_eq(jiffies, ar2->jiffies))
drivers/md/dm-log-userspace-base.c:     else if (jiffies < limit)
drivers/misc/sgi-gru/grumain.c:                 if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies)
drivers/net/ethernet/intel/e1000/e1000_ethtool.c:               if (jiffies >= (time + 2)) {
drivers/net/ethernet/intel/e1000e/ethtool.c:            if (jiffies >= (time + 20)) {
drivers/net/ethernet/micrel/ksz884x.c:                  if (next_jiffies < jiffies)
drivers/net/ethernet/micrel/ksz884x.c:          } else if (jiffies >= hw_priv->counter[i].time) {
drivers/net/ethernet/micrel/ksz884x.c:          if (hw_priv->pme_wait <= jiffies) {
drivers/net/ethernet/neterion/vxge/vxge-main.c: if (jiffies > fifo->jiffies + HZ / 100) {
drivers/net/ethernet/neterion/vxge/vxge-main.c: if (jiffies > ring->jiffies + HZ / 100) {
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c:                 if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) {
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c:                 if (jiffies > (QLCNIC_FILTER_AGE * HZ + time)) {
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c:                         if (jiffies > (QLCNIC_READD_AGE * HZ + time))
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c:                 if (jiffies > (QLCNIC_READD_AGE * HZ + tmp_fil->ftime))
drivers/scsi/lpfc/lpfc_scsi.c:  if ((phba->last_ramp_down_time + QUEUE_RAMP_DOWN_INTERVAL) > jiffies) {
drivers/staging/bcm/InterfaceIdleMode.c:                if (timeout < jiffies )
drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h:                 if (jiffies > expire) {           \
drivers/staging/speakup/speakup_acntpc.c:               if (jiffies >= jiff_max && ch == SPACE) {
drivers/staging/speakup/speakup_decext.c:                       if (jiffies >= jiff_max) {
drivers/staging/speakup/speakup_decpc.c:                        if (jiffies >= jiff_max) {
drivers/staging/speakup/speakup_dectlk.c:                       if (jiffies >= jiff_max) {
kernel/timer.c: if (j <= jiffies) /* rounding ate our timeout entirely; */
net/rds/ib_send.c:                      if (ic->i_ack_queued + HZ/2 < jiffies)
net/rds/ib_send.c:                      if (send->s_queued + HZ/2 < jiffies)
net/rds/iw_send.c:                      if (ic->i_ack_queued + HZ/2 < jiffies)
net/rds/iw_send.c:                      if (send->s_queued + HZ/2 < jiffies)

>   We could perhaps have a checkpatch rule
> which looks for comparisons against jiffes (and any other
> time-measuring variables we can detect)

other variables like?

>  and tells people to use
> time_after() and friends, or time_is_*_jiffies().



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
  2013-05-29 23:17   ` Joe Perches
@ 2013-05-29 23:38     ` Andrew Morton
  2013-05-29 23:48       ` Joe Perches
  2013-05-30  0:13       ` Joe Perches
  0 siblings, 2 replies; 9+ messages in thread
From: Andrew Morton @ 2013-05-29 23:38 UTC (permalink / raw)
  To: Joe Perches
  Cc: Bart Van Assche, Thomas Gleixner, Arjan van de Ven,
	Stephen Rothwell, linux-kernel

On Wed, 29 May 2013 16:17:47 -0700 Joe Perches <joe@perches.com> wrote:

> >   We could perhaps have a checkpatch rule
> > which looks for comparisons against jiffes (and any other
> > time-measuring variables we can detect)
> 
> other variables like?

Grepping for time_after finds a bunch.  There's no real pattern to it though.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
  2013-05-29 23:38     ` Andrew Morton
@ 2013-05-29 23:48       ` Joe Perches
  2013-05-30  0:13       ` Joe Perches
  1 sibling, 0 replies; 9+ messages in thread
From: Joe Perches @ 2013-05-29 23:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Bart Van Assche, Thomas Gleixner, Arjan van de Ven,
	Stephen Rothwell, linux-kernel

On Wed, 2013-05-29 at 16:38 -0700, Andrew Morton wrote:
> On Wed, 29 May 2013 16:17:47 -0700 Joe Perches <joe@perches.com> wrote:
> 
> > >   We could perhaps have a checkpatch rule
> > > which looks for comparisons against jiffes (and any other
> > > time-measuring variables we can detect)
> > 
> > other variables like?
> 
> Grepping for time_after finds a bunch.  There's no real pattern to it though.

Yup, that's the problem.
Thought I'd ask what I was missing though.

No variable really stands out as testable other
than jiffies.

I added this to my local queue and I'll send it later.

# check for comparisons of jiffies
		if ($line =~ /\bif\s*\((\s*jiffies\s*[\<\>]|.*[\<\>]=?\s*jiffies\b)/) {
			WARN("JIFFIES_COMPARISON",
			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
		}



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
  2013-05-29 23:38     ` Andrew Morton
  2013-05-29 23:48       ` Joe Perches
@ 2013-05-30  0:13       ` Joe Perches
  2013-05-30  4:50         ` Andrew Morton
  1 sibling, 1 reply; 9+ messages in thread
From: Joe Perches @ 2013-05-30  0:13 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Bart Van Assche, Thomas Gleixner, Arjan van de Ven,
	Stephen Rothwell, linux-kernel

On Wed, 2013-05-29 at 16:38 -0700, Andrew Morton wrote:
> On Wed, 29 May 2013 16:17:47 -0700 Joe Perches <joe@perches.com> wrote:
> 
> > >   We could perhaps have a checkpatch rule
> > > which looks for comparisons against jiffes (and any other
> > > time-measuring variables we can detect)
> > 
> > other variables like?
> 
> Grepping for time_after finds a bunch.  There's no real pattern to it though.

get_jiffies_64() should probably be added as
another test too.

Also, these might be wrong:

arch/arm/kernel/smp_twd.c:              while (get_jiffies_64() < waitjiffies)
arch/arm/kernel/smp_twd.c:              while (get_jiffies_64() < waitjiffies)
fs/fuse/dir.c:  else if (fuse_dentry_time(entry) < get_jiffies_64()) {
fs/fuse/dir.c:  if (fi->i_time < get_jiffies_64()) {
fs/fuse/dir.c:          if (fi->i_time < get_jiffies_64()) {



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
  2013-05-30  0:13       ` Joe Perches
@ 2013-05-30  4:50         ` Andrew Morton
  0 siblings, 0 replies; 9+ messages in thread
From: Andrew Morton @ 2013-05-30  4:50 UTC (permalink / raw)
  To: Joe Perches
  Cc: Bart Van Assche, Thomas Gleixner, Arjan van de Ven,
	Stephen Rothwell, linux-kernel, Miklos Szeredi

On Wed, 29 May 2013 17:13:49 -0700 Joe Perches <joe@perches.com> wrote:

> On Wed, 2013-05-29 at 16:38 -0700, Andrew Morton wrote:
> > On Wed, 29 May 2013 16:17:47 -0700 Joe Perches <joe@perches.com> wrote:
> > 
> > > >   We could perhaps have a checkpatch rule
> > > > which looks for comparisons against jiffes (and any other
> > > > time-measuring variables we can detect)
> > > 
> > > other variables like?
> > 
> > Grepping for time_after finds a bunch.  There's no real pattern to it though.
> 
> get_jiffies_64() should probably be added as
> another test too.
> 
> Also, these might be wrong:
> 
> arch/arm/kernel/smp_twd.c:              while (get_jiffies_64() < waitjiffies)
> arch/arm/kernel/smp_twd.c:              while (get_jiffies_64() < waitjiffies)
> fs/fuse/dir.c:  else if (fuse_dentry_time(entry) < get_jiffies_64()) {
> fs/fuse/dir.c:  if (fi->i_time < get_jiffies_64()) {
> fs/fuse/dir.c:          if (fi->i_time < get_jiffies_64()) {
> 

Yup.  Normally a 64-bit jiffy will wrap around shortly after the heat
death of the universe, but

a) it's derived from jiffies, which we evilly cause to wrap after 5
   minutes uptime and

b) it's derived from jiffies, which is 32-bit on 32-bit and hence
   wraps every 49 days (HZ=1000).


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*()
  2013-05-29 23:01 ` Andrew Morton
  2013-05-29 23:17   ` Joe Perches
@ 2013-05-30  6:19   ` Bart Van Assche
  1 sibling, 0 replies; 9+ messages in thread
From: Bart Van Assche @ 2013-05-30  6:19 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Thomas Gleixner, Arjan van de Ven, Stephen Rothwell,
	linux-kernel, Joe Perches

On 05/30/13 01:01, Andrew Morton wrote:
> On Tue, 21 May 2013 20:43:50 +0200 Bart Van Assche <bart.vanassche@gmail.com> wrote:
>
>> Make sure that the round_jiffies*() functions return a time that is
>> in the future when the jiffies counter is about to wrap.
>
> Actually "when the jiffies counter has recently wrapped".
>
> I assume this was found by inspection?

Hello Andrew,

You are correct, this was found via source code inspection. I started 
reviewing the round_jiffies*() implementation because I was chasing a 
bug in a kernel driver using one of these functions.

>> -		return original;
>> -	return j;
>> +	return time_is_after_jiffies(j) ? j : original;
>>   }
>
> Your email client mangles patches, btw.

Sorry. Will take more care in the future.

Bart.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [tip:timers/core] timer: Fix jiffies wrap behavior of round_jiffies_common()
  2013-05-21 18:43 [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*() Bart Van Assche
  2013-05-29 23:01 ` Andrew Morton
@ 2013-06-28 15:12 ` tip-bot for Bart Van Assche
  1 sibling, 0 replies; 9+ messages in thread
From: tip-bot for Bart Van Assche @ 2013-06-28 15:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, arjan, bvanassche, tglx, sfr, bart.vanassche

Commit-ID:  9e04d3804d3ac97d8c03a41d78d0f0674b5d01e1
Gitweb:     http://git.kernel.org/tip/9e04d3804d3ac97d8c03a41d78d0f0674b5d01e1
Author:     Bart Van Assche <bart.vanassche@gmail.com>
AuthorDate: Tue, 21 May 2013 20:43:50 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 28 Jun 2013 17:10:11 +0200

timer: Fix jiffies wrap behavior of round_jiffies_common()

Direct compare of jiffies related values does not work in the wrap
around case. Replace it with time_is_after_jiffies().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Link: http://lkml.kernel.org/r/519BC066.5080600@acm.org
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/timer.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/timer.c b/kernel/timer.c
index 15ffdb3..15bc1b4 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -149,9 +149,11 @@ static unsigned long round_jiffies_common(unsigned long j, int cpu,
 	/* now that we have rounded, subtract the extra skew again */
 	j -= cpu * 3;
 
-	if (j <= jiffies) /* rounding ate our timeout entirely; */
-		return original;
-	return j;
+	/*
+	 * Make sure j is still in the future. Otherwise return the
+	 * unmodified value.
+	 */
+	return time_is_after_jiffies(j) ? j : original;
 }
 
 /**

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-06-28 15:13 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-21 18:43 [PATCH] timer: Fix jiffies wrap behavior of round_jiffies*() Bart Van Assche
2013-05-29 23:01 ` Andrew Morton
2013-05-29 23:17   ` Joe Perches
2013-05-29 23:38     ` Andrew Morton
2013-05-29 23:48       ` Joe Perches
2013-05-30  0:13       ` Joe Perches
2013-05-30  4:50         ` Andrew Morton
2013-05-30  6:19   ` Bart Van Assche
2013-06-28 15:12 ` [tip:timers/core] timer: Fix jiffies wrap behavior of round_jiffies_common() tip-bot for Bart Van Assche

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.