lkml.org 
[lkml]   [2005]   [Aug]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: question on memory barrier
    On Thu, Aug 25, 2005 at 11:14:03AM +0200, moreau francis wrote:
    > --- Andy Isaacson <adi@hexapodia.org> a écrit :
    > > 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.)
    >
    > I'm compiling Linux kernel for a MIPS32 cpu.

    Funny, me too. (Well, mostly MIPS64, but some MIPS32.)

    > On my platform, writel seems
    > expand to:
    >
    > static inline writel(u32 val, volatile void __iomem *mem)
    > {
    > volatile u32 *__mem;
    > u32 __val;
    >
    > __mem = (void *)((unsigned long)(mem));
    > __val = val;
    >
    > *__mem = __val;
    > }
    >
    > I don't see the magic in it since "volatile" keyword do not handle memory
    > ordering constraints...Linus wrote on volatile keyword, see
    > http://www.ussg.iu.edu/hypermail/linux/kernel/0401.0/1387.html

    Did you *read* the post?

    # The _only_ acceptable use of "volatile" is basically:
    #
    # - in _code_ (not data structures), where we might mark a place as making
    # a special type of access. For example, in the PCI MMIO read functions,
    # rather than use inline assembly to force the particular access (which
    # would work equally well), we can force the pointer to a volatile type.

    That's *exactly* what the writel you quote above does!

    The thing that Linus is railing against is stupidity like

    struct my_dev_regs {
    volatile u8 reg0;
    };

    That "volatile" does not do what you might think it would do.

    To return to the point directly at hand - on MIPS architectures to date,
    simply doing your memory access through a "volatile u32 *" is sufficient
    to ensure that the IO hits the bus (assuming that your pointer points to
    kseg1, not kseg0, or is otherwise uncached), because 'volatile' forces
    gcc to generate a "sw" for each store, and all MIPS so far have been
    designed so that multiple uncached writes to mmio locations do generate
    multiple bus transactions.

    I'm not an architect, but I think it would be possible to build a MIPS
    where this was not the case, and require additional contortions from
    users. Such a MIPS would suck to program and would probably fail in the
    marketplace, and there's no compelling benefit to doing so; ergo, I
    would expect "volatile" to continue to be sufficient on MIPS.

    > make drivers/mydev.i should do the job

    Thanks for the pointer!

    > but preprocessor doesn't expand inline
    > functions. So I won't be able to see the expanded writel function.

    But you can simply search backwards in the .i file! The whole point of
    inline functions is that they're present in the postprocessed text. The
    vim command "#" is useful for this.

    -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-25 16:57    [W:0.028 / U:0.004 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site