All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-10-26 14:34 ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-10-26 14:34 UTC (permalink / raw)
  To: akpm
  Cc: Eric W. Biederman, Vivek Goyal, schwidefsky, heiko.carstens,
	kexec, linux-kernel

Hello Andrew,

After the discussion with Eric and Vivek the following patch
seems to be a good solution to me. Could you accept this patch?

When two CPUs call panic at the same time there is a
possible race condition that can stop kdump. The first
CPU calls crash_kexec() and the second CPU calls
smp_send_stop() in panic() before crash_kexec() finished
on the first CPU. So the second CPU stops the first CPU
and therefore kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in
panic that allows only one CPU to process crash_kexec() and
the subsequent panic code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
 #endif
 
 	/*
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic all other CPUs will wait on
+	 * the panic_lock. They are stopped afterwards by smp_send_stop().
+	 */
+	spin_lock(&panic_lock);
+
+	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
 	 * Do we want to call this before we try to display a message?



^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-10-26 14:34 ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-10-26 14:34 UTC (permalink / raw)
  To: akpm
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

Hello Andrew,

After the discussion with Eric and Vivek the following patch
seems to be a good solution to me. Could you accept this patch?

When two CPUs call panic at the same time there is a
possible race condition that can stop kdump. The first
CPU calls crash_kexec() and the second CPU calls
smp_send_stop() in panic() before crash_kexec() finished
on the first CPU. So the second CPU stops the first CPU
and therefore kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in
panic that allows only one CPU to process crash_kexec() and
the subsequent panic code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
 #endif
 
 	/*
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic all other CPUs will wait on
+	 * the panic_lock. They are stopped afterwards by smp_send_stop().
+	 */
+	spin_lock(&panic_lock);
+
+	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
 	 * Do we want to call this before we try to display a message?



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-10-26 14:34 ` Michael Holzheu
@ 2011-10-27 17:40   ` Vivek Goyal
  -1 siblings, 0 replies; 41+ messages in thread
From: Vivek Goyal @ 2011-10-27 17:40 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: akpm, Eric W. Biederman, schwidefsky, heiko.carstens, kexec,
	linux-kernel

On Wed, Oct 26, 2011 at 04:34:09PM +0200, Michael Holzheu wrote:
> Hello Andrew,
> 
> After the discussion with Eric and Vivek the following patch
> seems to be a good solution to me. Could you accept this patch?
> 
> When two CPUs call panic at the same time there is a
> possible race condition that can stop kdump. The first
> CPU calls crash_kexec() and the second CPU calls
> smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU. So the second CPU stops the first CPU
> and therefore kdump fails:
> 
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> 
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> 
> This patch fixes the problem by introducing a spinlock in
> panic that allows only one CPU to process crash_kexec() and
> the subsequent panic code.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>

Sounds reasonable to me.

Acked-by: Vivek Goyal <vgoyal@redhat.com>

Thanks
Vivek

> ---
>  kernel/panic.c |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
>   */
>  NORET_TYPE void panic(const char * fmt, ...)
>  {
> +	static DEFINE_SPINLOCK(panic_lock);
>  	static char buf[1024];
>  	va_list args;
>  	long i, i_next = 0;
> @@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
>  #endif
>  
>  	/*
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic all other CPUs will wait on
> +	 * the panic_lock. They are stopped afterwards by smp_send_stop().
> +	 */
> +	spin_lock(&panic_lock);
> +
> +	/*
>  	 * If we have crashed and we have a crash kernel loaded let it handle
>  	 * everything else.
>  	 * Do we want to call this before we try to display a message?
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-10-27 17:40   ` Vivek Goyal
  0 siblings, 0 replies; 41+ messages in thread
From: Vivek Goyal @ 2011-10-27 17:40 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, akpm

On Wed, Oct 26, 2011 at 04:34:09PM +0200, Michael Holzheu wrote:
> Hello Andrew,
> 
> After the discussion with Eric and Vivek the following patch
> seems to be a good solution to me. Could you accept this patch?
> 
> When two CPUs call panic at the same time there is a
> possible race condition that can stop kdump. The first
> CPU calls crash_kexec() and the second CPU calls
> smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU. So the second CPU stops the first CPU
> and therefore kdump fails:
> 
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> 
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> 
> This patch fixes the problem by introducing a spinlock in
> panic that allows only one CPU to process crash_kexec() and
> the subsequent panic code.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>

Sounds reasonable to me.

Acked-by: Vivek Goyal <vgoyal@redhat.com>

Thanks
Vivek

> ---
>  kernel/panic.c |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
>   */
>  NORET_TYPE void panic(const char * fmt, ...)
>  {
> +	static DEFINE_SPINLOCK(panic_lock);
>  	static char buf[1024];
>  	va_list args;
>  	long i, i_next = 0;
> @@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
>  #endif
>  
>  	/*
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic all other CPUs will wait on
> +	 * the panic_lock. They are stopped afterwards by smp_send_stop().
> +	 */
> +	spin_lock(&panic_lock);
> +
> +	/*
>  	 * If we have crashed and we have a crash kernel loaded let it handle
>  	 * everything else.
>  	 * Do we want to call this before we try to display a message?
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-10-26 14:34 ` Michael Holzheu
@ 2011-10-28 23:11   ` Andrew Morton
  -1 siblings, 0 replies; 41+ messages in thread
From: Andrew Morton @ 2011-10-28 23:11 UTC (permalink / raw)
  To: holzheu
  Cc: Eric W. Biederman, Vivek Goyal, schwidefsky, heiko.carstens,
	kexec, linux-kernel

On Wed, 26 Oct 2011 16:34:09 +0200
Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:

> Hello Andrew,
> 
> After the discussion with Eric and Vivek the following patch
> seems to be a good solution to me. Could you accept this patch?
> 
> When two CPUs call panic at the same time there is a
> possible race condition that can stop kdump. The first
> CPU calls crash_kexec() and the second CPU calls
> smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU. So the second CPU stops the first CPU
> and therefore kdump fails:
> 
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> 
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> 
> This patch fixes the problem by introducing a spinlock in
> panic that allows only one CPU to process crash_kexec() and
> the subsequent panic code.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/panic.c |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
>   */
>  NORET_TYPE void panic(const char * fmt, ...)
>  {
> +	static DEFINE_SPINLOCK(panic_lock);
>  	static char buf[1024];
>  	va_list args;
>  	long i, i_next = 0;
> @@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
>  #endif
>  
>  	/*
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic all other CPUs will wait on
> +	 * the panic_lock. They are stopped afterwards by smp_send_stop().
> +	 */
> +	spin_lock(&panic_lock);
> +

hm.  Boy.  That'll stop 'em OK!

Should this be done earlier in the function?  As it stands we'll have
multiple CPUs scribbling on buf[] at the same time and all trying to
print the same thing at the same time, dumping their stacks, etc. 
Perhaps it would be better to single-thread all that stuff.

Also...  this patch affects all CPU architectures, all configs, etc. 
So we're expecting that every architecture's smp_send_stop() is able to
stop a CPU which is spinning in spin_lock(), possibly with local
interrupts disabled.  Will this work?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-10-28 23:11   ` Andrew Morton
  0 siblings, 0 replies; 41+ messages in thread
From: Andrew Morton @ 2011-10-28 23:11 UTC (permalink / raw)
  To: holzheu
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

On Wed, 26 Oct 2011 16:34:09 +0200
Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:

> Hello Andrew,
> 
> After the discussion with Eric and Vivek the following patch
> seems to be a good solution to me. Could you accept this patch?
> 
> When two CPUs call panic at the same time there is a
> possible race condition that can stop kdump. The first
> CPU calls crash_kexec() and the second CPU calls
> smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU. So the second CPU stops the first CPU
> and therefore kdump fails:
> 
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> 
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> 
> This patch fixes the problem by introducing a spinlock in
> panic that allows only one CPU to process crash_kexec() and
> the subsequent panic code.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/panic.c |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
>   */
>  NORET_TYPE void panic(const char * fmt, ...)
>  {
> +	static DEFINE_SPINLOCK(panic_lock);
>  	static char buf[1024];
>  	va_list args;
>  	long i, i_next = 0;
> @@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
>  #endif
>  
>  	/*
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic all other CPUs will wait on
> +	 * the panic_lock. They are stopped afterwards by smp_send_stop().
> +	 */
> +	spin_lock(&panic_lock);
> +

hm.  Boy.  That'll stop 'em OK!

Should this be done earlier in the function?  As it stands we'll have
multiple CPUs scribbling on buf[] at the same time and all trying to
print the same thing at the same time, dumping their stacks, etc. 
Perhaps it would be better to single-thread all that stuff.

Also...  this patch affects all CPU architectures, all configs, etc. 
So we're expecting that every architecture's smp_send_stop() is able to
stop a CPU which is spinning in spin_lock(), possibly with local
interrupts disabled.  Will this work?

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-10-28 23:11   ` Andrew Morton
@ 2011-10-31  9:57     ` Michael Holzheu
  -1 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-10-31  9:57 UTC (permalink / raw)
  To: Andrew Morton
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

Hello Andrew,

On Fri, 2011-10-28 at 16:11 -0700, Andrew Morton wrote:

[snip]

> Should this be done earlier in the function?  As it stands we'll have
> multiple CPUs scribbling on buf[] at the same time and all trying to
> print the same thing at the same time, dumping their stacks, etc. 
> Perhaps it would be better to single-thread all that stuff

My fist patch took the spinlock at the beginning of panic(). But then
Eric asked, if it wouldn't be better to get both panic printk's and I
agreed.

> Also...  this patch affects all CPU architectures, all configs, etc. 
> So we're expecting that every architecture's smp_send_stop() is able to
> stop a CPU which is spinning in spin_lock(), possibly with local
> interrupts disabled.  Will this work?

At least on s390 it will work. If there are architectures that can't
stop disabled CPUs then this problem is already there without this
patch.

Example:

1. 1st CPU gets lock X and panics
2. 2nd CPU is disabled and gets lock X
3. 1st CPU calls smp_send_stop()
   -> 2nd CPU loops disabled and can't be stopped

Michael



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-10-31  9:57     ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-10-31  9:57 UTC (permalink / raw)
  To: Andrew Morton
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

Hello Andrew,

On Fri, 2011-10-28 at 16:11 -0700, Andrew Morton wrote:

[snip]

> Should this be done earlier in the function?  As it stands we'll have
> multiple CPUs scribbling on buf[] at the same time and all trying to
> print the same thing at the same time, dumping their stacks, etc. 
> Perhaps it would be better to single-thread all that stuff

My fist patch took the spinlock at the beginning of panic(). But then
Eric asked, if it wouldn't be better to get both panic printk's and I
agreed.

> Also...  this patch affects all CPU architectures, all configs, etc. 
> So we're expecting that every architecture's smp_send_stop() is able to
> stop a CPU which is spinning in spin_lock(), possibly with local
> interrupts disabled.  Will this work?

At least on s390 it will work. If there are architectures that can't
stop disabled CPUs then this problem is already there without this
patch.

Example:

1. 1st CPU gets lock X and panics
2. 2nd CPU is disabled and gets lock X
3. 1st CPU calls smp_send_stop()
   -> 2nd CPU loops disabled and can't be stopped

Michael



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-10-31  9:57     ` Michael Holzheu
@ 2011-10-31 10:39       ` Andrew Morton
  -1 siblings, 0 replies; 41+ messages in thread
From: Andrew Morton @ 2011-10-31 10:39 UTC (permalink / raw)
  To: holzheu
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:

> > Should this be done earlier in the function?  As it stands we'll have
> > multiple CPUs scribbling on buf[] at the same time and all trying to
> > print the same thing at the same time, dumping their stacks, etc. 
> > Perhaps it would be better to single-thread all that stuff
> 
> My fist patch took the spinlock at the beginning of panic(). But then
> Eric asked, if it wouldn't be better to get both panic printk's and I
> agreed.

Hm, why?  It will make a big mess.

> > Also...  this patch affects all CPU architectures, all configs, etc. 
> > So we're expecting that every architecture's smp_send_stop() is able to
> > stop a CPU which is spinning in spin_lock(), possibly with local
> > interrupts disabled.  Will this work?
> 
> At least on s390 it will work. If there are architectures that can't
> stop disabled CPUs then this problem is already there without this
> patch.
> 
> Example:
> 
> 1. 1st CPU gets lock X and panics
> 2. 2nd CPU is disabled and gets lock X

(irq-disabled)

> 3. 1st CPU calls smp_send_stop()
>    -> 2nd CPU loops disabled and can't be stopped

Well OK.  Maybe some architectures do have this problem - who would
notice?  If that is the case, we just made the failure cases much more
common.  Could you check, please?


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-10-31 10:39       ` Andrew Morton
  0 siblings, 0 replies; 41+ messages in thread
From: Andrew Morton @ 2011-10-31 10:39 UTC (permalink / raw)
  To: holzheu
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:

> > Should this be done earlier in the function?  As it stands we'll have
> > multiple CPUs scribbling on buf[] at the same time and all trying to
> > print the same thing at the same time, dumping their stacks, etc. 
> > Perhaps it would be better to single-thread all that stuff
> 
> My fist patch took the spinlock at the beginning of panic(). But then
> Eric asked, if it wouldn't be better to get both panic printk's and I
> agreed.

Hm, why?  It will make a big mess.

> > Also...  this patch affects all CPU architectures, all configs, etc. 
> > So we're expecting that every architecture's smp_send_stop() is able to
> > stop a CPU which is spinning in spin_lock(), possibly with local
> > interrupts disabled.  Will this work?
> 
> At least on s390 it will work. If there are architectures that can't
> stop disabled CPUs then this problem is already there without this
> patch.
> 
> Example:
> 
> 1. 1st CPU gets lock X and panics
> 2. 2nd CPU is disabled and gets lock X

(irq-disabled)

> 3. 1st CPU calls smp_send_stop()
>    -> 2nd CPU loops disabled and can't be stopped

Well OK.  Maybe some architectures do have this problem - who would
notice?  If that is the case, we just made the failure cases much more
common.  Could you check, please?


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-10-31 10:39       ` Andrew Morton
@ 2011-10-31 12:34         ` Michael Holzheu
  -1 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-10-31 12:34 UTC (permalink / raw)
  To: Andrew Morton, linux-arch
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

Hello Andrew, hello linux-arch,

On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> 
> > > Should this be done earlier in the function?  As it stands we'll have
> > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > print the same thing at the same time, dumping their stacks, etc. 
> > > Perhaps it would be better to single-thread all that stuff
> > 
> > My fist patch took the spinlock at the beginning of panic(). But then
> > Eric asked, if it wouldn't be better to get both panic printk's and I
> > agreed.
> 
> Hm, why?  It will make a big mess.

@Andrew:

I thought it would be good to have both messages and it would be good to
change the panic behavior as less as possible...

But ok, I have no problem with getting the lock at the beginning of
panic(). Below, I attached the updated patch.

> > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > So we're expecting that every architecture's smp_send_stop() is able to
> > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > interrupts disabled.  Will this work?
> > 
> > At least on s390 it will work. If there are architectures that can't
> > stop disabled CPUs then this problem is already there without this
> > patch.
> > 
> > Example:
> > 
> > 1. 1st CPU gets lock X and panics
> > 2. 2nd CPU is disabled and gets lock X
> 
> (irq-disabled)
> 
> > 3. 1st CPU calls smp_send_stop()
> >    -> 2nd CPU loops disabled and can't be stopped
> 
> Well OK.  Maybe some architectures do have this problem - who would
> notice?  If that is the case, we just made the failure cases much more
> common.  Could you check, please?

@linux-arch: 

This patch introduces a spinlock to prevent parallel execution of the
panic code. Andrew pointed out that this might be a problem for
architectures that can't do smp_send_stop() on remote CPUs that have
interrupts disabled. When irq-disabled CPUs execute panic() in parallel,
we then would have looping CPUs.

So please speak up if somebody has a problem with this patch!

Michael
---
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +69,12 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic all other CPUs will wait on
+	 * the panic_lock. They are stopped afterwards by smp_send_stop().
 	 */
-	preempt_disable();
+	spin_lock_irq(&panic_lock);
 
 	console_verbose();
 	bust_spinlocks(1);



^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-10-31 12:34         ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-10-31 12:34 UTC (permalink / raw)
  To: Andrew Morton, linux-arch
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal

Hello Andrew, hello linux-arch,

On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> 
> > > Should this be done earlier in the function?  As it stands we'll have
> > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > print the same thing at the same time, dumping their stacks, etc. 
> > > Perhaps it would be better to single-thread all that stuff
> > 
> > My fist patch took the spinlock at the beginning of panic(). But then
> > Eric asked, if it wouldn't be better to get both panic printk's and I
> > agreed.
> 
> Hm, why?  It will make a big mess.

@Andrew:

I thought it would be good to have both messages and it would be good to
change the panic behavior as less as possible...

But ok, I have no problem with getting the lock at the beginning of
panic(). Below, I attached the updated patch.

> > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > So we're expecting that every architecture's smp_send_stop() is able to
> > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > interrupts disabled.  Will this work?
> > 
> > At least on s390 it will work. If there are architectures that can't
> > stop disabled CPUs then this problem is already there without this
> > patch.
> > 
> > Example:
> > 
> > 1. 1st CPU gets lock X and panics
> > 2. 2nd CPU is disabled and gets lock X
> 
> (irq-disabled)
> 
> > 3. 1st CPU calls smp_send_stop()
> >    -> 2nd CPU loops disabled and can't be stopped
> 
> Well OK.  Maybe some architectures do have this problem - who would
> notice?  If that is the case, we just made the failure cases much more
> common.  Could you check, please?

@linux-arch: 

This patch introduces a spinlock to prevent parallel execution of the
panic code. Andrew pointed out that this might be a problem for
architectures that can't do smp_send_stop() on remote CPUs that have
interrupts disabled. When irq-disabled CPUs execute panic() in parallel,
we then would have looping CPUs.

So please speak up if somebody has a problem with this patch!

Michael
---
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +69,12 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic all other CPUs will wait on
+	 * the panic_lock. They are stopped afterwards by smp_send_stop().
 	 */
-	preempt_disable();
+	spin_lock_irq(&panic_lock);
 
 	console_verbose();
 	bust_spinlocks(1);



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-10-31 12:34         ` Michael Holzheu
@ 2011-11-01 20:04           ` Don Zickus
  -1 siblings, 0 replies; 41+ messages in thread
From: Don Zickus @ 2011-11-01 20:04 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: Andrew Morton, linux-arch, heiko.carstens, kexec, linux-kernel,
	Eric W. Biederman, schwidefsky, Vivek Goyal

On Mon, Oct 31, 2011 at 01:34:19PM +0100, Michael Holzheu wrote:
> Hello Andrew, hello linux-arch,
> 
> > Well OK.  Maybe some architectures do have this problem - who would
> > notice?  If that is the case, we just made the failure cases much more
> > common.  Could you check, please?
> 
> @linux-arch: 
> 
> This patch introduces a spinlock to prevent parallel execution of the
> panic code. Andrew pointed out that this might be a problem for
> architectures that can't do smp_send_stop() on remote CPUs that have
> interrupts disabled. When irq-disabled CPUs execute panic() in parallel,
> we then would have looping CPUs.

x86 has such problem and I posted a patch recently to fix it

https://lkml.org/lkml/2011/10/13/426

Cheers,
Don

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-01 20:04           ` Don Zickus
  0 siblings, 0 replies; 41+ messages in thread
From: Don Zickus @ 2011-11-01 20:04 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: linux-arch, heiko.carstens, kexec, linux-kernel,
	Eric W. Biederman, schwidefsky, Andrew Morton, Vivek Goyal

On Mon, Oct 31, 2011 at 01:34:19PM +0100, Michael Holzheu wrote:
> Hello Andrew, hello linux-arch,
> 
> > Well OK.  Maybe some architectures do have this problem - who would
> > notice?  If that is the case, we just made the failure cases much more
> > common.  Could you check, please?
> 
> @linux-arch: 
> 
> This patch introduces a spinlock to prevent parallel execution of the
> panic code. Andrew pointed out that this might be a problem for
> architectures that can't do smp_send_stop() on remote CPUs that have
> interrupts disabled. When irq-disabled CPUs execute panic() in parallel,
> we then would have looping CPUs.

x86 has such problem and I posted a patch recently to fix it

https://lkml.org/lkml/2011/10/13/426

Cheers,
Don

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-02 10:03             ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-02 10:03 UTC (permalink / raw)
  To: Don Zickus
  Cc: Andrew Morton, linux-arch, heiko.carstens, kexec, linux-kernel,
	Eric W. Biederman, schwidefsky, Vivek Goyal

On Tue, 2011-11-01 at 16:04 -0400, Don Zickus wrote:
> On Mon, Oct 31, 2011 at 01:34:19PM +0100, Michael Holzheu wrote:
> > Hello Andrew, hello linux-arch,
> > 
> > > Well OK.  Maybe some architectures do have this problem - who would
> > > notice?  If that is the case, we just made the failure cases much more
> > > common.  Could you check, please?
> > 
> > @linux-arch: 
> > 
> > This patch introduces a spinlock to prevent parallel execution of the
> > panic code. Andrew pointed out that this might be a problem for
> > architectures that can't do smp_send_stop() on remote CPUs that have
> > interrupts disabled. When irq-disabled CPUs execute panic() in parallel,
> > we then would have looping CPUs.
> 
> x86 has such problem and I posted a patch recently to fix it
> 
> https://lkml.org/lkml/2011/10/13/426

Ok good, so with this patch x86 has no problem with the panic spinlock.
Anybody else?

Instead of introducing the panic lock, as an alternative we could move
smp_send_stop() to the beginning of panic(). Eric told me that the
function is currently "insufficiently reliable" for that, but perhaps we
could make it more reliable.

Michael




^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-02 10:03             ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-02 10:03 UTC (permalink / raw)
  To: Don Zickus
  Cc: linux-arch-u79uwXL29TY76Z2rM5mHXA,
	heiko.carstens-tA70FqPdS9bQT0dZR+AlfA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Eric W. Biederman,
	schwidefsky-tA70FqPdS9bQT0dZR+AlfA, Andrew Morton, Vivek Goyal

On Tue, 2011-11-01 at 16:04 -0400, Don Zickus wrote:
> On Mon, Oct 31, 2011 at 01:34:19PM +0100, Michael Holzheu wrote:
> > Hello Andrew, hello linux-arch,
> > 
> > > Well OK.  Maybe some architectures do have this problem - who would
> > > notice?  If that is the case, we just made the failure cases much more
> > > common.  Could you check, please?
> > 
> > @linux-arch: 
> > 
> > This patch introduces a spinlock to prevent parallel execution of the
> > panic code. Andrew pointed out that this might be a problem for
> > architectures that can't do smp_send_stop() on remote CPUs that have
> > interrupts disabled. When irq-disabled CPUs execute panic() in parallel,
> > we then would have looping CPUs.
> 
> x86 has such problem and I posted a patch recently to fix it
> 
> https://lkml.org/lkml/2011/10/13/426

Ok good, so with this patch x86 has no problem with the panic spinlock.
Anybody else?

Instead of introducing the panic lock, as an alternative we could move
smp_send_stop() to the beginning of panic(). Eric told me that the
function is currently "insufficiently reliable" for that, but perhaps we
could make it more reliable.

Michael

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-02 10:03             ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-02 10:03 UTC (permalink / raw)
  To: Don Zickus
  Cc: linux-arch, heiko.carstens, kexec, linux-kernel,
	Eric W. Biederman, schwidefsky, Andrew Morton, Vivek Goyal

On Tue, 2011-11-01 at 16:04 -0400, Don Zickus wrote:
> On Mon, Oct 31, 2011 at 01:34:19PM +0100, Michael Holzheu wrote:
> > Hello Andrew, hello linux-arch,
> > 
> > > Well OK.  Maybe some architectures do have this problem - who would
> > > notice?  If that is the case, we just made the failure cases much more
> > > common.  Could you check, please?
> > 
> > @linux-arch: 
> > 
> > This patch introduces a spinlock to prevent parallel execution of the
> > panic code. Andrew pointed out that this might be a problem for
> > architectures that can't do smp_send_stop() on remote CPUs that have
> > interrupts disabled. When irq-disabled CPUs execute panic() in parallel,
> > we then would have looping CPUs.
> 
> x86 has such problem and I posted a patch recently to fix it
> 
> https://lkml.org/lkml/2011/10/13/426

Ok good, so with this patch x86 has no problem with the panic spinlock.
Anybody else?

Instead of introducing the panic lock, as an alternative we could move
smp_send_stop() to the beginning of panic(). Eric told me that the
function is currently "insufficiently reliable" for that, but perhaps we
could make it more reliable.

Michael




_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-02 10:03             ` Michael Holzheu
@ 2011-11-02 20:57               ` Luck, Tony
  -1 siblings, 0 replies; 41+ messages in thread
From: Luck, Tony @ 2011-11-02 20:57 UTC (permalink / raw)
  To: holzheu, Don Zickus
  Cc: Andrew Morton, linux-arch, heiko.carstens, kexec, linux-kernel,
	Eric W. Biederman, schwidefsky, Vivek Goyal

> Instead of introducing the panic lock, as an alternative we could move
> smp_send_stop() to the beginning of panic(). Eric told me that the
> function is currently "insufficiently reliable" for that, but perhaps we
> could make it more reliable.

That's tough to do.  We are in panic because something went horribly
wrong somewhere in the kernel - so we can make few assumptions about
which subsystems are still working. In the worst case (for this example)
our panic was caused by a failure in the code that sends cross-processor
interrupts ... so calling that same code to stop the other cpus is
likely to run into the same problem - perhaps causing a nested panic.

So what looks like a good fix for some panic scenarios actually makes
others worse.

-Tony

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-02 20:57               ` Luck, Tony
  0 siblings, 0 replies; 41+ messages in thread
From: Luck, Tony @ 2011-11-02 20:57 UTC (permalink / raw)
  To: holzheu, Don Zickus
  Cc: linux-arch, heiko.carstens, kexec, linux-kernel,
	Eric W. Biederman, schwidefsky, Andrew Morton, Vivek Goyal

> Instead of introducing the panic lock, as an alternative we could move
> smp_send_stop() to the beginning of panic(). Eric told me that the
> function is currently "insufficiently reliable" for that, but perhaps we
> could make it more reliable.

That's tough to do.  We are in panic because something went horribly
wrong somewhere in the kernel - so we can make few assumptions about
which subsystems are still working. In the worst case (for this example)
our panic was caused by a failure in the code that sends cross-processor
interrupts ... so calling that same code to stop the other cpus is
likely to run into the same problem - perhaps causing a nested panic.

So what looks like a good fix for some panic scenarios actually makes
others worse.

-Tony

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-10-31 10:39       ` Andrew Morton
@ 2011-11-03 10:07         ` Michael Holzheu
  -1 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-03 10:07 UTC (permalink / raw)
  To: Andrew Morton
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal, Don Zickus, Luck, Tony, linux-arch

Hello Andrew,

On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> 
> > > Should this be done earlier in the function?  As it stands we'll have
> > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > print the same thing at the same time, dumping their stacks, etc. 
> > > Perhaps it would be better to single-thread all that stuff
> > 
> > My fist patch took the spinlock at the beginning of panic(). But then
> > Eric asked, if it wouldn't be better to get both panic printk's and I
> > agreed.
> 
> Hm, why?  It will make a big mess.
> 
> > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > So we're expecting that every architecture's smp_send_stop() is able to
> > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > interrupts disabled.  Will this work?
> > 
> > At least on s390 it will work. If there are architectures that can't
> > stop disabled CPUs then this problem is already there without this
> > patch.
> > 
> > Example:
> > 
> > 1. 1st CPU gets lock X and panics
> > 2. 2nd CPU is disabled and gets lock X
> 
> (irq-disabled)
> 
> > 3. 1st CPU calls smp_send_stop()
> >    -> 2nd CPU loops disabled and can't be stopped
> 
> Well OK.  Maybe some architectures do have this problem - who would
> notice?  If that is the case, we just made the failure cases much more
> common.

Ok, next idea: What, if the CPUs wait irq-enabled in panic until they
get stopped by smp_send_stop()?

See patch below:
---
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +69,16 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic, all other CPUs will wait
+	 * until they are stopped by the 1st CPU with smp_send_stop().
 	 */
-	preempt_disable();
+	if (!spin_trylock(&panic_lock)) {
+		local_irq_enable();
+		while (1)
+			cpu_relax();
+	}
 
 	console_verbose();
 	bust_spinlocks(1);





^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-03 10:07         ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-03 10:07 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Don Zickus, linux-arch, Luck, Tony, heiko.carstens, kexec,
	linux-kernel, Eric W. Biederman, schwidefsky, Vivek Goyal

Hello Andrew,

On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> 
> > > Should this be done earlier in the function?  As it stands we'll have
> > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > print the same thing at the same time, dumping their stacks, etc. 
> > > Perhaps it would be better to single-thread all that stuff
> > 
> > My fist patch took the spinlock at the beginning of panic(). But then
> > Eric asked, if it wouldn't be better to get both panic printk's and I
> > agreed.
> 
> Hm, why?  It will make a big mess.
> 
> > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > So we're expecting that every architecture's smp_send_stop() is able to
> > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > interrupts disabled.  Will this work?
> > 
> > At least on s390 it will work. If there are architectures that can't
> > stop disabled CPUs then this problem is already there without this
> > patch.
> > 
> > Example:
> > 
> > 1. 1st CPU gets lock X and panics
> > 2. 2nd CPU is disabled and gets lock X
> 
> (irq-disabled)
> 
> > 3. 1st CPU calls smp_send_stop()
> >    -> 2nd CPU loops disabled and can't be stopped
> 
> Well OK.  Maybe some architectures do have this problem - who would
> notice?  If that is the case, we just made the failure cases much more
> common.

Ok, next idea: What, if the CPUs wait irq-enabled in panic until they
get stopped by smp_send_stop()?

See patch below:
---
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +69,16 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic, all other CPUs will wait
+	 * until they are stopped by the 1st CPU with smp_send_stop().
 	 */
-	preempt_disable();
+	if (!spin_trylock(&panic_lock)) {
+		local_irq_enable();
+		while (1)
+			cpu_relax();
+	}
 
 	console_verbose();
 	bust_spinlocks(1);





_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-03 10:07         ` Michael Holzheu
@ 2011-11-10  0:04           ` Andrew Morton
  -1 siblings, 0 replies; 41+ messages in thread
From: Andrew Morton @ 2011-11-10  0:04 UTC (permalink / raw)
  To: holzheu
  Cc: heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal, Don Zickus, Luck, Tony, linux-arch

On Thu, 03 Nov 2011 11:07:24 +0100
Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:

> Hello Andrew,
> 
> On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> > On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> > 
> > > > Should this be done earlier in the function?  As it stands we'll have
> > > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > > print the same thing at the same time, dumping their stacks, etc. 
> > > > Perhaps it would be better to single-thread all that stuff
> > > 
> > > My fist patch took the spinlock at the beginning of panic(). But then
> > > Eric asked, if it wouldn't be better to get both panic printk's and I
> > > agreed.
> > 
> > Hm, why?  It will make a big mess.

This, please?

> > > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > > So we're expecting that every architecture's smp_send_stop() is able to
> > > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > > interrupts disabled.  Will this work?
> > > 
> > > At least on s390 it will work. If there are architectures that can't
> > > stop disabled CPUs then this problem is already there without this
> > > patch.
> > > 
> > > Example:
> > > 
> > > 1. 1st CPU gets lock X and panics
> > > 2. 2nd CPU is disabled and gets lock X
> > 
> > (irq-disabled)
> > 
> > > 3. 1st CPU calls smp_send_stop()
> > >    -> 2nd CPU loops disabled and can't be stopped
> > 
> > Well OK.  Maybe some architectures do have this problem - who would
> > notice?  If that is the case, we just made the failure cases much more
> > common.
> 
> Ok, next idea: What, if the CPUs wait irq-enabled in panic until they
> get stopped by smp_send_stop()?
> 
> See patch below:
> ---
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic
> 
> When two CPUs call panic at the same time there is a possible race
> condition that can stop kdump.  The first CPU calls crash_kexec() and the
> second CPU calls smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU.  So the second CPU stops the first CPU and therefore
> kdump fails:
> 
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> 
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> 
> This patch fixes the problem by introducing a spinlock in panic that
> allows only one CPU to process crash_kexec() and the subsequent panic
> code.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/panic.c |   11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
>   */
>  NORET_TYPE void panic(const char * fmt, ...)
>  {
> +	static DEFINE_SPINLOCK(panic_lock);
>  	static char buf[1024];
>  	va_list args;
>  	long i, i_next = 0;
> @@ -68,8 +69,16 @@ NORET_TYPE void panic(const char * fmt,
>  	 * It's possible to come here directly from a panic-assertion and
>  	 * not have preempt disabled. Some functions called from here want
>  	 * preempt to be disabled. No point enabling it later though...
> +	 *
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic, all other CPUs will wait
> +	 * until they are stopped by the 1st CPU with smp_send_stop().
>  	 */
> -	preempt_disable();
> +	if (!spin_trylock(&panic_lock)) {
> +		local_irq_enable();
> +		while (1)
> +			cpu_relax();
> +	}

Looks worse ;) Unconditionally enabling interrupts in a panic situation
could cause all sorts of havoc, with other interrupts being taken or
same interrupts being retaken, etc.

Ho hum, I guess we stick with the original patch.  It *should* work, as
long as all archtectures are doing the expected thing.  But in this
situation it is bad of us to just hope that the architectures are doing
this.  We should go and find out, rather than waiting for bug reports
to come in.  Especially because in this case, bugs will take a very
long time indeed to even be noticed.

One way to resolve this would be to ask the various arch maintainers!

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-10  0:04           ` Andrew Morton
  0 siblings, 0 replies; 41+ messages in thread
From: Andrew Morton @ 2011-11-10  0:04 UTC (permalink / raw)
  To: holzheu
  Cc: Don Zickus, linux-arch, Luck, Tony, heiko.carstens, kexec,
	linux-kernel, Eric W. Biederman, schwidefsky, Vivek Goyal

On Thu, 03 Nov 2011 11:07:24 +0100
Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:

> Hello Andrew,
> 
> On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> > On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> > 
> > > > Should this be done earlier in the function?  As it stands we'll have
> > > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > > print the same thing at the same time, dumping their stacks, etc. 
> > > > Perhaps it would be better to single-thread all that stuff
> > > 
> > > My fist patch took the spinlock at the beginning of panic(). But then
> > > Eric asked, if it wouldn't be better to get both panic printk's and I
> > > agreed.
> > 
> > Hm, why?  It will make a big mess.

This, please?

> > > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > > So we're expecting that every architecture's smp_send_stop() is able to
> > > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > > interrupts disabled.  Will this work?
> > > 
> > > At least on s390 it will work. If there are architectures that can't
> > > stop disabled CPUs then this problem is already there without this
> > > patch.
> > > 
> > > Example:
> > > 
> > > 1. 1st CPU gets lock X and panics
> > > 2. 2nd CPU is disabled and gets lock X
> > 
> > (irq-disabled)
> > 
> > > 3. 1st CPU calls smp_send_stop()
> > >    -> 2nd CPU loops disabled and can't be stopped
> > 
> > Well OK.  Maybe some architectures do have this problem - who would
> > notice?  If that is the case, we just made the failure cases much more
> > common.
> 
> Ok, next idea: What, if the CPUs wait irq-enabled in panic until they
> get stopped by smp_send_stop()?
> 
> See patch below:
> ---
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic
> 
> When two CPUs call panic at the same time there is a possible race
> condition that can stop kdump.  The first CPU calls crash_kexec() and the
> second CPU calls smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU.  So the second CPU stops the first CPU and therefore
> kdump fails:
> 
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> 
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> 
> This patch fixes the problem by introducing a spinlock in panic that
> allows only one CPU to process crash_kexec() and the subsequent panic
> code.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/panic.c |   11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
>   */
>  NORET_TYPE void panic(const char * fmt, ...)
>  {
> +	static DEFINE_SPINLOCK(panic_lock);
>  	static char buf[1024];
>  	va_list args;
>  	long i, i_next = 0;
> @@ -68,8 +69,16 @@ NORET_TYPE void panic(const char * fmt,
>  	 * It's possible to come here directly from a panic-assertion and
>  	 * not have preempt disabled. Some functions called from here want
>  	 * preempt to be disabled. No point enabling it later though...
> +	 *
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic, all other CPUs will wait
> +	 * until they are stopped by the 1st CPU with smp_send_stop().
>  	 */
> -	preempt_disable();
> +	if (!spin_trylock(&panic_lock)) {
> +		local_irq_enable();
> +		while (1)
> +			cpu_relax();
> +	}

Looks worse ;) Unconditionally enabling interrupts in a panic situation
could cause all sorts of havoc, with other interrupts being taken or
same interrupts being retaken, etc.

Ho hum, I guess we stick with the original patch.  It *should* work, as
long as all archtectures are doing the expected thing.  But in this
situation it is bad of us to just hope that the architectures are doing
this.  We should go and find out, rather than waiting for bug reports
to come in.  Especially because in this case, bugs will take a very
long time indeed to even be noticed.

One way to resolve this would be to ask the various arch maintainers!

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-10  0:04           ` Andrew Morton
@ 2011-11-10 14:17             ` Américo Wang
  -1 siblings, 0 replies; 41+ messages in thread
From: Américo Wang @ 2011-11-10 14:17 UTC (permalink / raw)
  To: Andrew Morton
  Cc: holzheu, heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal, Don Zickus, Luck, Tony, linux-arch

On Thu, Nov 10, 2011 at 8:04 AM, Andrew Morton
<akpm@linux-foundation.org> wrote:
>
> Ho hum, I guess we stick with the original patch.  It *should* work, as
> long as all archtectures are doing the expected thing.  But in this
> situation it is bad of us to just hope that the architectures are doing
> this.  We should go and find out, rather than waiting for bug reports
> to come in.  Especially because in this case, bugs will take a very
> long time indeed to even be noticed.
>
> One way to resolve this would be to ask the various arch maintainers!

At least we can add the spin_lock just for x86 and s390, and leave
a big comment saying we are waiting for the other arch to be fixed...

Thanks.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-10 14:17             ` Américo Wang
  0 siblings, 0 replies; 41+ messages in thread
From: Américo Wang @ 2011-11-10 14:17 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Don Zickus, linux-arch, Luck, Tony, heiko.carstens, kexec,
	linux-kernel, Eric W. Biederman, schwidefsky, holzheu,
	Vivek Goyal

On Thu, Nov 10, 2011 at 8:04 AM, Andrew Morton
<akpm@linux-foundation.org> wrote:
>
> Ho hum, I guess we stick with the original patch.  It *should* work, as
> long as all archtectures are doing the expected thing.  But in this
> situation it is bad of us to just hope that the architectures are doing
> this.  We should go and find out, rather than waiting for bug reports
> to come in.  Especially because in this case, bugs will take a very
> long time indeed to even be noticed.
>
> One way to resolve this would be to ask the various arch maintainers!

At least we can add the spin_lock just for x86 and s390, and leave
a big comment saying we are waiting for the other arch to be fixed...

Thanks.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-10  0:04           ` Andrew Morton
@ 2011-11-10 14:22               ` Michael Holzheu
  -1 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-10 14:22 UTC (permalink / raw)
  To: Richard Henderson, Ivan Kokshaysky, Matt Turner, Russell King,
	Haavard Skinnemoen
  Cc: Don Zickus, linux-arch-u79uwXL29TY76Z2rM5mHXA, Luck, Tony,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Eric W. Biederman,
	Andrew Morton, Vivek Goyal

On Wed, 2011-11-09 at 16:04 -0800, Andrew Morton wrote:
> On Thu, 03 Nov 2011 11:07:24 +0100
> Michael Holzheu <holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:

[snip]

> Ho hum, I guess we stick with the original patch.  It *should* work, as
> long as all archtectures are doing the expected thing.  But in this
> situation it is bad of us to just hope that the architectures are doing
> this.  We should go and find out, rather than waiting for bug reports
> to come in.  Especially because in this case, bugs will take a very
> long time indeed to even be noticed.
> 
> One way to resolve this would be to ask the various arch maintainers!

Hello arch maintainers (from scripts/get_maintainer.pl),

Andrew asked me to contact you in this case.

The main concern of the patch below is that smp_send_stop() might not be
able to stop irq-disabled CPUs. So when two CPUs enter in parallel
panic() and the 2nd one has irqs disabled, with my patch below, perhaps
the 2nd CPU can't be stopped. On s390 and also on x86 (with a patch from
Don Zickus) this is not a problem.

Could you please look at the patch and tell me, if it will work on your
architecture or not. If not, perhaps you have a better idea to solve the
problem.

Michael
---
From: Michael Holzheu <holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>

When two CPUs call panic at the same time there is a
possible race condition that can stop kdump. The first
CPU calls crash_kexec() and the second CPU calls
smp_send_stop() in panic() before crash_kexec() finished
on the first CPU. So the second CPU stops the first CPU
and therefore kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in
panic that allows only one CPU to process crash_kexec() and
the subsequent panic code.

Signed-off-by: Michael Holzheu <holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 kernel/panic.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
 #endif
 
 	/*
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic all other CPUs will wait on
+	 * the panic_lock. They are stopped afterwards by smp_send_stop().
+	 */
+	spin_lock(&panic_lock);
+
+	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
 	 * Do we want to call this before we try to display a message?

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-10 14:22               ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-10 14:22 UTC (permalink / raw)
  To: Richard Henderson, Ivan Kokshaysky, Matt Turner, Russell King,
	Haavard Skinnemoen, Hans-Christian Egtvedt, Mike Frysinger,
	Mikael Starvik, Jesper Nilsson, David Howells, Yoshinori Sato,
	Richard Kuo, Tony Luck, Fenghua Yu, Hirokazu Takata,
	Geert Uytterhoeven, Michal Simek, Ralf Baechle, Koichi Yasutake,
	Jonas Bonn, Kyle McMartin, Helge Deller, James E.J. Bottomley,
	Benjamin Herrenschmidt, Paul Mackerras, Martin Schwidefsky,
	Heiko Carstens, Chen Liqin, Lennox Wu, Paul Mundt,
	David S. Miller, Chris Metcalf, Jeff Dike, Richard Weinberger,
	Guan Xuetao, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
	Chris Zankel, Peter Zijlstra
  Cc: Don Zickus, linux-arch, Luck, Tony, kexec, linux-kernel,
	Eric W. Biederman, Andrew Morton, Vivek Goyal

On Wed, 2011-11-09 at 16:04 -0800, Andrew Morton wrote:
> On Thu, 03 Nov 2011 11:07:24 +0100
> Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:

[snip]

> Ho hum, I guess we stick with the original patch.  It *should* work, as
> long as all archtectures are doing the expected thing.  But in this
> situation it is bad of us to just hope that the architectures are doing
> this.  We should go and find out, rather than waiting for bug reports
> to come in.  Especially because in this case, bugs will take a very
> long time indeed to even be noticed.
> 
> One way to resolve this would be to ask the various arch maintainers!

Hello arch maintainers (from scripts/get_maintainer.pl),

Andrew asked me to contact you in this case.

The main concern of the patch below is that smp_send_stop() might not be
able to stop irq-disabled CPUs. So when two CPUs enter in parallel
panic() and the 2nd one has irqs disabled, with my patch below, perhaps
the 2nd CPU can't be stopped. On s390 and also on x86 (with a patch from
Don Zickus) this is not a problem.

Could you please look at the patch and tell me, if it will work on your
architecture or not. If not, perhaps you have a better idea to solve the
problem.

Michael
---
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

When two CPUs call panic at the same time there is a
possible race condition that can stop kdump. The first
CPU calls crash_kexec() and the second CPU calls
smp_send_stop() in panic() before crash_kexec() finished
on the first CPU. So the second CPU stops the first CPU
and therefore kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in
panic that allows only one CPU to process crash_kexec() and
the subsequent panic code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -82,6 +83,13 @@ NORET_TYPE void panic(const char * fmt,
 #endif
 
 	/*
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic all other CPUs will wait on
+	 * the panic_lock. They are stopped afterwards by smp_send_stop().
+	 */
+	spin_lock(&panic_lock);
+
+	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
 	 * Do we want to call this before we try to display a message?






_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-10 14:22               ` Michael Holzheu
@ 2011-11-10 15:11                 ` Chris Metcalf
  -1 siblings, 0 replies; 41+ messages in thread
From: Chris Metcalf @ 2011-11-10 15:11 UTC (permalink / raw)
  To: holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Helge Deller, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, Matt Turner, Vivek Goyal,
	Haavard Skinnemoen

On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> On Wed, 2011-11-09 at 16:04 -0800, Andrew Morton wrote:
>> On Thu, 03 Nov 2011 11:07:24 +0100
>> Michael Holzheu<holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>  wrote:
> [snip]
>
>> Ho hum, I guess we stick with the original patch.  It *should* work, as
>> long as all archtectures are doing the expected thing.  But in this
>> situation it is bad of us to just hope that the architectures are doing
>> this.  We should go and find out, rather than waiting for bug reports
>> to come in.  Especially because in this case, bugs will take a very
>> long time indeed to even be noticed.
>>
>> One way to resolve this would be to ask the various arch maintainers!
> Hello arch maintainers (from scripts/get_maintainer.pl),
>
> Andrew asked me to contact you in this case.
>
> The main concern of the patch below is that smp_send_stop() might not be
> able to stop irq-disabled CPUs. So when two CPUs enter in parallel
> panic() and the 2nd one has irqs disabled, with my patch below, perhaps
> the 2nd CPU can't be stopped. On s390 and also on x86 (with a patch from
> Don Zickus) this is not a problem.

On tile the smp_send_stop() is delivered via IPIs that respect irq 
disabling, i.e. we wouldn't handle the message on the 2nd cpu in your 
scenario above.

This may not be a problem on many architectures, though.  If one or more 
cpus is blocked in spin_lock(), that may be just as effective from a 
"machine halt" point of view as if those cpus had handled the smp_stop_cpu 
interrupt, which on tile just leaves the cpu with interrupts disabled 
anyway, though sitting on a lower-power "nap" instruction rather than 
spinning trying to acquire the lock.  (It may also be the case that on some 
architectures you need to have shepherded all the cpus into the "machine 
halt" state before you can reboot them, though that's not true on tile.)

If a cleaner API seems useful (either for power reasons or restartability 
or whatever), I suppose a standard global function name could be specified 
that's the thing you execute when you get an smp_send_stop IPI (in tile's 
case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
just do an atomic_inc_return() of a global panic counter, and if it wasn't 
the first panicking cpu, call directly into the smp_stop handler routine to 
quiesce itself.  Then the panicking cpu could finish whatever it needs to 
do and then halt, reboot, etc., all the cpus.

For what it's worth we do see the condition sometimes when a bunch of cpus 
try to panic near-simultaneously and you get crazy interleaved panic 
output, so I'd certainly support some patch of this nature.
-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-10 15:11                 ` Chris Metcalf
  0 siblings, 0 replies; 41+ messages in thread
From: Chris Metcalf @ 2011-11-10 15:11 UTC (permalink / raw)
  To: holzheu
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Helge Deller, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven, linux-arch, Matt Turner,
	Vivek Goyal, Haavard Skinnemoen, Don Zickus, Fenghua Yu,
	Mike Frysinger, Peter Zijlstra, Jeff Dike, Mikael Starvik,
	Ivan Kokshaysky, Thomas Gleixner, Richard Henderson,
	Chris Zankel, Michal Simek, Tony Luck, kexec, linux-kernel,
	Ralf Baechle, Richard Kuo, Kyle McMartin, Paul Mundt,
	Eric W. Biederman, Martin Schwidefsky, Andrew Morton,
	Koichi Yasutake, Hirokazu Takata

On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> On Wed, 2011-11-09 at 16:04 -0800, Andrew Morton wrote:
>> On Thu, 03 Nov 2011 11:07:24 +0100
>> Michael Holzheu<holzheu@linux.vnet.ibm.com>  wrote:
> [snip]
>
>> Ho hum, I guess we stick with the original patch.  It *should* work, as
>> long as all archtectures are doing the expected thing.  But in this
>> situation it is bad of us to just hope that the architectures are doing
>> this.  We should go and find out, rather than waiting for bug reports
>> to come in.  Especially because in this case, bugs will take a very
>> long time indeed to even be noticed.
>>
>> One way to resolve this would be to ask the various arch maintainers!
> Hello arch maintainers (from scripts/get_maintainer.pl),
>
> Andrew asked me to contact you in this case.
>
> The main concern of the patch below is that smp_send_stop() might not be
> able to stop irq-disabled CPUs. So when two CPUs enter in parallel
> panic() and the 2nd one has irqs disabled, with my patch below, perhaps
> the 2nd CPU can't be stopped. On s390 and also on x86 (with a patch from
> Don Zickus) this is not a problem.

On tile the smp_send_stop() is delivered via IPIs that respect irq 
disabling, i.e. we wouldn't handle the message on the 2nd cpu in your 
scenario above.

This may not be a problem on many architectures, though.  If one or more 
cpus is blocked in spin_lock(), that may be just as effective from a 
"machine halt" point of view as if those cpus had handled the smp_stop_cpu 
interrupt, which on tile just leaves the cpu with interrupts disabled 
anyway, though sitting on a lower-power "nap" instruction rather than 
spinning trying to acquire the lock.  (It may also be the case that on some 
architectures you need to have shepherded all the cpus into the "machine 
halt" state before you can reboot them, though that's not true on tile.)

If a cleaner API seems useful (either for power reasons or restartability 
or whatever), I suppose a standard global function name could be specified 
that's the thing you execute when you get an smp_send_stop IPI (in tile's 
case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
just do an atomic_inc_return() of a global panic counter, and if it wasn't 
the first panicking cpu, call directly into the smp_stop handler routine to 
quiesce itself.  Then the panicking cpu could finish whatever it needs to 
do and then halt, reboot, etc., all the cpus.

For what it's worth we do see the condition sometimes when a bunch of cpus 
try to panic near-simultaneously and you get crazy interleaved panic 
output, so I'd certainly support some patch of this nature.
-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-10  0:04           ` Andrew Morton
@ 2011-11-10 15:31             ` James Bottomley
  -1 siblings, 0 replies; 41+ messages in thread
From: James Bottomley @ 2011-11-10 15:31 UTC (permalink / raw)
  To: Andrew Morton
  Cc: holzheu, heiko.carstens, kexec, linux-kernel, Eric W. Biederman,
	schwidefsky, Vivek Goyal, Don Zickus, Luck, Tony, linux-arch

On Wed, 2011-11-09 at 16:04 -0800, Andrew Morton wrote:
> On Thu, 03 Nov 2011 11:07:24 +0100
> Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> 
> > Hello Andrew,
> > 
> > On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> > > On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> > > 
> > > > > Should this be done earlier in the function?  As it stands we'll have
> > > > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > > > print the same thing at the same time, dumping their stacks, etc. 
> > > > > Perhaps it would be better to single-thread all that stuff
> > > > 
> > > > My fist patch took the spinlock at the beginning of panic(). But then
> > > > Eric asked, if it wouldn't be better to get both panic printk's and I
> > > > agreed.
> > > 
> > > Hm, why?  It will make a big mess.
> 
> This, please?
> 
> > > > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > > > So we're expecting that every architecture's smp_send_stop() is able to
> > > > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > > > interrupts disabled.  Will this work?
> > > > 
> > > > At least on s390 it will work. If there are architectures that can't
> > > > stop disabled CPUs then this problem is already there without this
> > > > patch.
> > > > 
> > > > Example:
> > > > 
> > > > 1. 1st CPU gets lock X and panics
> > > > 2. 2nd CPU is disabled and gets lock X
> > > 
> > > (irq-disabled)
> > > 
> > > > 3. 1st CPU calls smp_send_stop()
> > > >    -> 2nd CPU loops disabled and can't be stopped
> > > 
> > > Well OK.  Maybe some architectures do have this problem - who would
> > > notice?  If that is the case, we just made the failure cases much more
> > > common.
> > 
> > Ok, next idea: What, if the CPUs wait irq-enabled in panic until they
> > get stopped by smp_send_stop()?
> > 
> > See patch below:
> > ---
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic
> > 
> > When two CPUs call panic at the same time there is a possible race
> > condition that can stop kdump.  The first CPU calls crash_kexec() and the
> > second CPU calls smp_send_stop() in panic() before crash_kexec() finished
> > on the first CPU.  So the second CPU stops the first CPU and therefore
> > kdump fails:
> > 
> > 1st CPU:
> > panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> > 
> > 2nd CPU:
> > panic()->crash_kexec()->kexec_mutex already held by 1st CPU
> >        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> > 
> > This patch fixes the problem by introducing a spinlock in panic that
> > allows only one CPU to process crash_kexec() and the subsequent panic
> > code.
> > 
> > Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > ---
> >  kernel/panic.c |   11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > --- a/kernel/panic.c
> > +++ b/kernel/panic.c
> > @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
> >   */
> >  NORET_TYPE void panic(const char * fmt, ...)
> >  {
> > +	static DEFINE_SPINLOCK(panic_lock);
> >  	static char buf[1024];
> >  	va_list args;
> >  	long i, i_next = 0;
> > @@ -68,8 +69,16 @@ NORET_TYPE void panic(const char * fmt,
> >  	 * It's possible to come here directly from a panic-assertion and
> >  	 * not have preempt disabled. Some functions called from here want
> >  	 * preempt to be disabled. No point enabling it later though...
> > +	 *
> > +	 * Only one CPU is allowed to execute the panic code from here. For
> > +	 * multiple parallel invocations of panic, all other CPUs will wait
> > +	 * until they are stopped by the 1st CPU with smp_send_stop().
> >  	 */
> > -	preempt_disable();
> > +	if (!spin_trylock(&panic_lock)) {
> > +		local_irq_enable();
> > +		while (1)
> > +			cpu_relax();
> > +	}
> 
> Looks worse ;) Unconditionally enabling interrupts in a panic situation
> could cause all sorts of havoc, with other interrupts being taken or
> same interrupts being retaken, etc.
> 
> Ho hum, I guess we stick with the original patch. 

By original patch you mean the smp_send_stop() at the beginning of the
panic one (which isn't on linux-arch)?

>  It *should* work, as
> long as all archtectures are doing the expected thing.  But in this
> situation it is bad of us to just hope that the architectures are doing
> this.  We should go and find out, rather than waiting for bug reports
> to come in.  Especially because in this case, bugs will take a very
> long time indeed to even be noticed.
> 
> One way to resolve this would be to ask the various arch maintainers!

You're assuming we actually know.  On parisc, the IPI_STOP_CPU is
implemented, it's just it's not something we ever use (not even in the
shutdown path), so while I can tell you it *should* work (the code in
the IPI handler looks sane) ... we've never tested it.

James



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-10 15:31             ` James Bottomley
  0 siblings, 0 replies; 41+ messages in thread
From: James Bottomley @ 2011-11-10 15:31 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Don Zickus, linux-arch, Luck, Tony, heiko.carstens, kexec,
	linux-kernel, Eric W. Biederman, schwidefsky, holzheu,
	Vivek Goyal

On Wed, 2011-11-09 at 16:04 -0800, Andrew Morton wrote:
> On Thu, 03 Nov 2011 11:07:24 +0100
> Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> 
> > Hello Andrew,
> > 
> > On Mon, 2011-10-31 at 03:39 -0700, Andrew Morton wrote:
> > > On Mon, 31 Oct 2011 10:57:16 +0100 Michael Holzheu <holzheu@linux.vnet.ibm.com> wrote:
> > > 
> > > > > Should this be done earlier in the function?  As it stands we'll have
> > > > > multiple CPUs scribbling on buf[] at the same time and all trying to
> > > > > print the same thing at the same time, dumping their stacks, etc. 
> > > > > Perhaps it would be better to single-thread all that stuff
> > > > 
> > > > My fist patch took the spinlock at the beginning of panic(). But then
> > > > Eric asked, if it wouldn't be better to get both panic printk's and I
> > > > agreed.
> > > 
> > > Hm, why?  It will make a big mess.
> 
> This, please?
> 
> > > > > Also...  this patch affects all CPU architectures, all configs, etc. 
> > > > > So we're expecting that every architecture's smp_send_stop() is able to
> > > > > stop a CPU which is spinning in spin_lock(), possibly with local
> > > > > interrupts disabled.  Will this work?
> > > > 
> > > > At least on s390 it will work. If there are architectures that can't
> > > > stop disabled CPUs then this problem is already there without this
> > > > patch.
> > > > 
> > > > Example:
> > > > 
> > > > 1. 1st CPU gets lock X and panics
> > > > 2. 2nd CPU is disabled and gets lock X
> > > 
> > > (irq-disabled)
> > > 
> > > > 3. 1st CPU calls smp_send_stop()
> > > >    -> 2nd CPU loops disabled and can't be stopped
> > > 
> > > Well OK.  Maybe some architectures do have this problem - who would
> > > notice?  If that is the case, we just made the failure cases much more
> > > common.
> > 
> > Ok, next idea: What, if the CPUs wait irq-enabled in panic until they
> > get stopped by smp_send_stop()?
> > 
> > See patch below:
> > ---
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic
> > 
> > When two CPUs call panic at the same time there is a possible race
> > condition that can stop kdump.  The first CPU calls crash_kexec() and the
> > second CPU calls smp_send_stop() in panic() before crash_kexec() finished
> > on the first CPU.  So the second CPU stops the first CPU and therefore
> > kdump fails:
> > 
> > 1st CPU:
> > panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump
> > 
> > 2nd CPU:
> > panic()->crash_kexec()->kexec_mutex already held by 1st CPU
> >        ->smp_send_stop()-> stop 1st CPU (stop kdump)
> > 
> > This patch fixes the problem by introducing a spinlock in panic that
> > allows only one CPU to process crash_kexec() and the subsequent panic
> > code.
> > 
> > Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > ---
> >  kernel/panic.c |   11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > --- a/kernel/panic.c
> > +++ b/kernel/panic.c
> > @@ -59,6 +59,7 @@ EXPORT_SYMBOL(panic_blink);
> >   */
> >  NORET_TYPE void panic(const char * fmt, ...)
> >  {
> > +	static DEFINE_SPINLOCK(panic_lock);
> >  	static char buf[1024];
> >  	va_list args;
> >  	long i, i_next = 0;
> > @@ -68,8 +69,16 @@ NORET_TYPE void panic(const char * fmt,
> >  	 * It's possible to come here directly from a panic-assertion and
> >  	 * not have preempt disabled. Some functions called from here want
> >  	 * preempt to be disabled. No point enabling it later though...
> > +	 *
> > +	 * Only one CPU is allowed to execute the panic code from here. For
> > +	 * multiple parallel invocations of panic, all other CPUs will wait
> > +	 * until they are stopped by the 1st CPU with smp_send_stop().
> >  	 */
> > -	preempt_disable();
> > +	if (!spin_trylock(&panic_lock)) {
> > +		local_irq_enable();
> > +		while (1)
> > +			cpu_relax();
> > +	}
> 
> Looks worse ;) Unconditionally enabling interrupts in a panic situation
> could cause all sorts of havoc, with other interrupts being taken or
> same interrupts being retaken, etc.
> 
> Ho hum, I guess we stick with the original patch. 

By original patch you mean the smp_send_stop() at the beginning of the
panic one (which isn't on linux-arch)?

>  It *should* work, as
> long as all archtectures are doing the expected thing.  But in this
> situation it is bad of us to just hope that the architectures are doing
> this.  We should go and find out, rather than waiting for bug reports
> to come in.  Especially because in this case, bugs will take a very
> long time indeed to even be noticed.
> 
> One way to resolve this would be to ask the various arch maintainers!

You're assuming we actually know.  On parisc, the IPI_STOP_CPU is
implemented, it's just it's not something we ever use (not even in the
shutdown path), so while I can tell you it *should* work (the code in
the IPI handler looks sane) ... we've never tested it.

James



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-10 15:11                 ` Chris Metcalf
@ 2011-11-11 12:28                     ` Michael Holzheu
  -1 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-11 12:28 UTC (permalink / raw)
  To: Chris Metcalf
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Helge Deller, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, Matt Turner, Vivek Goyal,
	Haavard Skinnemoen

Hello Chris,

On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
> On 11/10/2011 9:22 AM, Michael Holzheu wrote:

[snip]

> If a cleaner API seems useful (either for power reasons or restartability 
> or whatever), I suppose a standard global function name could be specified 
> that's the thing you execute when you get an smp_send_stop IPI (in tile's 
> case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
> just do an atomic_inc_return() of a global panic counter, and if it wasn't 
> the first panicking cpu, call directly into the smp_stop handler routine to 
> quiesce itself.  Then the panicking cpu could finish whatever it needs to 
> do and then halt, reboot, etc., all the cpus.

Thanks for the info. So introducing a "weak" function that can stop the
CPU it is running on could solve the problem. Every architecture can
override the function with something appropriate. E.g. "tile" can use
the lower-power "nap" instruction there.

What about the following patch.

Michael
---
From: Michael Holzheu <holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

Signed-off-by: Michael Holzheu <holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 kernel/panic.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -49,6 +49,15 @@ static long no_blink(int state)
 long (*panic_blink)(int state);
 EXPORT_SYMBOL(panic_blink);
 
+/*
+ * Stop ourself in panic -- architecture code may override this
+ */
+void __attribute__ ((weak)) panic_smp_self_stop(void)
+{
+	while (1)
+		cpu_relax();
+}
+
 /**
  *	panic - halt the system
  *	@fmt: The text string to print
@@ -59,6 +68,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +78,14 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic, all other CPUs either
+	 * stop themself or will wait until they are stopped by the 1st CPU
+	 * with smp_send_stop().
 	 */
-	preempt_disable();
+	if (!spin_trylock(&panic_lock))
+		panic_smp_self_stop();
 
 	console_verbose();
 	bust_spinlocks(1);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-11 12:28                     ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-11 12:28 UTC (permalink / raw)
  To: Chris Metcalf
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Helge Deller, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven, linux-arch, Matt Turner,
	Vivek Goyal, Haavard Skinnemoen, Don Zickus, Fenghua Yu,
	Mike Frysinger, Peter Zijlstra, Jeff Dike, Mikael Starvik,
	Ivan Kokshaysky, Thomas Gleixner, Richard Henderson,
	Chris Zankel, Michal Simek, Tony Luck, kexec, linux-kernel,
	Ralf Baechle, Richard Kuo, Kyle McMartin, Paul Mundt,
	Eric W. Biederman, Martin Schwidefsky, Andrew Morton,
	Koichi Yasutake, Hirokazu Takata

Hello Chris,

On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
> On 11/10/2011 9:22 AM, Michael Holzheu wrote:

[snip]

> If a cleaner API seems useful (either for power reasons or restartability 
> or whatever), I suppose a standard global function name could be specified 
> that's the thing you execute when you get an smp_send_stop IPI (in tile's 
> case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
> just do an atomic_inc_return() of a global panic counter, and if it wasn't 
> the first panicking cpu, call directly into the smp_stop handler routine to 
> quiesce itself.  Then the panicking cpu could finish whatever it needs to 
> do and then halt, reboot, etc., all the cpus.

Thanks for the info. So introducing a "weak" function that can stop the
CPU it is running on could solve the problem. Every architecture can
override the function with something appropriate. E.g. "tile" can use
the lower-power "nap" instruction there.

What about the following patch.

Michael
---
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -49,6 +49,15 @@ static long no_blink(int state)
 long (*panic_blink)(int state);
 EXPORT_SYMBOL(panic_blink);
 
+/*
+ * Stop ourself in panic -- architecture code may override this
+ */
+void __attribute__ ((weak)) panic_smp_self_stop(void)
+{
+	while (1)
+		cpu_relax();
+}
+
 /**
  *	panic - halt the system
  *	@fmt: The text string to print
@@ -59,6 +68,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +78,14 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic, all other CPUs either
+	 * stop themself or will wait until they are stopped by the 1st CPU
+	 * with smp_send_stop().
 	 */
-	preempt_disable();
+	if (!spin_trylock(&panic_lock))
+		panic_smp_self_stop();
 
 	console_verbose();
 	bust_spinlocks(1);



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-11 12:28                     ` Michael Holzheu
@ 2011-11-11 12:30                       ` James Bottomley
  -1 siblings, 0 replies; 41+ messages in thread
From: James Bottomley @ 2011-11-11 12:30 UTC (permalink / raw)
  To: holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Hirokazu Takata, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, Matt Turner, Vivek Goyal,
	Haavard Skinnemoen

On Fri, 2011-11-11 at 13:28 +0100, Michael Holzheu wrote:
> Hello Chris,
> 
> On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
> > On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> 
> [snip]
> 
> > If a cleaner API seems useful (either for power reasons or restartability 
> > or whatever), I suppose a standard global function name could be specified 
> > that's the thing you execute when you get an smp_send_stop IPI (in tile's 
> > case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
> > just do an atomic_inc_return() of a global panic counter, and if it wasn't 
> > the first panicking cpu, call directly into the smp_stop handler routine to 
> > quiesce itself.  Then the panicking cpu could finish whatever it needs to 
> > do and then halt, reboot, etc., all the cpus.
> 
> Thanks for the info. So introducing a "weak" function that can stop the
> CPU it is running on could solve the problem. Every architecture can
> override the function with something appropriate. E.g. "tile" can use
> the lower-power "nap" instruction there.
> 
> What about the following patch.

Since we're discussing architecture stuff, could we move back to the
architecture list?  This thread keeps moving off it and it's not
helping.

James

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-11 12:30                       ` James Bottomley
  0 siblings, 0 replies; 41+ messages in thread
From: James Bottomley @ 2011-11-11 12:30 UTC (permalink / raw)
  To: holzheu
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Hirokazu Takata, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven, linux-arch, Matt Turner,
	Vivek Goyal, Haavard Skinnemoen, Don Zickus, Fenghua Yu,
	Mike Frysinger, Peter Zijlstra, Jeff Dike, Chris Metcalf,
	Mikael Starvik, Ivan Kokshaysky, Thomas Gleixner,
	Richard Henderson, Chris Zankel, Michal Simek, Tony Luck, kexec,
	linux-kernel, Ralf Baechle, Richard Kuo, Kyle McMartin,
	Paul Mundt, Eric W. Biederman, Martin Schwidefsky, Andrew Morton,
	Koichi Yasutake, Helge Deller

On Fri, 2011-11-11 at 13:28 +0100, Michael Holzheu wrote:
> Hello Chris,
> 
> On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
> > On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> 
> [snip]
> 
> > If a cleaner API seems useful (either for power reasons or restartability 
> > or whatever), I suppose a standard global function name could be specified 
> > that's the thing you execute when you get an smp_send_stop IPI (in tile's 
> > case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
> > just do an atomic_inc_return() of a global panic counter, and if it wasn't 
> > the first panicking cpu, call directly into the smp_stop handler routine to 
> > quiesce itself.  Then the panicking cpu could finish whatever it needs to 
> > do and then halt, reboot, etc., all the cpus.
> 
> Thanks for the info. So introducing a "weak" function that can stop the
> CPU it is running on could solve the problem. Every architecture can
> override the function with something appropriate. E.g. "tile" can use
> the lower-power "nap" instruction there.
> 
> What about the following patch.

Since we're discussing architecture stuff, could we move back to the
architecture list?  This thread keeps moving off it and it's not
helping.

James



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-11 12:28                     ` Michael Holzheu
@ 2011-11-11 17:02                       ` Chris Metcalf
  -1 siblings, 0 replies; 41+ messages in thread
From: Chris Metcalf @ 2011-11-11 17:02 UTC (permalink / raw)
  To: holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Helge Deller, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, Matt Turner, Vivek Goyal,
	Haavard Skinnemoen

On 11/11/2011 7:28 AM, Michael Holzheu wrote:
> Hello Chris,
>
> On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
>> On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> [snip]
>
>> If a cleaner API seems useful (either for power reasons or restartability
>> or whatever), I suppose a standard global function name could be specified
>> that's the thing you execute when you get an smp_send_stop IPI (in tile's
>> case it's "smp_stop_cpu_interrupt()") and the panic() code could instead
>> just do an atomic_inc_return() of a global panic counter, and if it wasn't
>> the first panicking cpu, call directly into the smp_stop handler routine to
>> quiesce itself.  Then the panicking cpu could finish whatever it needs to
>> do and then halt, reboot, etc., all the cpus.
> Thanks for the info. So introducing a "weak" function that can stop the
> CPU it is running on could solve the problem. Every architecture can
> override the function with something appropriate. E.g. "tile" can use
> the lower-power "nap" instruction there.
>
> What about the following patch.

Seems reasonable to me.

Acked-by: Chris Metcalf <cmetcalf-kv+TWInifGbQT0dZR+AlfA@public.gmane.org>

>
> Michael
> ---
> From: Michael Holzheu<holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic
>
> When two CPUs call panic at the same time there is a possible race
> condition that can stop kdump.  The first CPU calls crash_kexec() and the
> second CPU calls smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU.  So the second CPU stops the first CPU and therefore
> kdump fails:
>
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)->  do kdump
>
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>         ->smp_send_stop()->  stop 1st CPU (stop kdump)
>
> This patch fixes the problem by introducing a spinlock in panic that
> allows only one CPU to process crash_kexec() and the subsequent panic
> code.
>
> Signed-off-by: Michael Holzheu<holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>   kernel/panic.c |   18 +++++++++++++++++-
>   1 file changed, 17 insertions(+), 1 deletion(-)
>
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -49,6 +49,15 @@ static long no_blink(int state)
>   long (*panic_blink)(int state);
>   EXPORT_SYMBOL(panic_blink);
>
> +/*
> + * Stop ourself in panic -- architecture code may override this
> + */
> +void __attribute__ ((weak)) panic_smp_self_stop(void)
> +{
> +	while (1)
> +		cpu_relax();
> +}
> +
>   /**
>    *	panic - halt the system
>    *	@fmt: The text string to print
> @@ -59,6 +68,7 @@ EXPORT_SYMBOL(panic_blink);
>    */
>   NORET_TYPE void panic(const char * fmt, ...)
>   {
> +	static DEFINE_SPINLOCK(panic_lock);
>   	static char buf[1024];
>   	va_list args;
>   	long i, i_next = 0;
> @@ -68,8 +78,14 @@ NORET_TYPE void panic(const char * fmt,
>   	 * It's possible to come here directly from a panic-assertion and
>   	 * not have preempt disabled. Some functions called from here want
>   	 * preempt to be disabled. No point enabling it later though...
> +	 *
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic, all other CPUs either
> +	 * stop themself or will wait until they are stopped by the 1st CPU
> +	 * with smp_send_stop().
>   	 */
> -	preempt_disable();
> +	if (!spin_trylock(&panic_lock))
> +		panic_smp_self_stop();
>
>   	console_verbose();
>   	bust_spinlocks(1);
>
>

-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-11 17:02                       ` Chris Metcalf
  0 siblings, 0 replies; 41+ messages in thread
From: Chris Metcalf @ 2011-11-11 17:02 UTC (permalink / raw)
  To: holzheu
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, David S. Miller,
	Richard Weinberger, Helge Deller, James E.J. Bottomley,
	Ingo Molnar, Geert Uytterhoeven, linux-arch, Matt Turner,
	Vivek Goyal, Haavard Skinnemoen, Don Zickus, Fenghua Yu,
	Mike Frysinger, Peter Zijlstra, Jeff Dike, Mikael Starvik,
	Ivan Kokshaysky, Thomas Gleixner, Richard Henderson,
	Chris Zankel, Michal Simek, Tony Luck, kexec, linux-kernel,
	Ralf Baechle, Richard Kuo, Kyle McMartin, Paul Mundt,
	Eric W. Biederman, Martin Schwidefsky, Andrew Morton,
	Koichi Yasutake, Hirokazu Takata

On 11/11/2011 7:28 AM, Michael Holzheu wrote:
> Hello Chris,
>
> On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
>> On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> [snip]
>
>> If a cleaner API seems useful (either for power reasons or restartability
>> or whatever), I suppose a standard global function name could be specified
>> that's the thing you execute when you get an smp_send_stop IPI (in tile's
>> case it's "smp_stop_cpu_interrupt()") and the panic() code could instead
>> just do an atomic_inc_return() of a global panic counter, and if it wasn't
>> the first panicking cpu, call directly into the smp_stop handler routine to
>> quiesce itself.  Then the panicking cpu could finish whatever it needs to
>> do and then halt, reboot, etc., all the cpus.
> Thanks for the info. So introducing a "weak" function that can stop the
> CPU it is running on could solve the problem. Every architecture can
> override the function with something appropriate. E.g. "tile" can use
> the lower-power "nap" instruction there.
>
> What about the following patch.

Seems reasonable to me.

Acked-by: Chris Metcalf <cmetcalf@tilera.com>

>
> Michael
> ---
> From: Michael Holzheu<holzheu@linux.vnet.ibm.com>
> Subject: kdump: fix crash_kexec()/smp_send_stop() race in panic
>
> When two CPUs call panic at the same time there is a possible race
> condition that can stop kdump.  The first CPU calls crash_kexec() and the
> second CPU calls smp_send_stop() in panic() before crash_kexec() finished
> on the first CPU.  So the second CPU stops the first CPU and therefore
> kdump fails:
>
> 1st CPU:
> panic()->crash_kexec()->mutex_trylock(&kexec_mutex)->  do kdump
>
> 2nd CPU:
> panic()->crash_kexec()->kexec_mutex already held by 1st CPU
>         ->smp_send_stop()->  stop 1st CPU (stop kdump)
>
> This patch fixes the problem by introducing a spinlock in panic that
> allows only one CPU to process crash_kexec() and the subsequent panic
> code.
>
> Signed-off-by: Michael Holzheu<holzheu@linux.vnet.ibm.com>
> ---
>   kernel/panic.c |   18 +++++++++++++++++-
>   1 file changed, 17 insertions(+), 1 deletion(-)
>
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -49,6 +49,15 @@ static long no_blink(int state)
>   long (*panic_blink)(int state);
>   EXPORT_SYMBOL(panic_blink);
>
> +/*
> + * Stop ourself in panic -- architecture code may override this
> + */
> +void __attribute__ ((weak)) panic_smp_self_stop(void)
> +{
> +	while (1)
> +		cpu_relax();
> +}
> +
>   /**
>    *	panic - halt the system
>    *	@fmt: The text string to print
> @@ -59,6 +68,7 @@ EXPORT_SYMBOL(panic_blink);
>    */
>   NORET_TYPE void panic(const char * fmt, ...)
>   {
> +	static DEFINE_SPINLOCK(panic_lock);
>   	static char buf[1024];
>   	va_list args;
>   	long i, i_next = 0;
> @@ -68,8 +78,14 @@ NORET_TYPE void panic(const char * fmt,
>   	 * It's possible to come here directly from a panic-assertion and
>   	 * not have preempt disabled. Some functions called from here want
>   	 * preempt to be disabled. No point enabling it later though...
> +	 *
> +	 * Only one CPU is allowed to execute the panic code from here. For
> +	 * multiple parallel invocations of panic, all other CPUs either
> +	 * stop themself or will wait until they are stopped by the 1st CPU
> +	 * with smp_send_stop().
>   	 */
> -	preempt_disable();
> +	if (!spin_trylock(&panic_lock))
> +		panic_smp_self_stop();
>
>   	console_verbose();
>   	bust_spinlocks(1);
>
>

-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-11 12:28                     ` Michael Holzheu
@ 2011-11-11 17:45                       ` Richard Kuo
  -1 siblings, 0 replies; 41+ messages in thread
From: Richard Kuo @ 2011-11-11 17:45 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, Richard Weinberger,
	Hirokazu Takata, James E.J. Bottomley, Ingo Molnar,
	Geert Uytterhoeven, linux-arch-u79uwXL29TY76Z2rM5mHXA,
	Matt Turner, Vivek Goyal, Haavard Skinnemoen, Don Zickus

On Fri, Nov 11, 2011 at 01:28:14PM +0100, Michael Holzheu wrote:
> Hello Chris,
> 
> On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
> > On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> 
> [snip]
> 
> > If a cleaner API seems useful (either for power reasons or restartability 
> > or whatever), I suppose a standard global function name could be specified 
> > that's the thing you execute when you get an smp_send_stop IPI (in tile's 
> > case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
> > just do an atomic_inc_return() of a global panic counter, and if it wasn't 
> > the first panicking cpu, call directly into the smp_stop handler routine to 
> > quiesce itself.  Then the panicking cpu could finish whatever it needs to 
> > do and then halt, reboot, etc., all the cpus.
> 
> Thanks for the info. So introducing a "weak" function that can stop the
> CPU it is running on could solve the problem. Every architecture can
> override the function with something appropriate. E.g. "tile" can use
> the lower-power "nap" instruction there.
> 
> What about the following patch.

Hexagon uses interrupts to send the stop to the other CPU's as well, and
we also have a stop local cpu operation defined, so I think we're in the same
boat as tile.  This patch should work for us.




-- 

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-11 17:45                       ` Richard Kuo
  0 siblings, 0 replies; 41+ messages in thread
From: Richard Kuo @ 2011-11-11 17:45 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: Benjamin Herrenschmidt, Heiko Carstens, David Howells,
	Chen Liqin, Paul Mackerras, H. Peter Anvin, Guan Xuetao,
	Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn, Jesper Nilsson,
	Russell King, Yoshinori Sato, Richard Weinberger,
	Hirokazu Takata, James E.J. Bottomley, Ingo Molnar,
	Geert Uytterhoeven, linux-arch, Matt Turner, Vivek Goyal,
	Haavard Skinnemoen, Don Zickus, Fenghua Yu, Mike Frysinger,
	Peter Zijlstra, Jeff Dike, Chris Metcalf, Mikael Starvik,
	Ivan Kokshaysky, Thomas Gleixner, Richard Henderson,
	Chris Zankel, Michal Simek, Tony Luck, kexec, linux-kernel,
	Ralf Baechle, David S. Miller, Kyle McMartin, Paul Mundt,
	Eric W. Biederman, Martin Schwidefsky, Andrew Morton,
	Koichi Yasutake, Helge Deller

On Fri, Nov 11, 2011 at 01:28:14PM +0100, Michael Holzheu wrote:
> Hello Chris,
> 
> On Thu, 2011-11-10 at 10:11 -0500, Chris Metcalf wrote:
> > On 11/10/2011 9:22 AM, Michael Holzheu wrote:
> 
> [snip]
> 
> > If a cleaner API seems useful (either for power reasons or restartability 
> > or whatever), I suppose a standard global function name could be specified 
> > that's the thing you execute when you get an smp_send_stop IPI (in tile's 
> > case it's "smp_stop_cpu_interrupt()") and the panic() code could instead 
> > just do an atomic_inc_return() of a global panic counter, and if it wasn't 
> > the first panicking cpu, call directly into the smp_stop handler routine to 
> > quiesce itself.  Then the panicking cpu could finish whatever it needs to 
> > do and then halt, reboot, etc., all the cpus.
> 
> Thanks for the info. So introducing a "weak" function that can stop the
> CPU it is running on could solve the problem. Every architecture can
> override the function with something appropriate. E.g. "tile" can use
> the lower-power "nap" instruction there.
> 
> What about the following patch.

Hexagon uses interrupts to send the stop to the other CPU's as well, and
we also have a stop local cpu operation defined, so I think we're in the same
boat as tile.  This patch should work for us.




-- 

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v3] kdump: Fix crash_kexec - smp_send_stop race in panic
  2011-11-11 17:02                       ` Chris Metcalf
@ 2011-11-29  8:58                           ` Michael Holzheu
  -1 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-29  8:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Fenghua Yu, Benjamin Herrenschmidt, Heiko Carstens,
	David Howells, Chen Liqin, Paul Mackerras, H. Peter Anvin,
	Guan Xuetao, Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn,
	Jesper Nilsson, Russell King, Yoshinori Sato, Richard Weinberger,
	Helge Deller, James E.J. Bottomley, Ingo Molnar,
	Geert Uytterhoeven, Matt Turner, Vivek Goyal, Haavard Skinnemoen,
	Don Zickus

From: Michael Holzheu <holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Subject: kdump: Fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

All other CPUs call the weak function panic_smp_self_stop() that stops
the CPU itself. This function can be overloaded by architecture code.
For example "tile" can use their lower-power "nap" instruction for
that.

Acked-by: Chris Metcalf <cmetcalf-kv+TWInifGbQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Michael Holzheu <holzheu-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
 kernel/panic.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -49,6 +49,15 @@ static long no_blink(int state)
 long (*panic_blink)(int state);
 EXPORT_SYMBOL(panic_blink);
 
+/*
+ * Stop ourself in panic -- architecture code may override this
+ */
+void __weak panic_smp_self_stop(void)
+{
+	while (1)
+		cpu_relax();
+}
+
 /**
  *	panic - halt the system
  *	@fmt: The text string to print
@@ -59,6 +68,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +78,14 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic, all other CPUs either
+	 * stop themself or will wait until they are stopped by the 1st CPU
+	 * with smp_send_stop().
 	 */
-	preempt_disable();
+	if (!spin_trylock(&panic_lock))
+		panic_smp_self_stop();
 
 	console_verbose();
 	bust_spinlocks(1);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v3] kdump: Fix crash_kexec - smp_send_stop race in panic
@ 2011-11-29  8:58                           ` Michael Holzheu
  0 siblings, 0 replies; 41+ messages in thread
From: Michael Holzheu @ 2011-11-29  8:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Fenghua Yu, Benjamin Herrenschmidt, Heiko Carstens,
	David Howells, Chen Liqin, Paul Mackerras, H. Peter Anvin,
	Guan Xuetao, Lennox Wu, Hans-Christian Egtvedt, Jonas Bonn,
	Jesper Nilsson, Russell King, Yoshinori Sato, Richard Weinberger,
	Helge Deller, James E.J. Bottomley, Ingo Molnar,
	Geert Uytterhoeven, Matt Turner, Vivek Goyal, Haavard Skinnemoen,
	Don Zickus, linux-arch, Mike Frysinger, Peter Zijlstra,
	Jeff Dike, Chris Metcalf, Mikael Starvik, Ivan Kokshaysky,
	Thomas Gleixner, Richard Henderson, Chris Zankel, Michal Simek,
	Tony Luck, Hirokazu Takata, kexec, linux-kernel, Ralf Baechle,
	Richard Kuo, Kyle McMartin, Paul Mundt, Eric W. Biederman,
	Martin Schwidefsky, Andrew Morton, Koichi Yasutake,
	David S. Miller

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Subject: kdump: Fix crash_kexec()/smp_send_stop() race in panic

When two CPUs call panic at the same time there is a possible race
condition that can stop kdump.  The first CPU calls crash_kexec() and the
second CPU calls smp_send_stop() in panic() before crash_kexec() finished
on the first CPU.  So the second CPU stops the first CPU and therefore
kdump fails:

1st CPU:
panic()->crash_kexec()->mutex_trylock(&kexec_mutex)-> do kdump

2nd CPU:
panic()->crash_kexec()->kexec_mutex already held by 1st CPU
       ->smp_send_stop()-> stop 1st CPU (stop kdump)

This patch fixes the problem by introducing a spinlock in panic that
allows only one CPU to process crash_kexec() and the subsequent panic
code.

All other CPUs call the weak function panic_smp_self_stop() that stops
the CPU itself. This function can be overloaded by architecture code.
For example "tile" can use their lower-power "nap" instruction for
that.

Acked-by: Chris Metcalf <cmetcalf@tilera.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -49,6 +49,15 @@ static long no_blink(int state)
 long (*panic_blink)(int state);
 EXPORT_SYMBOL(panic_blink);
 
+/*
+ * Stop ourself in panic -- architecture code may override this
+ */
+void __weak panic_smp_self_stop(void)
+{
+	while (1)
+		cpu_relax();
+}
+
 /**
  *	panic - halt the system
  *	@fmt: The text string to print
@@ -59,6 +68,7 @@ EXPORT_SYMBOL(panic_blink);
  */
 NORET_TYPE void panic(const char * fmt, ...)
 {
+	static DEFINE_SPINLOCK(panic_lock);
 	static char buf[1024];
 	va_list args;
 	long i, i_next = 0;
@@ -68,8 +78,14 @@ NORET_TYPE void panic(const char * fmt,
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
+	 *
+	 * Only one CPU is allowed to execute the panic code from here. For
+	 * multiple parallel invocations of panic, all other CPUs either
+	 * stop themself or will wait until they are stopped by the 1st CPU
+	 * with smp_send_stop().
 	 */
-	preempt_disable();
+	if (!spin_trylock(&panic_lock))
+		panic_smp_self_stop();
 
 	console_verbose();
 	bust_spinlocks(1);



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2011-11-29  8:59 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-26 14:34 [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic Michael Holzheu
2011-10-26 14:34 ` Michael Holzheu
2011-10-27 17:40 ` Vivek Goyal
2011-10-27 17:40   ` Vivek Goyal
2011-10-28 23:11 ` Andrew Morton
2011-10-28 23:11   ` Andrew Morton
2011-10-31  9:57   ` Michael Holzheu
2011-10-31  9:57     ` Michael Holzheu
2011-10-31 10:39     ` Andrew Morton
2011-10-31 10:39       ` Andrew Morton
2011-10-31 12:34       ` [PATCH v2] " Michael Holzheu
2011-10-31 12:34         ` Michael Holzheu
2011-11-01 20:04         ` Don Zickus
2011-11-01 20:04           ` Don Zickus
2011-11-02 10:03           ` Michael Holzheu
2011-11-02 10:03             ` Michael Holzheu
2011-11-02 10:03             ` Michael Holzheu
2011-11-02 20:57             ` Luck, Tony
2011-11-02 20:57               ` Luck, Tony
2011-11-03 10:07       ` [PATCH] " Michael Holzheu
2011-11-03 10:07         ` Michael Holzheu
2011-11-10  0:04         ` Andrew Morton
2011-11-10  0:04           ` Andrew Morton
2011-11-10 14:17           ` Américo Wang
2011-11-10 14:17             ` Américo Wang
     [not found]           ` <20111109160400.cc2d27d9.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
2011-11-10 14:22             ` Michael Holzheu
2011-11-10 14:22               ` Michael Holzheu
2011-11-10 15:11               ` Chris Metcalf
2011-11-10 15:11                 ` Chris Metcalf
     [not found]                 ` <4EBBE9B4.3040009-kv+TWInifGbQT0dZR+AlfA@public.gmane.org>
2011-11-11 12:28                   ` Michael Holzheu
2011-11-11 12:28                     ` Michael Holzheu
2011-11-11 12:30                     ` James Bottomley
2011-11-11 12:30                       ` James Bottomley
2011-11-11 17:02                     ` Chris Metcalf
2011-11-11 17:02                       ` Chris Metcalf
     [not found]                       ` <4EBD5536.7010806-kv+TWInifGbQT0dZR+AlfA@public.gmane.org>
2011-11-29  8:58                         ` [PATCH v3] " Michael Holzheu
2011-11-29  8:58                           ` Michael Holzheu
2011-11-11 17:45                     ` [PATCH] " Richard Kuo
2011-11-11 17:45                       ` Richard Kuo
2011-11-10 15:31           ` James Bottomley
2011-11-10 15:31             ` James Bottomley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.