Messages in this thread | | | Date | Mon, 13 May 2002 13:26:05 +1000 | From | Rusty Russell <> | Subject | Re: Memory Barrier Definitions |
| |
On Thu, 9 May 2002 08:00:35 -0700 David Mosberger <davidm@napali.hpl.hp.com> wrote: > The latter: loads can have "acquire" semantics and stores can have > "release" semantics. For example, at the assembly level, ld8.acq > would be an 8-byte load with acquire semantics, st8.rel an 8-byte > store with release semantics. At the C level, acquire/release > semantics is used for all accesses to "volatile" variables.
OK. So ignoring the fact that you somehow have to attach your barriers to a load or store for the moment, we have before vs. after (ia64), read vs. write (most archs), io vs mem (ppc, ppc64), data dependency vs non-data dependency (alpha), and smp vs up.
{read|write|readwrite} \ _{before|after|bidir} \ _{io|mem|iomem} \ _{dd|nondd} \ _{smp|nonsmp}
Now, I think the non-data-depends case is so common that it doesn't belong in the name at all, but as a separate macro:
#ifndef __alpha__ #define data_depends(barrier) (barrier) #else #define data_depends(barrier) (ddep_##barrier) #endif
Also, assuming that no data dependency on normal memory where it doesn't matter on UP is the default, we can elide those. Also, any barrier mentioning IO can be assumed to be in force even if UP, so those combinations are invalid. Note that UP with CONFIG_PREEMPT counts as SMP here:
/* Complete all reads from normal memory before any normal memory reads ;which follow this instruction, on SMP or PREEMPT */ read_before();
/* Do not begin any reads from normal memory which follow, before any normal reads which preceed this instruction are complete, on SMP or PREEMPT */ read_after();
/* read_before(); read_after(); */ read_bidir();
/* Complete all reads from IO before any IO reads which follow this instruction. */ read_before_io();
/* Complete all reads (IO or memory) before any reads which follow this instruction. */ read_before_iomem();
/* Do not begin any IO reads which follow, before any IO reads which preceed this instruction are complete. */ read_after_io();
/* Do not begin any reads (IO or memory) which follow, before any reads which preceed this instruction are complete. */ read_after_iomem();
/* read_before_io(); read_after_io(); */ read_bidir_io();
/* read_before_iomem(); read_after_iomem(); */ read_bidir_iomem();
/* read_before(), even if we are non-PREEMPT, non-SMP. */ read_before_nonsmp();
/* read_after(), even if we are non-PREEMPT, non-SMP. */ read_after_nonsmp();
/* read_before_nonsmp(); read_after_nonsmp(); */ read_bidir_nonsmp();
Complete for write_* and readwrite_*.
Suggested semantics spin_lock(): readwrite_after(); readwrite_after_io(); ie. no interlock between io and memory: if you're doing both (eg acenic) you need to put in your own iomem barrier (this is for the PPC folk).
Questions: 1) Can we elide any others? In particular, can we remove ths _bidir_ ones? 2) Should we prepend a "barr_" prefix? 3) Any variations I missed?
Cheers, Rusty. -- there are those who do and those who hang on and you don't see too many doers quoting their contemporaries. -- Larry McVoy - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |