Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [patch] linux 2.4.9: Bad code in xchg_u32()
@ 2001-10-16 17:06 Maciej W. Rozycki
  2001-10-16 22:29 ` Ralf Baechle
  0 siblings, 1 reply; 5+ messages in thread
From: Maciej W. Rozycki @ 2001-10-16 17:06 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips, linux-mips

Ralf,

 There is a problem with the xchg_u32() function when compiled for
CPU_HAS_LLSC.  The constraints are broken and do not prevent gcc from
expanding ll and sc into multiple instructions, clobbering $at
additionally.  See a dump below (from free_dma() in kernel/dma.o): 

 108:   00602021        move    a0,v1
 10c:   3c030000        lui     v1,0x0
                        10c: R_MIPS_HI16        .data
 110:   00621821        addu    v1,v1,v0
 114:   c0630004        ll      v1,4(v1)
                        114: R_MIPS_LO16        .data
 118:   00800821        move    at,a0
 11c:   3c010000        lui     at,0x0
                        11c: R_MIPS_HI16        .data
 120:   00220821        addu    at,at,v0
 124:   e0210004        sc      at,4(at)
                        124: R_MIPS_LO16        .data
 128:   5020fffb        beqzl   at,118 <free_dma+0x40>
 12c:   3c030000        lui     v1,0x0
                        12c: R_MIPS_HI16        .data
 130:   00621821        addu    v1,v1,v0
 134:   c0630004        ll      v1,4(v1)
                        134: R_MIPS_LO16        .data

 Following is a fix that works for me.  The code now looks:

 104:   3c010000        lui     at,0x0
                        104: R_MIPS_HI16        .data
 108:   24210004        addiu   at,at,4
                        108: R_MIPS_LO16        .data
 10c:   00221021        addu    v0,at,v0
 110:   00001821        move    v1,zero
 114:   c0460000        ll      a2,0(v0)
 118:   00602021        move    a0,v1
 11c:   e0440000        sc      a0,0(v0)
 120:   5080fffd        beqzl   a0,118 <free_dma+0x40>
 124:   c0460000        ll      a2,0(v0)

Excellent -- it got shortened as well. 

 Unfortunately, gcc 2.95.3 doesn't want to accept a "=R" output constraint
here so I had to use "=m".  It looks like a bug in gcc.  Until it is fixed
the "R" input constraint here is sufficient for gcc to know it has m
already available in one of registers.  I added ".set nomacro" to make
sure the second ll fits in the BDS as well.

 Ralf, I think this should get applied.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.9-20011009-xchg-1
diff -up --recursive --new-file linux-mips-2.4.9-20011009.macro/include/asm-mips/system.h linux-mips-2.4.9-20011009/include/asm-mips/system.h
--- linux-mips-2.4.9-20011009.macro/include/asm-mips/system.h	Sun Oct  7 04:26:15 2001
+++ linux-mips-2.4.9-20011009/include/asm-mips/system.h	Tue Oct 16 01:11:27 2001
@@ -234,18 +234,17 @@ extern __inline__ unsigned long xchg_u32
 	unsigned long dummy;
 
 	__asm__ __volatile__(
-		".set\tnoreorder\t\t\t# xchg_u32\n\t"
-		".set\tnoat\n\t"
+		".set\tpush\t\t\t\t# xchg_u32\n\t"
+		".set\tnoreorder\n\t"
+		".set\tnomacro\n\t"
 		"ll\t%0, %3\n"
-		"1:\tmove\t$1, %2\n\t"
-		"sc\t$1, %1\n\t"
-		"beqzl\t$1, 1b\n\t"
+		"1:\tmove\t%2, %z4\n\t"
+		"sc\t%2, %1\n\t"
+		"beqzl\t%2, 1b\n\t"
 		" ll\t%0, %3\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (val), "=o" (*m), "=r" (dummy)
-		: "o" (*m), "2" (val)
-		: "memory");
+		".set\tpop"
+		: "=&r" (val), "=m" (*m), "=&r" (dummy)
+		: "R" (*m), "Jr" (val));
 
 	return val;
 #else

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

* Re: [patch] linux 2.4.9: Bad code in xchg_u32()
  2001-10-16 17:06 [patch] linux 2.4.9: Bad code in xchg_u32() Maciej W. Rozycki
@ 2001-10-16 22:29 ` Ralf Baechle
  2001-10-16 22:49   ` Jun Sun
  2001-10-17 11:07   ` Maciej W. Rozycki
  0 siblings, 2 replies; 5+ messages in thread
From: Ralf Baechle @ 2001-10-16 22:29 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: linux-mips, linux-mips

On Tue, Oct 16, 2001 at 07:06:40PM +0200, Maciej W. Rozycki wrote:

> 
>  Unfortunately, gcc 2.95.3 doesn't want to accept a "=R" output constraint
> here so I had to use "=m".  It looks like a bug in gcc.  Until it is fixed
> the "R" input constraint here is sufficient for gcc to know it has m
> already available in one of registers.  I added ".set nomacro" to make
> sure the second ll fits in the BDS as well.

I've added the "memory" clobber back; xchg() is expected to imply a memory
barrier.

"R" indeed seems to be fishy; I can't compile the kernel if I remove
the volatile from the first argument of xchg_u32().  I'd feel safer if
we could use "m" until we can be sure "R" works fine.

  Ralf

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

* Re: [patch] linux 2.4.9: Bad code in xchg_u32()
  2001-10-16 22:29 ` Ralf Baechle
@ 2001-10-16 22:49   ` Jun Sun
  2001-10-17  0:57     ` Ralf Baechle
  2001-10-17 11:07   ` Maciej W. Rozycki
  1 sibling, 1 reply; 5+ messages in thread
From: Jun Sun @ 2001-10-16 22:49 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Maciej W. Rozycki, linux-mips, linux-mips

Ralf Baechle wrote:
> 
> On Tue, Oct 16, 2001 at 07:06:40PM +0200, Maciej W. Rozycki wrote:
> 
> >
> >  Unfortunately, gcc 2.95.3 doesn't want to accept a "=R" output constraint
> > here so I had to use "=m".  It looks like a bug in gcc.  Until it is fixed
> > the "R" input constraint here is sufficient for gcc to know it has m
> > already available in one of registers.  I added ".set nomacro" to make
> > sure the second ll fits in the BDS as well.
> 
> I've added the "memory" clobber back; xchg() is expected to imply a memory
> barrier.
> 
> "R" indeed seems to be fishy; I can't compile the kernel if I remove
> the volatile from the first argument of xchg_u32().  I'd feel safer if
> we could use "m" until we can be sure "R" works fine.

Is there any reason to think "R" *should* be better than "m"?

Jun

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

* Re: [patch] linux 2.4.9: Bad code in xchg_u32()
  2001-10-16 22:49   ` Jun Sun
@ 2001-10-17  0:57     ` Ralf Baechle
  0 siblings, 0 replies; 5+ messages in thread
From: Ralf Baechle @ 2001-10-17  0:57 UTC (permalink / raw)
  To: Jun Sun; +Cc: Maciej W. Rozycki, linux-mips, linux-mips

On Tue, Oct 16, 2001 at 03:49:29PM -0700, Jun Sun wrote:

> > >  Unfortunately, gcc 2.95.3 doesn't want to accept a "=R" output constraint
> > > here so I had to use "=m".  It looks like a bug in gcc.  Until it is fixed
> > > the "R" input constraint here is sufficient for gcc to know it has m
> > > already available in one of registers.  I added ".set nomacro" to make
> > > sure the second ll fits in the BDS as well.
> > 
> > I've added the "memory" clobber back; xchg() is expected to imply a memory
> > barrier.
> > 
> > "R" indeed seems to be fishy; I can't compile the kernel if I remove
> > the volatile from the first argument of xchg_u32().  I'd feel safer if
> > we could use "m" until we can be sure "R" works fine.
> 
> Is there any reason to think "R" *should* be better than "m"?

Single instruction loads that is no macros.

  Ralf

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

* Re: [patch] linux 2.4.9: Bad code in xchg_u32()
  2001-10-16 22:29 ` Ralf Baechle
  2001-10-16 22:49   ` Jun Sun
@ 2001-10-17 11:07   ` Maciej W. Rozycki
  1 sibling, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2001-10-17 11:07 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips, linux-mips

On Wed, 17 Oct 2001, Ralf Baechle wrote:

> I've added the "memory" clobber back; xchg() is expected to imply a memory
> barrier.

 I'm not sure what you mean.  The "memory" clobber only means random
memory can get modified so gcc must dispose of all variables cached in
registers and reload them from memory.  Is xchg() meant to do so?  What
for?

> "R" indeed seems to be fishy; I can't compile the kernel if I remove
> the volatile from the first argument of xchg_u32().  I'd feel safer if
> we could use "m" until we can be sure "R" works fine.

 Sure we can, at the expense of obfuscating the code and wasting a
register -- we may use la explicitly.  But I hate workarounds -- they tend
to live forever and keep the real bug unfixed.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

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

end of thread, other threads:[~2001-10-17 11:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-10-16 17:06 [patch] linux 2.4.9: Bad code in xchg_u32() Maciej W. Rozycki
2001-10-16 22:29 ` Ralf Baechle
2001-10-16 22:49   ` Jun Sun
2001-10-17  0:57     ` Ralf Baechle
2001-10-17 11:07   ` Maciej W. Rozycki

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