public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* jiffies_64 vs. jiffies
@ 2006-03-01  5:44 Atsushi Nemoto
  2006-03-01 12:05 ` Atsushi Nemoto
  2006-03-03  4:06 ` Paul Mackerras
  0 siblings, 2 replies; 7+ messages in thread
From: Atsushi Nemoto @ 2006-03-01  5:44 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-mips

Hi.  I noticed that the 'jiffies' variable has 'wall_jiffies + 1'
value in most of time.  I'm using MIPS platform but I think this is
same for other platforms.

I suppose this is due to gcc does not know that jiffies_64 and jiffies
share same place.

In kernel/timer.c:

static inline void update_times(void)
{
	unsigned long ticks;

	ticks = jiffies - wall_jiffies;
	if (ticks) {
		wall_jiffies += ticks;
		update_wall_time(ticks);
	}
	calc_load(ticks);
}
  
void do_timer(struct pt_regs *regs)
{
	jiffies_64++;
	update_times();
	softlockup_tick(regs);
}

This is compiled MIPS code (gcc 3.4.5):

80056db4 <do_timer>:
...
80056de0:       lui     a3,0x8033
80056de4:       lw      v0,21400(a3)	# load jiffies_64(lo)
80056de8:       lui     a1,0x8033
80056dec:       lui     t1,0x8033
80056df0:       lw      a2,21400(a1)	# load jiffies
80056df4:       lw      v1,21404(a3)	# load jiffies_64(hi)
80056df8:       addiu   v0,v0,1		# inc jiffies_64(lo)
80056dfc:       lw      t0,21360(t1)	# load wall_jiffies
80056e00:       sltiu   a1,v0,1		# calc carry
80056e04:       addu    v1,v1,a1	# add carry to jiffies_64(hi)
80056e08:       subu    s4,a2,t0	# calc ticks (jiffies - wall_jiffies)
80056e0c:       sw      v0,21400(a3)	# store jiffies_64(lo)
80056e10:       sw      v1,21404(a3)	# store jiffies_64(hi)
80056e14:       beqz    s4,80057060 <do_timer+0x2ac>
80056e18:       move    s8,a0

The 'tick' variable is calculated using 'jiffies' value before
incrementing 'jiffies_64'.  As a result, wall_jiffies will always one
smaller then jiffies on elsewhere.

I also checked x86 code (3.4.4).

c012696a <do_timer>:
...
c012696e:       mov    0xc0482400,%eax	# load jiffies
c0126973:       addl   $0x1,0xc0482400	# inc jiffies_64(lo)
c012697a:       mov    0xc041a230,%edx	# load wall_jiffies
c0126980:       mov    %eax,%ebx
c0126982:       adcl   $0x0,0xc0482404	# add carry to jiffies_64(hi)
c0126989:       sub    %edx,%ebx	# calc ticks (jiffies - wall_jiffies)
c012698b:       jne    c01269a0 <do_timer+0x36>

Though I'm not familiar with x86, it looks same.

Is this really expected code?  If no, how it can be fixed?  Insert
"barrier()" right after "jiffies_64++" ?

---
Atsushi Nemoto

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

* Re: jiffies_64 vs. jiffies
  2006-03-01  5:44 jiffies_64 vs. jiffies Atsushi Nemoto
@ 2006-03-01 12:05 ` Atsushi Nemoto
  2006-03-01 12:52   ` Nick Piggin
  2006-03-03  4:06 ` Paul Mackerras
  1 sibling, 1 reply; 7+ messages in thread
From: Atsushi Nemoto @ 2006-03-01 12:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-mips

>>>>> On Wed, 01 Mar 2006 14:44:42 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:
anemo> Hi.  I noticed that the 'jiffies' variable has 'wall_jiffies +
anemo> 1' value in most of time.  I'm using MIPS platform but I think
anemo> this is same for other platforms.

anemo> I suppose this is due to gcc does not know that jiffies_64 and
anemo> jiffies share same place.
...
anemo> Is this really expected code?  If no, how it can be fixed?
anemo> Insert "barrier()" right after "jiffies_64++" ?

I suppose passing updated jiffies to update_times() would be more
efficient than barrier().  Here is a patch.


Pass updated jiffies to update_times() to avoid jiffies/jiffies_64
aliasing.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>

diff --git a/kernel/timer.c b/kernel/timer.c
index fe3a9a9..7734788 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -904,11 +904,11 @@ void run_local_timers(void)
  * Called by the timer interrupt. xtime_lock must already be taken
  * by the timer IRQ!
  */
-static inline void update_times(void)
+static inline void update_times(unsigned long jif)
 {
 	unsigned long ticks;
 
-	ticks = jiffies - wall_jiffies;
+	ticks = jif - wall_jiffies;
 	if (ticks) {
 		wall_jiffies += ticks;
 		update_wall_time(ticks);
@@ -924,8 +924,7 @@ static inline void update_times(void)
 
 void do_timer(struct pt_regs *regs)
 {
-	jiffies_64++;
-	update_times();
+	update_times(++jiffies_64);
 	softlockup_tick(regs);
 }
 
---
Atsushi Nemoto

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

* Re: jiffies_64 vs. jiffies
  2006-03-01 12:05 ` Atsushi Nemoto
@ 2006-03-01 12:52   ` Nick Piggin
  2006-03-01 14:57     ` Atsushi Nemoto
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Piggin @ 2006-03-01 12:52 UTC (permalink / raw)
  To: Atsushi Nemoto; +Cc: linux-kernel, linux-mips

Atsushi Nemoto wrote:

> @@ -924,8 +924,7 @@ static inline void update_times(void)
>  
>  void do_timer(struct pt_regs *regs)
>  {
> -	jiffies_64++;
> -	update_times();
> +	update_times(++jiffies_64);
>  	softlockup_tick(regs);
>  }
>  

jiffies_64 is not volatile so you should not have to obfuscate
the code like this.

-- 
Send instant messages to your online friends http://au.messenger.yahoo.com 

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

* Re: jiffies_64 vs. jiffies
  2006-03-01 12:52   ` Nick Piggin
@ 2006-03-01 14:57     ` Atsushi Nemoto
  2006-03-01 15:00       ` Nick Piggin
  0 siblings, 1 reply; 7+ messages in thread
From: Atsushi Nemoto @ 2006-03-01 14:57 UTC (permalink / raw)
  To: nickpiggin; +Cc: linux-kernel, linux-mips

>>>>> On Wed, 01 Mar 2006 23:52:37 +1100, Nick Piggin <nickpiggin@yahoo.com.au> said:

>> void do_timer(struct pt_regs *regs)
>> {
>> -	jiffies_64++;
>> -	update_times();
>> +	update_times(++jiffies_64);
>>  	softlockup_tick(regs);
>> }

nick> jiffies_64 is not volatile so you should not have to obfuscate
nick> the code like this.

Well, do you mean it should be like this ?

	jiffies_64++;
	update_times(jiffies_64);

Thanks for your comments.
---
Atsushi Nemoto

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

* Re: jiffies_64 vs. jiffies
  2006-03-01 14:57     ` Atsushi Nemoto
@ 2006-03-01 15:00       ` Nick Piggin
  2006-03-01 16:13         ` Atsushi Nemoto
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Piggin @ 2006-03-01 15:00 UTC (permalink / raw)
  To: Atsushi Nemoto; +Cc: linux-kernel, linux-mips

Atsushi Nemoto wrote:
>>>>>>On Wed, 01 Mar 2006 23:52:37 +1100, Nick Piggin <nickpiggin@yahoo.com.au> said:
> 
> 
>>>void do_timer(struct pt_regs *regs)
>>>{
>>>-	jiffies_64++;
>>>-	update_times();
>>>+	update_times(++jiffies_64);
>>> 	softlockup_tick(regs);
>>>}
> 
> 
> nick> jiffies_64 is not volatile so you should not have to obfuscate
> nick> the code like this.
> 
> Well, do you mean it should be like this ?
> 
> 	jiffies_64++;
> 	update_times(jiffies_64);
> 

Yeah. It makes your patch a line smaller too!

> Thanks for your comments.

Oh it was nothing really ;)

-- 
SUSE Labs, Novell Inc.
Send instant messages to your online friends http://au.messenger.yahoo.com 

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

* Re: jiffies_64 vs. jiffies
  2006-03-01 15:00       ` Nick Piggin
@ 2006-03-01 16:13         ` Atsushi Nemoto
  0 siblings, 0 replies; 7+ messages in thread
From: Atsushi Nemoto @ 2006-03-01 16:13 UTC (permalink / raw)
  To: nickpiggin; +Cc: linux-kernel, linux-mips

>>>>> On Thu, 02 Mar 2006 02:00:16 +1100, Nick Piggin <nickpiggin@yahoo.com.au> said:

>> Well, do you mean it should be like this ?
>> 
>> jiffies_64++;
>> update_times(jiffies_64);

nick> Yeah. It makes your patch a line smaller too!

Another solution might be simplifying update_times() like this.  It
looks there is no point to calculate ticks in update_times().

diff --git a/kernel/timer.c b/kernel/timer.c
index fe3a9a9..6188c99 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -906,14 +906,9 @@ void run_local_timers(void)
  */
 static inline void update_times(void)
 {
-	unsigned long ticks;
-
-	ticks = jiffies - wall_jiffies;
-	if (ticks) {
-		wall_jiffies += ticks;
-		update_wall_time(ticks);
-	}
-	calc_load(ticks);
+	wall_jiffies++;
+	update_wall_time(1);
+	calc_load(1);
 }
   
 /*


As for long term solution, using an union for jiffies and jiffies_64
would be robust.  But it affects so many codes ...

---
Atsushi Nemoto

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

* Re: jiffies_64 vs. jiffies
  2006-03-01  5:44 jiffies_64 vs. jiffies Atsushi Nemoto
  2006-03-01 12:05 ` Atsushi Nemoto
@ 2006-03-03  4:06 ` Paul Mackerras
  1 sibling, 0 replies; 7+ messages in thread
From: Paul Mackerras @ 2006-03-03  4:06 UTC (permalink / raw)
  To: Atsushi Nemoto; +Cc: linux-kernel, linux-mips, akpm

Atsushi Nemoto writes:

> Hi.  I noticed that the 'jiffies' variable has 'wall_jiffies + 1'
> value in most of time.  I'm using MIPS platform but I think this is
> same for other platforms.
> 
> I suppose this is due to gcc does not know that jiffies_64 and jiffies
> share same place.

I can confirm that the same thing happens on powerpc, both 32-bit and
64-bit.  The compiler loads up jiffies, jiffies_64 and wall_jiffies
into registers before storing back the incremented value into
jiffies_64 and then updating wall_jiffies.

Thanks for finding that, it explains some other strange things that I
have seen happen.

Paul.

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

end of thread, other threads:[~2006-03-03  4:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-01  5:44 jiffies_64 vs. jiffies Atsushi Nemoto
2006-03-01 12:05 ` Atsushi Nemoto
2006-03-01 12:52   ` Nick Piggin
2006-03-01 14:57     ` Atsushi Nemoto
2006-03-01 15:00       ` Nick Piggin
2006-03-01 16:13         ` Atsushi Nemoto
2006-03-03  4:06 ` Paul Mackerras

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox