On Wed, Jun 10, 2020 at 11:08 AM Daniel Palmer <daniel@xxxxxxxx> wrote: > +/* > + * This may need locking to deal with situations where an interrupt > + * happens while we are in here and mb() gets called by the interrupt handler. > + */ I would suspect that you don't need locking here, and locking would likely make it worse. >From what I can tell, an interrupt happening anywhere inside of mstarv7_mb() would still result in the function completing (as miu_status still has the MSTARV7_L3BRIDGE_STATUS_DONE bit set) and nothing that could happen inside the irq would make the barrier weaker, only stronger. > +static void mstarv7_mb(void) > +{ > + /* toggle the flush miu pipe fire bit */ > + writel_relaxed(0, miu_flush); > + writel_relaxed(MSTARV7_L3BRIDGE_FLUSH_TRIGGER, miu_flush); > + while (!(readl_relaxed(miu_status) & MSTARV7_L3BRIDGE_STATUS_DONE)) { > + /* wait for flush to complete */ > + } > +} This is a heavy memory barrier indeed. The use of _relaxed() accessors is normally a bad idea and should be avoided, but this is one of the places where it is necessary because the normal writel()/readl() would recurse into arm_heavy_barrier(). Can you add a comment explaining this for the next reviewer? > +static void __init mstarv7_barriers_init(void) > +{ > + miu_flush = ioremap(MSTARV7_L3BRIDGE_FLUSH, sizeof(*miu_flush)); > + miu_status = ioremap(MSTARV7_L3BRIDGE_STATUS, sizeof(*miu_status)); > + soc_mb = mstarv7_mb; > +} Hardcoding physical addresses is generally considered bad style, even if you know the address in advance. Can you change this to get the address of the L3BRIDGE from DT instead and just hardcode the offsets? Note that they are in the same physical page, so you only need a single of_iomap(). > +static void __init mstarv7_init(void) > +{ > + mstarv7_barriers_init(); > +} I think you can fold this into a single function. Arnd