[RFC][PATCH -next] make pstore/kmsg_dump run after stopping other cpus in panic path

October 14th, 2011 - 05:00 pm ET by Seiji Aguchi | Report spam
Hi,

As Don mentioned in following thread, it would be nice for pstore/kmsg_dump to serialize
panic path and have one cpu running because they can log messages reliably.

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

For realizing this idea, we have to move kmsg_dump below smp_send_stop() and bust some locks
of kmsg_dump/pstore in panic path.

This patch does followings.

- moving kmsg_dump(KMSG_DUMP_PANIC) below smp_send_stop.
- busting logbuf_lock of kmsg_dump() in panic path for avoiding deadlock.
- busting psinfo->buf_lock of pstore_dump() in panic path for avoiding deadlock.

Any comments are welcome.

Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com>


fs/pstore/platform.c | 22 ++++++++++
kernel/panic.c | 4 ++--
kernel/printk.c | 7 +++++++
3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 2bd620f..e73d940 100644
a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -90,19 +90,21 @@ static void pstore_dump(struct kmsg_dumper *dumper,
int hsize, ret;
unsigned int part = 1;
unsigned long flags = 0;
- int is_locked = 0;

if (reason < ARRAY_SIZE(reason_str))
why = reason_str[reason];
else
why = "Unknown";

- if (in_nmi()) {
- is_locked = spin_trylock(&psinfo->buf_lock);
- if (!is_locked)
- pr_err("pstore dump routine blocked in NMI, may corrupt error record");
- } else
- spin_lock_irqsave(&psinfo->buf_lock, flags);
+ /*
+ * pstore_dump() is called after smp_send_stop() in panic path.
+ * So, spin_lock should be bust for avoiding deadlock.
+ */
+ if (reason == KMSG_DUMP_PANIC)
+ spin_lock_init(&psinfo->buf_lock);
+
+ spin_lock_irqsave(&psinfo->buf_lock, flags);
+
oopscount++;
while (total < kmsg_bytes) {
dst = psinfo->buf;
@@ -131,11 +133,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
total += l1_cpy + l2_cpy;
part++;
}
- if (in_nmi()) {
- if (is_locked)
- spin_unlock(&psinfo->buf_lock);
- } else
- spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+ spin_unlock_irqrestore(&psinfo->buf_lock, flags);
}

static struct kmsg_dumper pstore_dumper = {
diff --git a/kernel/panic.c b/kernel/panic.c
index d7bb697..41bf6ad 100644
a/kernel/panic.c
+++ b/kernel/panic.c
@@ -88,8 +88,6 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
crash_kexec(NULL);

- kmsg_dump(KMSG_DUMP_PANIC);
-
/*
* Note smp_send_stop is the usual smp shutdown function, which
* unfortunately means it may not be hardened to work in a panic
@@ -97,6 +95,8 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
smp_send_stop();

+ kmsg_dump(KMSG_DUMP_PANIC);
+
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);

bust_spinlocks(0);
diff --git a/kernel/printk.c b/kernel/printk.c
index 1455a0d..e1e57db 100644
a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1732,6 +1732,13 @@ void kmsg_dump(enum kmsg_dump_reason reason)
unsigned long l1, l2;
unsigned long flags;

+ /*
+ * kmsg_dump() is called after smp_send_stop() in panic path.
+ * So, spin_lock should be bust for avoiding deadlock.
+ */
+ if (reason == KMSG_DUMP_PANIC)
+ raw_spin_lock_init(&logbuf_lock);
+
/* Theoretically, the log could move on after we do this, but
there's not a lot we can do about that. The new messages
will overwrite the start of what we dump. */
1.7.1
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
email Follow the discussionReplies 13 repliesReplies Make a reply

Similar topics

Replies

#1 Chen Gong
October 17th, 2011 - 02:30 am ET | Report spam
于 2011/10/15 4:53, Seiji Aguchi 写道:
Hi,

As Don mentioned in following thread, it would be nice for pstore/kmsg_dump to serialize
panic path and have one cpu running because they can log messages reliably.

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

For realizing this idea, we have to move kmsg_dump below smp_send_stop() and bust some locks
of kmsg_dump/pstore in panic path.

This patch does followings.

- moving kmsg_dump(KMSG_DUMP_PANIC) below smp_send_stop.
- busting logbuf_lock of kmsg_dump() in panic path for avoiding deadlock.
- busting psinfo->buf_lock of pstore_dump() in panic path for avoiding deadlock.

Any comments are welcome.




Hi, Seiji

I have a stupid question: since you have serialized the process procedure via
smp_send_stop, why still using spin_lock_xxx? Maybe preempt_disable/enable is
enough?
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Replies Reply to this message
#2 Don Zickus
October 17th, 2011 - 12:10 pm ET | Report spam
On Fri, Oct 14, 2011 at 04:53:05PM -0400, Seiji Aguchi wrote:
Hi,

As Don mentioned in following thread, it would be nice for pstore/kmsg_dump to serialize
panic path and have one cpu running because they can log messages reliably.

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

For realizing this idea, we have to move kmsg_dump below smp_send_stop() and bust some locks
of kmsg_dump/pstore in panic path.

This patch does followings.

- moving kmsg_dump(KMSG_DUMP_PANIC) below smp_send_stop.
- busting logbuf_lock of kmsg_dump() in panic path for avoiding deadlock.
- busting psinfo->buf_lock of pstore_dump() in panic path for avoiding deadlock.

Any comments are welcome.



I think I am ok with this, just some comments below.


Signed-off-by: Seiji Aguchi


fs/pstore/platform.c | 22 ++++++++++
kernel/panic.c | 4 ++--
kernel/printk.c | 7 +++++++
3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 2bd620f..e73d940 100644
a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -90,19 +90,21 @@ static void pstore_dump(struct kmsg_dumper *dumper,
int hsize, ret;
unsigned int part = 1;
unsigned long flags = 0;
- int is_locked = 0;

if (reason < ARRAY_SIZE(reason_str))
why = reason_str[reason];
else
why = "Unknown";

- if (in_nmi()) {
- is_locked = spin_trylock(&psinfo->buf_lock);
- if (!is_locked)
- pr_err("pstore dump routine blocked in NMI, may corrupt error record");
- } else
- spin_lock_irqsave(&psinfo->buf_lock, flags);
+ /*
+ * pstore_dump() is called after smp_send_stop() in panic path.
+ * So, spin_lock should be bust for avoiding deadlock.
+ */
+ if (reason == KMSG_DUMP_PANIC)
+ spin_lock_init(&psinfo->buf_lock);
+
+ spin_lock_irqsave(&psinfo->buf_lock, flags);
+
oopscount++;
while (total < kmsg_bytes) {
dst = psinfo->buf;
@@ -131,11 +133,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
total += l1_cpy + l2_cpy;
part++;
}
- if (in_nmi()) {
- if (is_locked)
- spin_unlock(&psinfo->buf_lock);
- } else
- spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+ spin_unlock_irqrestore(&psinfo->buf_lock, flags);
}



My original problem was the NMI path was calling panic and thus causing
these locking problems. With the change below, which allows the change
above, I believe the NMI case is covered (because this path is only called
by NMI during panic). This makes my previous patch (accepted by Tony)
probably unnecessary if we go with this patch.

As for the need for using spin_lock_init vs just skipping the locking, I
don't have a preference, nor know what the correct usage is for these
things. I suppose this patch does the proper thing.


static struct kmsg_dumper pstore_dumper = {
diff --git a/kernel/panic.c b/kernel/panic.c
index d7bb697..41bf6ad 100644
a/kernel/panic.c
+++ b/kernel/panic.c
@@ -88,8 +88,6 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
crash_kexec(NULL);

- kmsg_dump(KMSG_DUMP_PANIC);
-
/*
* Note smp_send_stop is the usual smp shutdown function, which
* unfortunately means it may not be hardened to work in a panic
@@ -97,6 +95,8 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
smp_send_stop();

+ kmsg_dump(KMSG_DUMP_PANIC);
+
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);

bust_spinlocks(0);



Yes, this is what Seiji and I talked about previously based on Vivek's
suggestion. This can only work on x86 if we pick up my 'using NMI in stop
cpu path' patch from last week.

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

Otherwise, there is no guarantee all the cpus stop and we can still end up
in data corruption depending on the backend being used.

diff --git a/kernel/printk.c b/kernel/printk.c
index 1455a0d..e1e57db 100644
a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1732,6 +1732,13 @@ void kmsg_dump(enum kmsg_dump_reason reason)
unsigned long l1, l2;
unsigned long flags;

+ /*
+ * kmsg_dump() is called after smp_send_stop() in panic path.
+ * So, spin_lock should be bust for avoiding deadlock.
+ */
+ if (reason == KMSG_DUMP_PANIC)
+ raw_spin_lock_init(&logbuf_lock);
+
/* Theoretically, the log could move on after we do this, but
there's not a lot we can do about that. The new messages
will overwrite the start of what we dump. */



The just adds more lock busting based on the movement of kmsg_dump() in
the panic path.

There is still more lock busting to do in the various backends, but this
patch provides the necessary first steps.

All this lock busting probably isn't pretty and causes one to reflect what
is going on here. But as long as we are going to keep the kmsg_dump
design, changes like this seem necessary to make sure the locking stays
sane(r) for now.

Acked-by: Don Zickus
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Replies Reply to this message
#3 Luck, Tony
October 17th, 2011 - 01:00 pm ET | Report spam
All this lock busting probably isn't pretty and causes one to reflect what
is going on here. But as long as we are going to keep the kmsg_dump
design, changes like this seem necessary to make sure the locking stays
sane(r) for now.



So should we let the back-end know that locks have been busted? I worry
that we'll get through the pstore layer by blasting away at any locks that
get in our way - but then the backend (which may well have been written on
the assumption that pstore serialized calls to it) will not do anything
useful (and may cause its own hang).

-Tony
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Replies Reply to this message
#4 Don Zickus
October 17th, 2011 - 01:30 pm ET | Report spam
On Mon, Oct 17, 2011 at 09:56:50AM -0700, Luck, Tony wrote:
> All this lock busting probably isn't pretty and causes one to reflect what
> is going on here. But as long as we are going to keep the kmsg_dump
> design, changes like this seem necessary to make sure the locking stays
> sane(r) for now.

So should we let the back-end know that locks have been busted? I worry
that we'll get through the pstore layer by blasting away at any locks that
get in our way - but then the backend (which may well have been written on
the assumption that pstore serialized calls to it) will not do anything
useful (and may cause its own hang).



I was kinda alluding to something like that, when I said we probably need
follow on patches to clean up the backend. But maybe it would be smarter
to set a flag in pstore to let the backend know we busted the locks
instead of letting them do panic checks themselves. I agree with your
concerns.

I really can't think of a good overall solution other than slowly
step-by-step untangle things by making subtle changes, this round being
the serialization of kmsg_dump().

My brain is to small to figure this out. I keep thinking about making an
ascii art diagram to see all the various paths and their contexts, but
then I keep finding more interesting things to do. :-)

Perhaps we should do that and make some rules about what the back-end can
and can not do when plugging into kmsg_dump.

Cheers,
Don

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Replies Reply to this message
#5 Seiji Aguchi
October 17th, 2011 - 02:00 pm ET | Report spam
Hi,

I agree with Tony's concern.
But as Don told, the best way to go proceed is fixing backend drivers step by step.

Seiji


From: Don Zickus [mailto:]
Sent: Monday, October 17, 2011 1:22 PM
To: Luck, Tony
Cc: Seiji Aguchi; ; Matthew Garrett; Vivek Goyal; Chen, Gong; Andrew Morton; Brown, Len; Huang,
Ying; ; ; ; ; ;
; ; Satoru Moriya
Subject: Re: [RFC][PATCH -next] make pstore/kmsg_dump run after stopping other cpus in panic path

On Mon, Oct 17, 2011 at 09:56:50AM -0700, Luck, Tony wrote:
> All this lock busting probably isn't pretty and causes one to reflect what
> is going on here. But as long as we are going to keep the kmsg_dump
> design, changes like this seem necessary to make sure the locking stays
> sane(r) for now.

So should we let the back-end know that locks have been busted? I worry
that we'll get through the pstore layer by blasting away at any locks that
get in our way - but then the backend (which may well have been written on
the assumption that pstore serialized calls to it) will not do anything
useful (and may cause its own hang).



I was kinda alluding to something like that, when I said we probably need
follow on patches to clean up the backend. But maybe it would be smarter
to set a flag in pstore to let the backend know we busted the locks
instead of letting them do panic checks themselves. I agree with your
concerns.

I really can't think of a good overall solution other than slowly
step-by-step untangle things by making subtle changes, this round being
the serialization of kmsg_dump().

My brain is to small to figure this out. I keep thinking about making an
ascii art diagram to see all the various paths and their contexts, but
then I keep finding more interesting things to do. :-)

Perhaps we should do that and make some rules about what the back-end can
and can not do when plugging into kmsg_dump.

Cheers,
Don



To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Replies Reply to this message
Help Create a new topicNext page Replies Make a reply
Search Make your own search