[Cbe-oss-dev] [PATCH 2:9] spufs: Fix spu status read in spu_stopped()
Benjamin Herrenschmidt
benh at kernel.crashing.org
Fri Jun 6 08:39:28 EST 2008
On Thu, 2008-06-05 at 15:02 +0000, Luke Browning wrote:
>
> That is true also, but I assumed Jeremy knew that. The loop is a simple
> read loop with no writes taking place. The eieio() is needed to
> synchronize the caller with state transitions in the hardware that are
> still in flight so to speak.
I don't know about that. Unless the SPU does something special on
receiveing an eieio message on the bus, which I yet have to see
documented properly, I would expect the eieio to be only useful to
ensure the ordering of the following load with previous stores from the
CPU to the SPU control registers.
> If the eieio() instruction does not
> provide this guarantee, it is a hardware bug. There are no subsequent
> instructions in the loop that would cause a state transtion. The
> eieio() is required in this case even without the loop.
I don't know what you call by state transition here. eieio only provides
ordering between storage accesses. It's not supposed to do anything
else.
> > However, I strongly suspect that status_read implementation uses
> > one of the in_* accessors which will already do the necessary barrier.
> >
> >
>
> I would not expect an eieio() for a read. I would for a write.
>
> static inline unsigned in_be32(const volatile unsigned *addr)
> {
> unsigned ret;
>
> __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
> : "=r" (ret) : "m" (*addr));
> return ret;
> }
Well, two things here.
First is: How old is the code above ? Current kernels have:
#define DEF_MMIO_IN(name, type, insn) \
static inline type name(const volatile type __iomem *addr) \
{ \
type ret; \
__asm__ __volatile__("sync;" insn ";twi 0,%0,0;isync" \
: "=r" (ret) : "r" (addr), "m" (*addr)); \
return ret; \
}
#define DEF_MMIO_OUT(name, type, insn) \
static inline void name(volatile type __iomem *addr, type val) \
{ \
__asm__ __volatile__("sync;" insn \
: "=m" (*addr) : "r" (val), "r" (addr)); \
IO_SET_SYNC_FLAG(); \
}
There are many reasons for that, we can discuss them later if you
want. In addition, even with the code above, I would strongly
suspect that the eieio is only needed as a barrier between previous
stores to the SPU control registers and the load. And that eieio is
present in the old code's out_* accessors. I don't think there is
any intrinsic state transition caused nor necessary due to the eieio
itself.
Ben.
More information about the cbe-oss-dev
mailing list