tty: Strengthen no-subsequent-use guarantee of tty_ldisc_halt()
In preparation for destructing and freeing the tty, the line discipline
must first be brought to an inactive state before it can be destructed.
This line discipline shutdown must:
- disallow new users of the ldisc
- wait for existing ldisc users to finish
- only then, cancel/flush their pending/running work
Factor tty_ldisc_wait_idle() from tty_set_ldisc() and tty_ldisc_kill()
to ensure this shutdown order.
Failure to provide this guarantee can result in scheduled work
running after the tty has already been freed, as indicated in the
following log message:
[ 88.331234] WARNING: at drivers/tty/tty_buffer.c:435 flush_to_ldisc+0x194/0x1d0()
[ 88.334505] Hardware name: Bochs
[ 88.335618] tty is bad=-1
[ 88.335703] Modules linked in: netconsole configfs bnep rfcomm bluetooth ......
[ 88.345272] Pid: 39, comm: kworker/1:1 Tainted: G W 3.7.0-next-
20121129+ttydebug-xeon #
20121129+ttydebug
[ 88.347736] Call Trace:
[ 88.349024] [<
ffffffff81058aff>] warn_slowpath_common+0x7f/0xc0
[ 88.350383] [<
ffffffff81058bf6>] warn_slowpath_fmt+0x46/0x50
[ 88.351745] [<
ffffffff81432bd4>] flush_to_ldisc+0x194/0x1d0
[ 88.353047] [<
ffffffff816f7fe1>] ? _raw_spin_unlock_irq+0x21/0x50
[ 88.354190] [<
ffffffff8108a809>] ? finish_task_switch+0x49/0xe0
[ 88.355436] [<
ffffffff81077ad1>] process_one_work+0x121/0x490
[ 88.357674] [<
ffffffff81432a40>] ? __tty_buffer_flush+0x90/0x90
[ 88.358954] [<
ffffffff81078c84>] worker_thread+0x164/0x3e0
[ 88.360247] [<
ffffffff81078b20>] ? manage_workers+0x120/0x120
[ 88.361282] [<
ffffffff8107e230>] kthread+0xc0/0xd0
[ 88.362284] [<
ffffffff816f0000>] ? cmos_do_probe+0x2eb/0x3bf
[ 88.363391] [<
ffffffff8107e170>] ? flush_kthread_worker+0xb0/0xb0
[ 88.364797] [<
ffffffff816fff6c>] ret_from_fork+0x7c/0xb0
[ 88.366087] [<
ffffffff8107e170>] ? flush_kthread_worker+0xb0/0xb0
[ 88.367266] ---[ end trace
453a7c9f38fbfec0 ]---
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>