I/O read, write implementation questions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The SDM shows on pages 2:585-586 how the I/O space reads and
writes have to be iplemented, e.g.:

outb:	...
	mf
	st1.rel [port_addr] = in1
	mf.a
	mf

inb:	...
	mf
	ld1.acq r8 = [port_addr]
	mf.a
	mf

The actual implementation does not include the pairs of "mf"-s.
Can someone, please, explain me why they are left off?

The following code sequence:

	outb(data, port_addr);
	flag = 1;

may be compiled as:

	add	r8 = 1, r0
	add	r2 = flag_offs, r1
	;;
	st1.rel [port_addr] = data
	mf.a
	st1	[r2] = r8

What prevents "st1 [r2] = r8" from being seen before
"st1.rel [port_addr] = data" is seen?
("mf.a" is unordered, see Table 4-14, SDM vol2.)
Similar hazardous code can be constructed with "inb()".

Why do not "readb()" ... "writeb()" include "mf.a"-s?

Let's take an example from the "ia-64 Linux Kernel" book, chapter 7.2.1:

	dmabuf[0] = 5;
	memcpy(dmabuf + 1, "hello", 5);
	mb();
	readl(dmactl);	// Memory mapped I/O
// And let's add:
	flag = 1;

What prevents "flag = 1" from being seen before the DMA is actually
kicked off?

The ".acq" generated by "readl()" - because "dmactl" is a volatile
pointer - plays with the OzQ only.
As "dmactl" is an uncached address, the read request goes into the
In-Order Output Queue.
Nothing remains in the OzQ ahead of "flag = 1", it gets committed
happily against the L2 cache, i.e. it becomes globally visible.
Our uncached read request is still sitting in the In-Order Output Queue...
It would not help if I added an "mb()" before "flag = 1".

Thanks,

Zoltan
-
: send the line "unsubscribe linux-ia64" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [Sparc Linux]     [DCCP]     [Linux ARM]     [Yosemite News]     [Linux SCSI]     [Linux x86_64]     [Linux for Ham Radio]

  Powered by Linux