G'day,
On Mon, Sep 27, 2004 at 11:03:39AM -0700, Jesse Barnes wrote:
On some platforms (e.g. SGI Challenge, Origin, and Altix machines), writes to
I/O space aren't ordered coming from different CPUs. For the most part, this
isn't a problem since drivers generally spinlock around code that does writeX
calls, but if the last operation a driver does before it releases a lock is a
write and some other CPU takes the lock and immediately does a write, it's
possible the second CPU's write could arrive before the first's.
This patch adds a mmiowb() call to deal with this sort of situation, and
adds some documentation describing I/O ordering issues to deviceiobook.tmpl.
The idea is to mirror the regular, cacheable memory barrier operation, wmb.
[...]
Patches to use this new primitive in various drivers will come separately,
probably via the SCSI tree.
Ok, here's a patch for the tg3 network driver to use mmiowb(). Tests
over the last couple of days has shown that it solves the oopses in
tg3_tx() that I reported and attempted to patch some time ago:
http://marc.theaimsgroup.com/?l=linux-netdev&m=108538612421774&w=2
The CPU usage of the mmiowb() approach is also significantly better
than doing PCI reads to flush the writes (by setting the existing
TG3_FLAG_MBOX_WRITE_REORDER flag). In an artificial CPU-constrained
test on a ProPack kernel, the same amount of CPU work for the REORDER
solution pushes 85.1 MB/s over 2 NICs compared to 146.5 MB/s for the
mmiowb() solution.
Ok, here's a patch for the tg3 network driver to use mmiowb(). Tests
over the last couple of days has shown that it solves the oopses in
tg3_tx() that I reported and attempted to patch some time ago:
http://marc.theaimsgroup.com/?l=linux-netdev&m=108538612421774&w=2
The CPU usage of the mmiowb() approach is also significantly better
than doing PCI reads to flush the writes (by setting the existing
TG3_FLAG_MBOX_WRITE_REORDER flag). In an artificial CPU-constrained
test on a ProPack kernel, the same amount of CPU work for the REORDER
solution pushes 85.1 MB/s over 2 NICs compared to 146.5 MB/s for the
mmiowb() solution.
Please put this macro in asm/io.h or similar and make sure
every platform has it implemented or provides a NOP version.
A lot of people are going to get this wrong btw. The only
way it's really going to be cured across the board is if someone
like yourself who understands this audits all of the drivers.
Ok, here's a patch for the tg3 network driver to use mmiowb(). Tests
over the last couple of days has shown that it solves the oopses in
tg3_tx() that I reported and attempted to patch some time ago:
http://marc.theaimsgroup.com/?l=linux-netdev&m=108538612421774&w=2
The CPU usage of the mmiowb() approach is also significantly better
than doing PCI reads to flush the writes (by setting the existing
TG3_FLAG_MBOX_WRITE_REORDER flag). In an artificial CPU-constrained
test on a ProPack kernel, the same amount of CPU work for the REORDER
solution pushes 85.1 MB/s over 2 NICs compared to 146.5 MB/s for the
mmiowb() solution.
Please put this macro in asm/io.h or similar and make sure
every platform has it implemented or provides a NOP version.
The patch that actually implements mmiowb() already does this, I think Greg
just used his patch for testing. The proper way to do it of course is to
just use mmiowb() where needed in tg3 after the write barrier patch gets in.
A lot of people are going to get this wrong btw. The only
way it's really going to be cured across the board is if someone
like yourself who understands this audits all of the drivers.
Yep, just like PCI posting (though many people seem to have a grasp on that
now).
Thanks,
Jesse
The patch that actually implements mmiowb() already does this, I think Greg
just used his patch for testing. The proper way to do it of course is to
just use mmiowb() where needed in tg3 after the write barrier patch gets in.
Perfect, please send me a tg3 patch once the mmiowb() bits
go into the tree.
Thanks a lot.