* [PATCH] tty_ldisc: Fix BUG() on hangup
@ 2010-10-26 15:49 Philippe Rétornaz
2010-10-26 16:13 ` Alan Cox
0 siblings, 1 reply; 3+ messages in thread
From: Philippe Rétornaz @ 2010-10-26 15:49 UTC (permalink / raw)
To: Alan Cox; +Cc: Greg Kroah-Hartman, linux-kernel
Hello
A kernel BUG when bluetooth rfcomm connection drop while
the associated serial port is open is sometime triggered.
It seems that the line discipline can disappear between the tty_ldisc_put and
tty_ldisc_get. This patch fall back to the N_TTY line discipline if the
previous discipline is not available anymore.
This seem to fix the BUG(), but I don't know if it's correct.
Regards,
Philippe
---
--- linux-2.6.34.x86_64/drivers/char/tty_ldisc.c.orig 2010-05-16
23:17:36.000000000 +0200
+++ linux-2.6.34.x86_64/drivers/char/tty_ldisc.c 2010-10-15 10:48:01.871721197
+0200
@@ -712,9 +712,12 @@ static void tty_reset_termios(struct tty
* state closed
*/
-static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
+static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
{
- struct tty_ldisc *ld;
+ struct tty_ldisc *ld = tty_ldisc_get(ldisc);
+
+ if (IS_ERR(ld))
+ return -1;
tty_ldisc_close(tty, tty->ldisc);
tty_ldisc_put(tty->ldisc);
@@ -722,10 +725,10 @@ static void tty_ldisc_reinit(struct tty_
/*
* Switch the line discipline back
*/
- ld = tty_ldisc_get(ldisc);
- BUG_ON(IS_ERR(ld));
tty_ldisc_assign(tty, ld);
tty_set_termios_ldisc(tty, ldisc);
+
+ return 0;
}
/**
@@ -787,13 +790,16 @@ void tty_ldisc_hangup(struct tty_struct
a FIXME */
if (tty->ldisc) { /* Not yet closed */
if (reset == 0) {
- tty_ldisc_reinit(tty, tty->termios->c_line);
- err = tty_ldisc_open(tty, tty->ldisc);
+
+ if (!tty_ldisc_reinit(tty, tty->termios->c_line))
+ err = tty_ldisc_open(tty, tty->ldisc);
+ else
+ err = 1;
}
/* If the re-open fails or we reset then go to N_TTY. The
N_TTY open cannot fail */
if (reset || err) {
- tty_ldisc_reinit(tty, N_TTY);
+ BUG_ON(tty_ldisc_reinit(tty, N_TTY));
WARN_ON(tty_ldisc_open(tty, tty->ldisc));
}
tty_ldisc_enable(tty);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] tty_ldisc: Fix BUG() on hangup
2010-10-26 15:49 [PATCH] tty_ldisc: Fix BUG() on hangup Philippe Rétornaz
@ 2010-10-26 16:13 ` Alan Cox
2010-10-27 15:13 ` Philippe Rétornaz
0 siblings, 1 reply; 3+ messages in thread
From: Alan Cox @ 2010-10-26 16:13 UTC (permalink / raw)
To: Philippe Rétornaz; +Cc: Alan Cox, Greg Kroah-Hartman, linux-kernel
On Tue, 26 Oct 2010 17:49:03 +0200
Philippe Rétornaz <philippe.retornaz@epfl.ch> wrote:
> Hello
>
> A kernel BUG when bluetooth rfcomm connection drop while
> the associated serial port is open is sometime triggered.
>
> It seems that the line discipline can disappear between the tty_ldisc_put and
> tty_ldisc_get. This patch fall back to the N_TTY line discipline if the
> previous discipline is not available anymore.
>
> This seem to fix the BUG(), but I don't know if it's correct.
I can see what you are trying to handle, and in theory you could if you
unload modules as they go unused hit a race there - I'm amazed it's
possible however.
The first part looks right - grab the reference before changing over and
error if it isn't available, and the second part follows logically,
although that bit of the hangup code is looking even more untidy now.
Acked-by: Alan Cox <alan@linux.intel.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] tty_ldisc: Fix BUG() on hangup
2010-10-26 16:13 ` Alan Cox
@ 2010-10-27 15:13 ` Philippe Rétornaz
0 siblings, 0 replies; 3+ messages in thread
From: Philippe Rétornaz @ 2010-10-27 15:13 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: Alan Cox, linux-kernel
A kernel BUG when bluetooth rfcomm connection drop while
the associated serial port is open is sometime triggered.
It seems that the line discipline can disappear between the tty_ldisc_put and
tty_ldisc_get. This patch fall back to the N_TTY line discipline if the
previous discipline is not available anymore.
Signed-off-by: Philippe Retornaz <philippe.retornaz@epfl.ch>
Acked-by: Alan Cox <alan@linux.intel.com>
---
--- linux-2.6.34.x86_64/drivers/char/tty_ldisc.c.orig 2010-05-16 23:17:36.000000000 +0200
+++ linux-2.6.34.x86_64/drivers/char/tty_ldisc.c 2010-10-15 10:48:01.871721197 +0200
@@ -712,9 +712,12 @@ static void tty_reset_termios(struct tty
* state closed
*/
-static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
+static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
{
- struct tty_ldisc *ld;
+ struct tty_ldisc *ld = tty_ldisc_get(ldisc);
+
+ if (IS_ERR(ld))
+ return -1;
tty_ldisc_close(tty, tty->ldisc);
tty_ldisc_put(tty->ldisc);
@@ -722,10 +725,10 @@ static void tty_ldisc_reinit(struct tty_
/*
* Switch the line discipline back
*/
- ld = tty_ldisc_get(ldisc);
- BUG_ON(IS_ERR(ld));
tty_ldisc_assign(tty, ld);
tty_set_termios_ldisc(tty, ldisc);
+
+ return 0;
}
/**
@@ -787,13 +790,16 @@ void tty_ldisc_hangup(struct tty_struct
a FIXME */
if (tty->ldisc) { /* Not yet closed */
if (reset == 0) {
- tty_ldisc_reinit(tty, tty->termios->c_line);
- err = tty_ldisc_open(tty, tty->ldisc);
+
+ if (!tty_ldisc_reinit(tty, tty->termios->c_line))
+ err = tty_ldisc_open(tty, tty->ldisc);
+ else
+ err = 1;
}
/* If the re-open fails or we reset then go to N_TTY. The
N_TTY open cannot fail */
if (reset || err) {
- tty_ldisc_reinit(tty, N_TTY);
+ BUG_ON(tty_ldisc_reinit(tty, N_TTY));
WARN_ON(tty_ldisc_open(tty, tty->ldisc));
}
tty_ldisc_enable(tty);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-10-27 15:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-26 15:49 [PATCH] tty_ldisc: Fix BUG() on hangup Philippe Rétornaz
2010-10-26 16:13 ` Alan Cox
2010-10-27 15:13 ` Philippe Rétornaz
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).