summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-05-14 17:11:46 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2008-05-15 10:19:30 -0700
commit487ad7efbf6b0ec338cdfc2a7b0fbeb53f17a94c (patch)
treee2bc37cc97680403bf664a5944b10cdd907b9f10
parent8568dae21e186fbb111bbe6583033a33fe26f83d (diff)
downloadlinux-487ad7efbf6b0ec338cdfc2a7b0fbeb53f17a94c.tar.bz2
tty: fix BKL related leak and crash
Enabling the BKL to be lockdep tracked uncovered the following upstream kernel bug in the tty code, which caused a BKL reference leak: ================================================ [ BUG: lock held when returning to user space! ] ------------------------------------------------ dmesg/3121 is leaving the kernel with locks still held! 1 lock held by dmesg/3121: #0: (kernel_mutex){--..}, at: [<c02f34d9>] opost+0x24/0x194 this might explain some of the atomicity warnings and crashes that -tip tree testing has been experiencing since the BKL was converted back to a spinlock. Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/n_tty.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 19105ec203f7..8096389b0dc2 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -282,16 +282,20 @@ static int opost(unsigned char c, struct tty_struct *tty)
if (O_ONLRET(tty))
tty->column = 0;
if (O_ONLCR(tty)) {
- if (space < 2)
+ if (space < 2) {
+ unlock_kernel();
return -1;
+ }
tty_put_char(tty, '\r');
tty->column = 0;
}
tty->canon_column = tty->column;
break;
case '\r':
- if (O_ONOCR(tty) && tty->column == 0)
+ if (O_ONOCR(tty) && tty->column == 0) {
+ unlock_kernel();
return 0;
+ }
if (O_OCRNL(tty)) {
c = '\n';
if (O_ONLRET(tty))
@@ -303,10 +307,13 @@ static int opost(unsigned char c, struct tty_struct *tty)
case '\t':
spaces = 8 - (tty->column & 7);
if (O_TABDLY(tty) == XTABS) {
- if (space < spaces)
+ if (space < spaces) {
+ unlock_kernel();
return -1;
+ }
tty->column += spaces;
tty->ops->write(tty, " ", spaces);
+ unlock_kernel();
return 0;
}
tty->column += spaces;