Message ID | 20120809120144.GA19617@S2101-09.ap.freescale.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Aug 09, 2012 at 08:01:47PM +0800, Shawn Guo wrote: > diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h > index 99afa74..1282b61 100644 > --- a/arch/arm/include/asm/processor.h > +++ b/arch/arm/include/asm/processor.h > @@ -80,11 +80,18 @@ extern void release_thread(struct task_struct *); > unsigned long get_wchan(struct task_struct *p); > > #if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327) > -#define cpu_relax() smp_mb() > +#define __cpu_relax() smp_mb() > #else > -#define cpu_relax() barrier() > +#define __cpu_relax() barrier() > #endif > > +#define cpu_relax() \ > +({ \ > + static int i; \ > + if (i++ % 100) \ This should be if (i++ % 100 == 0) But either way it fixes the problem. > + __cpu_relax(); \ > +}) > + > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Thu, Aug 09, 2012 at 08:22:22PM +0800, Shawn Guo wrote: > On Thu, Aug 09, 2012 at 08:01:47PM +0800, Shawn Guo wrote: > > diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h > > index 99afa74..1282b61 100644 > > --- a/arch/arm/include/asm/processor.h > > +++ b/arch/arm/include/asm/processor.h > > @@ -80,11 +80,18 @@ extern void release_thread(struct task_struct *); > > unsigned long get_wchan(struct task_struct *p); > > > > #if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327) > > -#define cpu_relax() smp_mb() > > +#define __cpu_relax() smp_mb() > > #else > > -#define cpu_relax() barrier() > > +#define __cpu_relax() barrier() > > #endif > > > > +#define cpu_relax() \ > > +({ \ > > + static int i; \ > > + if (i++ % 100) \ > > This should be > > if (i++ % 100 == 0) > > But either way it fixes the problem. Right, so it does sound like issuing dmb instructions in a tight loop can bring a system to its knees. While we can address it in the above way in the kernel, it points to a much bigger problem - userspace can issue dmb instructions itself, which means any user program can effectively take a system down. Can you confirm this by building and running the following program: int main() { while (1) asm("dmb"); } Then try running some other programs. If I'm correct, this should result in the system becoming rather unresponsive. Thanks.
On Thu, Aug 09, 2012 at 02:57:55PM +0100, Russell King - ARM Linux wrote: > Then try running some other programs. If I'm correct, this should > result in the system becoming rather unresponsive. I should better describe what I mean by "unresponsive" - it won't lock the system up (because the dmb loop will be interrupted from time to time) but it should make it rather sluggish to deal with page faults on other CPUs.
On Thu, Aug 09, 2012 at 03:01:37PM +0100, Russell King - ARM Linux wrote: > On Thu, Aug 09, 2012 at 02:57:55PM +0100, Russell King - ARM Linux wrote: > > Then try running some other programs. If I'm correct, this should > > result in the system becoming rather unresponsive. > > I should better describe what I mean by "unresponsive" - it won't lock > the system up (because the dmb loop will be interrupted from time to > time) but it should make it rather sluggish to deal with page faults on > other CPUs. You are right. I'm seeing exactly the "unresponsive" you describe here after launching that little program.
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 99afa74..1282b61 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -80,11 +80,18 @@ extern void release_thread(struct task_struct *); unsigned long get_wchan(struct task_struct *p); #if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327) -#define cpu_relax() smp_mb() +#define __cpu_relax() smp_mb() #else -#define cpu_relax() barrier() +#define __cpu_relax() barrier() #endif +#define cpu_relax() \ +({ \ + static int i; \ + if (i++ % 100) \ + __cpu_relax(); \ +}) + _______________________________________________