Linus Torvalds 0b5759c654 tty: Avoid dropping ldisc_mutex over hangup tty re-initialization
A couple of people have hit the WARN_ON() in drivers/char/tty_io.c,
tty_open() that is unhappy about seeing the tty line discipline go away
during the tty hangup. See for example

	http://bugzilla.kernel.org/show_bug.cgi?id=14255

and the reason is that we do the tty_ldisc_halt() outside the
ldisc_mutex in order to be able to flush the scheduled work without a
deadlock with vhangup_work.

However, it turns out that we can solve this particular case by

 - using "cancel_delayed_work_sync()" in tty_ldisc_halt(), which waits
   for just the particular work, rather than synchronizing with any
   random outstanding pending work.

   This won't deadlock, since the buf.work we synchronize with doesn't
   care about the ldisc_mutex, it just flushes the tty ldisc buffers.

 - realize that for this particular case, we don't need to wait for any
   hangup work, because we are inside the hangup codepaths ourselves.

so as a result we can just drop the flush_scheduled_work() entirely, and
then move the tty_ldisc_halt() call to inside the mutex.  That way we
never expose the partially torn down ldisc state to tty_open(), and hold
the ldisc_mutex over the whole sequence.

Reported-by: Ingo Molnar <mingo@elte.hu>
Reported-by: Heinz Diehl <htd@fancy-poultry.org>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-10-03 21:44:21 -07:00
..
2009-06-11 08:51:01 -07:00
2009-09-24 07:21:03 -07:00
2009-09-22 07:17:42 -07:00
2009-07-12 12:22:34 -07:00
2008-06-20 14:05:55 -06:00
2008-12-13 11:25:49 -08:00
2009-10-01 16:11:16 -07:00
2008-10-20 08:52:41 -07:00
2008-12-13 09:12:07 +00:00
2009-06-19 16:46:06 -07:00
2009-09-21 15:14:58 +02:00
2008-07-20 17:12:36 -07:00
2008-06-20 14:05:57 -06:00
2009-06-18 11:16:55 +10:00
2009-01-02 10:28:32 -08:00
2009-07-12 12:22:34 -07:00
2009-09-15 08:42:00 -07:00
2009-09-27 11:39:25 -07:00
2009-09-23 07:39:29 -07:00
2009-07-12 12:22:34 -07:00
2009-07-12 12:22:34 -07:00
2009-07-12 12:22:34 -07:00
2009-07-20 16:38:43 -07:00
2009-06-18 13:03:54 -07:00
2009-09-19 13:13:37 -07:00
2008-07-20 17:12:38 -07:00
2009-07-12 12:22:34 -07:00
2009-01-08 16:44:03 -07:00
2009-02-22 09:23:02 -08:00
2009-06-11 08:51:01 -07:00
2009-03-16 08:34:35 -06:00
2008-07-20 17:12:38 -07:00
2009-07-12 12:22:34 -07:00
2009-09-01 01:13:31 -07:00
2009-09-01 01:13:31 -07:00
2009-09-01 01:13:31 -07:00
2009-07-03 15:45:29 +01:00
2008-06-20 14:05:51 -06:00
2008-04-30 23:15:34 +02:00
2009-06-11 08:51:02 -07:00
2009-09-19 13:13:35 -07:00
2009-09-19 13:13:36 -07:00
2009-09-23 22:26:32 +09:30
2009-10-01 16:11:12 -07:00
2009-09-19 13:13:35 -07:00