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
![]() |