[PATCH] Remove CPU_32v6K dependencies in asm/spinlock.h
Russell King - ARM Linux
linux at arm.linux.org.uk
Mon Jan 17 05:53:32 EST 2011
On Mon, Jan 17, 2011 at 10:37:39AM +0000, Russell King - ARM Linux wrote:
> On Mon, Jan 17, 2011 at 10:15:25AM +0000, Catalin Marinas wrote:
> > On 15 January 2011 16:11, Russell King - ARM Linux
> > <linux at arm.linux.org.uk> wrote:
> > > SMP requires at least the ARMv6K extensions to be present, so if we're
> > > running on SMP, the WFE and SEV instructions must be available.
> > >
> > > However, when we run on UP, the v6K extensions may not be available,
> > > and so we don't want WFE/SEV to be in the instruction stream. Use the
> > > SMP alternatives infrastructure to replace these instructions with NOPs
> > > if we build for SMP but run on UP.
> > [...]
> > > --- a/arch/arm/include/asm/spinlock.h
> > > +++ b/arch/arm/include/asm/spinlock.h
> > > @@ -5,17 +5,36 @@
> > > #error SMP not supported on pre-ARMv6 CPUs
> > > #endif
> > >
> > > +/*
> > > + * sev and wfe are ARMv6K extensions. Uniprocessor ARMv6 may not have the K
> > > + * extensions, so when running on UP, we have to patch these instructions away.
> > > + */
> > > +#define ALT_SMP(smp, up) \
> > > + "9998: " smp "\n" \
> > > + " .pushsection \".alt.smp.init\", \"a\"\n" \
> > > + " .long 9998b\n" \
> > > + " " up "\n" \
> > > + " .popsection\n"
> > > +
> > > +#ifdef CONFIG_THUMB2_KERNEL
> > > +#define SEV ALT_SMP("sev.w", "nop.w")
> > > +#define WFE(cond) ALT_SMP("wfe" cond ".w", "nop.w")
> > > +#else
> > > +#define SEV ALT_SMP("sev", "nop")
> > > +#define WFE(cond) ALT_SMP("wfe" cond, "nop")
> > > +#endif
> > In the SEV macro definition, can you also include the dsb?
> No, you can't do preprocessor conditionals in the middle of a macro
> definition, and I don't want to have 4 versions of the SEV stuff.
> > This barrier is only there because of sev, otherwise we don't need it
> > (we have a dmb prior to releasing the lock).
> 1. Does it make sense to have sev and wfe instructions in non-SMP kernels?
> We now have in asm/system.h:
> #if __LINUX_ARM_ARCH__ >= 7 || \
> (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
> #define sev() __asm__ __volatile__ ("sev" : : : "memory")
> #define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
> #define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
> 2. Should we have a smp_dsb() which makes the dsb conditional elsewhere?
> 3. Do we always need a dsb prior to a sev? Maybe the SPEAR patches need
> another review to determine how they're using sev()?
FYI, this is how the SPEAR patches use sev():
| +static void __init wakeup_secondary(void)
| + /* nobody is to be released from the pen yet */
| + pen_release = -1;
| + /*
| + * Write the address of secondary startup into the system-wide
| + * location (presently it is in SRAM). The BootMonitor waits
| + * for this register to become non-zero.
| + * We must also send an sev to wake it up
| + */
| + __raw_writel(BSYM(virt_to_phys(spear13xx_secondary_startup)),
| + __io_address(SPEAR13XX_SYS_LOCATION));
| + mb();
| + /*
| + * Send a 'sev' to wake the secondary core from WFE.
| + */
| + sev();
so the dsb() is inside mb(), before the outer sync call.
There should be another version of this patch coming which updates the
way the pen_release stuff is done (I hope) for the changes I made in
other platforms pen_release handling, so the above may change.
More information about the linux-arm-kernel