From mboxrd@z Thu Jan 1 00:00:00 1970 From: Zoltan Menyhart Date: Tue, 25 Apr 2006 14:13:58 +0000 Subject: I/O read, write implementation questions Message-Id: <444E2EA6.8000604@bull.net> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linux-ia64@vger.kernel.org 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