* [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic [not found] ` <20111031033948.a0edb7f3.akpm@linux-foundation.org> @ 2011-10-31 12:34 ` Michael Holzheu 2011-11-01 20:04 ` Don Zickus 2011-11-03 10:07 ` [PATCH] " Michael Holzheu 1 sibling, 1 reply; 17+ 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] 17+ messages in thread
* Re: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic 2011-10-31 12:34 ` [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic Michael Holzheu @ 2011-11-01 20:04 ` Don Zickus [not found] ` <20111101200420.GN17705-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 0 siblings, 1 reply; 17+ 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] 17+ messages in thread
[parent not found: <20111101200420.GN17705-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic [not found] ` <20111101200420.GN17705-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2011-11-02 10:03 ` Michael Holzheu 2011-11-02 10:03 ` Michael Holzheu 2011-11-02 20:57 ` Luck, Tony 0 siblings, 2 replies; 17+ 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] 17+ 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 10:03 ` Michael Holzheu 2011-11-02 20:57 ` Luck, Tony 1 sibling, 0 replies; 17+ 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] 17+ 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 10:03 ` Michael Holzheu @ 2011-11-02 20:57 ` Luck, Tony 1 sibling, 0 replies; 17+ messages in thread From: Luck, Tony @ 2011-11-02 20:57 UTC (permalink / raw) To: holzheu@linux.vnet.ibm.com, Don Zickus Cc: Andrew Morton, linux-arch@vger.kernel.org, heiko.carstens@de.ibm.com, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, Eric W. Biederman, schwidefsky@de.ibm.com, 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] 17+ messages in thread
* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic [not found] ` <20111031033948.a0edb7f3.akpm@linux-foundation.org> 2011-10-31 12:34 ` [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic Michael Holzheu @ 2011-11-03 10:07 ` Michael Holzheu 2011-11-10 0:04 ` Andrew Morton 1 sibling, 1 reply; 17+ 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] 17+ messages in thread
* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic 2011-11-03 10:07 ` [PATCH] " Michael Holzheu @ 2011-11-10 0:04 ` Andrew Morton 2011-11-10 14:17 ` Américo Wang ` (2 more replies) 0 siblings, 3 replies; 17+ 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] 17+ 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 [not found] ` <20111109160400.cc2d27d9.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org> 2011-11-10 15:31 ` James Bottomley 2 siblings, 0 replies; 17+ 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] 17+ messages in thread
[parent not found: <20111109160400.cc2d27d9.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>]
* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic [not found] ` <20111109160400.cc2d27d9.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org> @ 2011-11-10 14:22 ` Michael Holzheu 2011-11-10 15:11 ` Chris Metcalf 0 siblings, 1 reply; 17+ 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 <hskinnemoe> 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] 17+ 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 [not found] ` <4EBBE9B4.3040009-kv+TWInifGbQT0dZR+AlfA@public.gmane.org> 0 siblings, 1 reply; 17+ 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] 17+ messages in thread
[parent not found: <4EBBE9B4.3040009-kv+TWInifGbQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic [not found] ` <4EBBE9B4.3040009-kv+TWInifGbQT0dZR+AlfA@public.gmane.org> @ 2011-11-11 12:28 ` Michael Holzheu 2011-11-11 12:30 ` James Bottomley ` (2 more replies) 0 siblings, 3 replies; 17+ 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] 17+ 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 2011-11-11 17:02 ` Chris Metcalf 2011-11-11 17:45 ` [PATCH] " Richard Kuo 2 siblings, 0 replies; 17+ 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 <hskinnemoen> 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] 17+ 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 @ 2011-11-11 17:02 ` Chris Metcalf [not found] ` <4EBD5536.7010806-kv+TWInifGbQT0dZR+AlfA@public.gmane.org> 2011-11-11 17:45 ` [PATCH] " Richard Kuo 2 siblings, 1 reply; 17+ 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] 17+ messages in thread
[parent not found: <4EBD5536.7010806-kv+TWInifGbQT0dZR+AlfA@public.gmane.org>]
* [PATCH v3] kdump: Fix crash_kexec - smp_send_stop race in panic [not found] ` <4EBD5536.7010806-kv+TWInifGbQT0dZR+AlfA@public.gmane.org> @ 2011-11-29 8:58 ` Michael Holzheu 0 siblings, 0 replies; 17+ 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] 17+ 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 2011-11-11 17:02 ` Chris Metcalf @ 2011-11-11 17:45 ` Richard Kuo 2 siblings, 0 replies; 17+ 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] 17+ 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 [not found] ` <20111109160400.cc2d27d9.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org> @ 2011-11-10 15:31 ` James Bottomley 2011-11-10 15:31 ` James Bottomley 2 siblings, 1 reply; 17+ 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] 17+ messages in thread
* Re: [PATCH] kdump: Fix crash_kexec - smp_send_stop race in panic 2011-11-10 15:31 ` James Bottomley @ 2011-11-10 15:31 ` James Bottomley 0 siblings, 0 replies; 17+ 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] 17+ messages in thread
end of thread, other threads:[~2011-11-29 8:58 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1319639649.3321.11.camel@br98xy6r>
[not found] ` <20111028161143.e5ebf617.akpm@linux-foundation.org>
[not found] ` <1320055036.2796.8.camel@br98xy6r>
[not found] ` <20111031033948.a0edb7f3.akpm@linux-foundation.org>
2011-10-31 12:34 ` [PATCH v2] kdump: Fix crash_kexec - smp_send_stop race in panic Michael Holzheu
2011-11-01 20:04 ` Don Zickus
[not found] ` <20111101200420.GN17705-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-11-02 10:03 ` Michael Holzheu
2011-11-02 10:03 ` Michael Holzheu
2011-11-02 20:57 ` Luck, Tony
2011-11-03 10:07 ` [PATCH] " Michael Holzheu
2011-11-10 0:04 ` Andrew Morton
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 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:30 ` James Bottomley
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-11 17:45 ` [PATCH] " Richard Kuo
2011-11-10 15:31 ` James Bottomley
2011-11-10 15:31 ` James Bottomley
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).