From: Daniel Thompson <daniel.thompson@linaro.org>
To: Sumit Garg <sumit.garg@linaro.org>
Cc: kgdb-bugreport@lists.sourceforge.net,
Jason Wessel <jason.wessel@windriver.com>,
Douglas Anderson <dianders@chromium.org>,
Petr Mladek <pmladek@suse.com>,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3 4/4] kdb: Switch kdb_msg_write() to use safer polling I/O
Date: Thu, 28 May 2020 12:26:20 +0100 [thread overview]
Message-ID: <20200528112620.a6zhgnkl2izuggsa@holly.lan> (raw)
In-Reply-To: <CAFA6WYNeBDRdRqb8dB5HA923ujD3zq7JEQQnV4WJr_fthCc=GQ@mail.gmail.com>
On Thu, May 28, 2020 at 11:48:48AM +0530, Sumit Garg wrote:
> On Wed, 27 May 2020 at 19:01, Daniel Thompson
> <daniel.thompson@linaro.org> wrote:
> >
> > On Wed, May 27, 2020 at 11:55:59AM +0530, Sumit Garg wrote:
> > > In kgdb NMI context, calling console handlers isn't safe due to locks
> > > used in those handlers which could lead to a deadlock. Although, using
> > > oops_in_progress increases the chance to bypass locks in most console
> > > handlers but it might not be sufficient enough in case a console uses
> > > more locks (VT/TTY is good example).
> > >
> > > Currently when a driver provides both polling I/O and a console then kdb
> > > will output using the console. We can increase robustness by using the
> > > currently active polling I/O driver (which should be lockless) instead
> > > of the corresponding console. For several common cases (e.g. an
> > > embedded system with a single serial port that is used both for console
> > > output and debugger I/O) this will result in no console handler being
> > > used.
> >
> > Not sure I would have predicted all those changes to kgdboc.c based on
> > this patch description. I assume this is to help identify which console
> > matches our dbg_io_ops but it would be good to spell this out.
> >
>
> Okay, will add the corresponding description.
>
> >
> > > Suggested-by: Daniel Thompson <daniel.thompson@linaro.org>
> > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> > > ---
> > > drivers/tty/serial/kgdboc.c | 17 ++++++++---------
> > > include/linux/kgdb.h | 2 ++
> > > kernel/debug/kdb/kdb_io.c | 46 +++++++++++++++++++++++++++++++--------------
> > > 3 files changed, 42 insertions(+), 23 deletions(-)
> > >
> > > diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
> > > index c9f94fa..6199fe1 100644
> > > --- a/drivers/tty/serial/kgdboc.c
> > > +++ b/drivers/tty/serial/kgdboc.c
> > > @@ -35,7 +35,6 @@ static struct kparam_string kps = {
> > > };
> > >
> > > static int kgdboc_use_kms; /* 1 if we use kernel mode switching */
> > > -static struct tty_driver *kgdb_tty_driver;
> > > static int kgdb_tty_line;
> > >
> > > #ifdef CONFIG_KDB_KEYBOARD
> > > @@ -154,7 +153,7 @@ static int configure_kgdboc(void)
> > > }
> > >
> > > kgdboc_io_ops.is_console = 0;
> > > - kgdb_tty_driver = NULL;
> > > + kgdboc_io_ops.tty_drv = NULL;
> > >
> > > kgdboc_use_kms = 0;
> > > if (strncmp(cptr, "kms,", 4) == 0) {
> > > @@ -178,7 +177,7 @@ static int configure_kgdboc(void)
> > > }
> > > }
> > >
> > > - kgdb_tty_driver = p;
> > > + kgdboc_io_ops.tty_drv = p;
> > > kgdb_tty_line = tty_line;
> > >
> > > do_register:
> > > @@ -216,18 +215,18 @@ static int __init init_kgdboc(void)
> > >
> > > static int kgdboc_get_char(void)
> > > {
> > > - if (!kgdb_tty_driver)
> > > + if (!kgdboc_io_ops.tty_drv)
> > > return -1;
> > > - return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
> > > - kgdb_tty_line);
> > > + return kgdboc_io_ops.tty_drv->ops->poll_get_char(kgdboc_io_ops.tty_drv,
> > > + kgdb_tty_line);
> > > }
> > >
> > > static void kgdboc_put_char(u8 chr)
> > > {
> > > - if (!kgdb_tty_driver)
> > > + if (!kgdboc_io_ops.tty_drv)
> > > return;
> > > - kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
> > > - kgdb_tty_line, chr);
> > > + kgdboc_io_ops.tty_drv->ops->poll_put_char(kgdboc_io_ops.tty_drv,
> > > + kgdb_tty_line, chr);
> > > }
> > >
> > > static int param_set_kgdboc_var(const char *kmessage,
> > > diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
> > > index b072aeb..05d165d 100644
> > > --- a/include/linux/kgdb.h
> > > +++ b/include/linux/kgdb.h
> > > @@ -275,6 +275,7 @@ struct kgdb_arch {
> > > * for the I/O driver.
> > > * @is_console: 1 if the end device is a console 0 if the I/O device is
> > > * not a console
> > > + * @tty_drv: Pointer to polling tty driver.
> > > */
> > > struct kgdb_io {
> > > const char *name;
> > > @@ -285,6 +286,7 @@ struct kgdb_io {
> > > void (*pre_exception) (void);
> > > void (*post_exception) (void);
> > > int is_console;
> > > + struct tty_driver *tty_drv;
> >
> > Should this be a struct tty_driver or a struct console?
> >
> > In other words if the lifetime the console structure is the same as the
> > tty_driver then isn't it better to capture the console instead
> > (easier to compare and works with non-tty devices such as the
> > USB debug mode).
> >
>
> IIUC, you mean to say we can easily replace "is_console" with "struct
> console". This sounds feasible and should be a straightforward
> comparison in order to prefer "dbg_io_ops" over console handlers. So I
> will switch to use "struct console" instead.
My comment contains an if ("if the lifetime of the console structure is
the same") so you need to check that it is true before sharing a patch to
make the change.
Daniel.
>
> >
> > > };
> > >
> > > extern const struct kgdb_arch arch_kgdb_ops;
> > > diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
> > > index f848482..c2efa52 100644
> > > --- a/kernel/debug/kdb/kdb_io.c
> > > +++ b/kernel/debug/kdb/kdb_io.c
> > > @@ -24,6 +24,7 @@
> > > #include <linux/kgdb.h>
> > > #include <linux/kdb.h>
> > > #include <linux/kallsyms.h>
> > > +#include <linux/tty_driver.h>
> > > #include "kdb_private.h"
> > >
> > > #define CMD_BUFLEN 256
> > > @@ -542,13 +543,18 @@ static int kdb_search_string(char *searched, char *searchfor)
> > > return 0;
> > > }
> > >
> > > -static void kdb_io_write(char *cp, int len, void (*io_put_char)(u8 ch))
> > > +static void kdb_io_write(char *cp, int len, void (*io_put_char)(u8),
> > > + struct tty_driver *p, int line,
> > > + void (*poll_put_char)(struct tty_driver *, int, char))
> >
> > Judging from your reply to comment 1 I guess this is already on the list
> > to eliminate ;-).
> >
>
> Yeah.
>
> -Sumit
>
> >
> > Daniel.
> >
> >
> > > {
> > > if (len <= 0)
> > > return;
> > >
> > > while (len--) {
> > > - io_put_char(*cp);
> > > + if (io_put_char)
> > > + io_put_char(*cp);
> > > + if (poll_put_char)
> > > + poll_put_char(p, line, *cp);
> > > cp++;
> > > }
> > > }
> > > @@ -561,22 +567,34 @@ static void kdb_msg_write(char *msg, int msg_len)
> > > return;
> > >
> > > if (dbg_io_ops && !dbg_io_ops->is_console)
> > > - kdb_io_write(msg, msg_len, dbg_io_ops->write_char);
> > > + kdb_io_write(msg, msg_len, dbg_io_ops->write_char,
> > > + NULL, 0, NULL);
> > >
> > > for_each_console(c) {
> > > + int line;
> > > + struct tty_driver *p;
> > > +
> > > if (!(c->flags & CON_ENABLED))
> > > continue;
> > > - /*
> > > - * While rounding up CPUs via NMIs, its possible that
> > > - * a rounded up CPU maybe holding a console port lock
> > > - * leading to kgdb master CPU stuck in a deadlock during
> > > - * invocation of console write operations. So in order
> > > - * to avoid such a deadlock, enable oops_in_progress
> > > - * prior to invocation of console handlers.
> > > - */
> > > - ++oops_in_progress;
> > > - c->write(c, msg, msg_len);
> > > - --oops_in_progress;
> > > +
> > > + p = c->device ? c->device(c, &line) : NULL;
> > > + if (p && dbg_io_ops && p == dbg_io_ops->tty_drv && p->ops &&
> > > + p->ops->poll_put_char) {
> > > + kdb_io_write(msg, msg_len, NULL, p, line,
> > > + p->ops->poll_put_char);
> > > + } else {
> > > + /*
> > > + * While rounding up CPUs via NMIs, its possible that
> > > + * a rounded up CPU maybe holding a console port lock
> > > + * leading to kgdb master CPU stuck in a deadlock during
> > > + * invocation of console write operations. So in order
> > > + * to avoid such a deadlock, enable oops_in_progress
> > > + * prior to invocation of console handlers.
> > > + */
> > > + ++oops_in_progress;
> > > + c->write(c, msg, msg_len);
> > > + --oops_in_progress;
> > > + }
> > > touch_nmi_watchdog();
> > > }
> > > }
> > > --
> > > 2.7.4
> > >
next prev parent reply other threads:[~2020-05-28 11:26 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-27 6:25 [PATCH v3 0/4] kdb: Improve console handling Sumit Garg
2020-05-27 6:25 ` [PATCH v3 1/4] kdb: Re-factor kdb_printf() message write code Sumit Garg
2020-05-27 8:29 ` Daniel Thompson
2020-05-27 10:01 ` Sumit Garg
2020-05-27 6:25 ` [PATCH v3 2/4] kdb: Check status of console prior to invoking handlers Sumit Garg
2020-05-27 14:26 ` Daniel Thompson
2020-05-27 6:25 ` [PATCH v3 3/4] kdb: Make kdb_printf robust to run in NMI context Sumit Garg
2020-05-27 14:26 ` Daniel Thompson
2020-05-28 7:42 ` Sumit Garg
2020-05-27 6:25 ` [PATCH v3 4/4] kdb: Switch kdb_msg_write() to use safer polling I/O Sumit Garg
2020-05-27 13:31 ` Daniel Thompson
2020-05-28 6:18 ` Sumit Garg
2020-05-28 11:26 ` Daniel Thompson [this message]
2020-05-28 14:57 ` Petr Mladek
2020-05-29 5:46 ` Sumit Garg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200528112620.a6zhgnkl2izuggsa@holly.lan \
--to=daniel.thompson@linaro.org \
--cc=dianders@chromium.org \
--cc=jason.wessel@windriver.com \
--cc=kgdb-bugreport@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=pmladek@suse.com \
--cc=sergey.senozhatsky@gmail.com \
--cc=sumit.garg@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®