lkml.org 
[lkml]   [2005]   [Aug]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: question on memory barrier
    On Wed, Aug 24, 2005 at 07:31:31PM +0200, moreau francis wrote:
    > --- "linux-os (Dick Johnson)" <linux-os@analogic.com> a écrit :
    > > On Wed, 24 Aug 2005, moreau francis wrote:
    > > > I'm currently trying to write a USB driver for Linux. The device must be
    > > > configured by writing some values into the same register but I want to be
    > > > sure that the writing order is respected by either the compiler and the
    > > > cpu.
    [snip]
    > > > static inline void dev_out(u32 *reg, u32 value)
    > > > {
    > > > writel(value, regs);
    > > > }
    > > >
    > > > void config_dev(void)
    > > > {
    > > > dev_out(reg_a, 0x0); /* first io */
    > > > dev_out(reg_a, 0xA); /* second io */
    > > > }
    > > >
    > >
    > > This should be fine. The effect of the first bit of code
    > > plus all side-effects (if any) should be complete at the
    > > first effective sequence-point (;) but you need to

    While sequence points are relevant for purposes of reasoning about the
    effects of C code on the abstract state machine as defined by the C
    standard, they are irrelevant when talking about IO.

    > sorry but I'm not sure to understand you...Do you mean that the first write
    > into reg_a pointer will be completed before the second write because they're
    > separated by a (;) ?
    > Or because writes are encapsulated inside an inline function,
    > therefore compiler must execute every single writes before returning
    > from the inline function ?

    The first register write will be completed before the second register
    write because you use writel, which is defined to have the semantics you
    want. (It uses a platform-specific method to guarantee this, possibly
    "volatile" or "asm("eieio")" or whatever method your platform requires.)

    The sequence points, by themselves, do not make any requirements on the
    externally visible behavior of the program. Nor does the fact that
    there's an inline function involved. It's just the writel() that
    contains the magic to force in-order execution.

    You might benefit by running your source code through gcc -E and seeing
    what the writel() expands to. (I do something like "rm drivers/mydev.o;
    make V=1" and then copy-n-paste the gcc line, replacing the "-c -o mydev.o"
    options with -E.)

    The sequence point argument is obviously wrong, BTW - if it were the
    case that a mere sequence point required the compiler to have completed
    all externally-visible side effects, then almost every optimization that
    gcc does with -O2 would be impossible. CSE, loop splitting, etc.

    -andy
    -
    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/

    \
     
     \ /
      Last update: 2005-08-24 21:52    [W:2.954 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site