[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a0cfcb83e2c34ae399beeea65582ff99@AcuMS.aculab.com>
Date: Wed, 28 Mar 2018 16:16:08 +0000
From: David Laight <David.Laight@...LAB.COM>
To: 'Benjamin Herrenschmidt' <benh@...nel.crashing.org>,
Will Deacon <will.deacon@....com>
CC: Linus Torvalds <torvalds@...ux-foundation.org>,
Alexander Duyck <alexander.duyck@...il.com>,
Sinan Kaya <okaya@...eaurora.org>,
Arnd Bergmann <arnd@...db.de>, Jason Gunthorpe <jgg@...pe.ca>,
Oliver <oohall@...il.com>,
"open list:LINUX FOR POWERPC (32-BIT AND 64-BIT)"
<linuxppc-dev@...ts.ozlabs.org>,
"linux-rdma@...r.kernel.org" <linux-rdma@...r.kernel.org>,
"Paul E. McKenney" <paulmck@...ux.vnet.ibm.com>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>
Subject: RE: RFC on writel and writel_relaxed
From: Benjamin Herrenschmidt
> Sent: 28 March 2018 16:13
...
> > I've always wondered exactly what the twi;isync were for - always seemed
> > very heavy handed for most mmio reads.
> > Particularly if you are doing mmio reads from a data fifo.
>
> If you do that you should use the "s" version of the accessors. Those
> will only do the above trick at the end of the access series. Also a
> FIFO needs special care about endianness anyway, so you should use
> those accessors regardless. (Hint: you never endian swap a FIFO even on
> BE on a LE device, unless something's been wired very badly in HW).
That was actually a 64 bit wide fifo connected to a 16bit wide PIO interface.
Reading the high address 'clocked' the fifo.
So the first 3 reads could happen in any order, but the 4th had to be last.
This is a small ppc and we shovel a lot of data through that fifo.
Whether it needed byteswapping depended completely on how our hardware people
had built the pcb (not made easy by some docs using the ibm bit numbering).
In fact it didn't....
While that driver only had to run on a very specific small ppc, generic drivers
might have similar issues.
I suspect that writel() is always (or should always be):
barrier_before_writel()
writel_relaxed()
barrier_after_writel()
So if a driver needs to do multiple writes (without strong ordering)
it should be able to repeat the writel_relaxed() with only one set
of barriers.
Similarly for readl().
In addition a lesser barrier is probably enough between a readl_relaxed()
and a writel_relaxed() that is conditional on the read value.
David
Powered by blists - more mailing lists