[parisc-linux] missing barrier in _raw_spin_lock?
Grant Grundler
grundler at parisc-linux.org
Sat Jan 24 18:37:49 MST 2004
On Sat, Jan 24, 2004 at 04:15:44PM -0500, John David Anglin wrote:
> > >> static int x;
> > >> static spinlock_t lock;
...
> The test is wrong. Static variables are initialized to 0. So, the first
> `if' is never true and the code will optimize to a return instruction.
In any case, that should be
static spinlock_t lock = SPIN_LOCK_UNLOCKED;
(On parisc UNLOCKED == 1, not 0 like the rest of the world)
Is gcc really that smart that it knows static variables are 0?
The would be amazing to me because I thought linker magic could
twiddle stuff like this. Anyway, gcc doesn't seem to be that smart:
# diff t1.c t2.c
3c3
< static int x=1;
---
> static int x;
# diff t1.S t2.S
3,7d2
< .align 4
< .type x, @object
< .size x, 4
< x:
< .word 1
54a50,51
> .local x
> .comm x,4,4
BTW, the .S diff is the same for both -O2 and -O3 output.
Maybe other compile options would further optimize.
Arndt,
In any case, thanks for raising the issue.
I hadn't looked at the asm code in a long time.
The key bit is __ldcw() in asm/system.h:
/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
#define __ldcw(a) ({ \
unsigned __ret; \
__asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
__ret; \
})
I suspect (but am not certain) Arnd is right.
We indicate __ret is getting clobbered (=r) and that 'a' is an input ("r").
I don't see anything indicating we changed the memory location.
But I don't see the problem. The t2.S output looks correct.
The "if (!x) {...}" code is generated:
...
.L18:
ldw RR'x-$global$(%r21),%r20
comib,<> 0,%r20,.L13
ldi 4660,%r25
stw %r25,RR'x-$global$(%r21)
...
BTW, PARISC still doesn't support CONFIG_SMP (cpu init sequence)
on 2.6 kernels. SMP works (mostly) on 2.4 kernels.
Here's how I generated t1.S output and it's not completely trivial.
One has to:
o cp /usr/src/linux-2.6/include/linux/autoconf.h ./linux/
o vi linux/autoconf.hl
- change "#undef CONFIG_SMP" to #define
- add "#define CONFIG_NR_CPUS 4"
o gcc -O3 -I. -I/usr/src/linux-2.6/include/ -S t1.c -o t1.S
I've put the whole mess on
http://iou.parisc-linux.org/~grundler/asm-memory/
BTW, I notice several other asm() in linux/asm-parisc/system.h which
specify ': "memory"' but the instructions used are register only.
Notably the ssm/rsm/mtsm insn's.
Any comment if those asm() *do NOT* need ': "memory"'?
thanks,
grant
More information about the parisc-linux
mailing list