From 60af22d2ed490554cc92c8d0fed0b5b9cf687568 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 1 Jun 2010 22:53:06 +0200 Subject: tty: reorder ldisc locking We need to release the BTM in paste_selection() when sleeping in tty_ldisc_ref_wait to avoid deadlocks with tty_ldisc_enable. In tty_set_ldisc, we now always grab the BTM before taking the ldisc_mutex in order to avoid AB-BA deadlocks between the two. tty_ldisc_halt potentially blocks on a workqueue function that takes the BTM, so we must release the BTM before calling it. Signed-off-by: Arnd Bergmann Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/char/selection.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/char/selection.c') diff --git a/drivers/char/selection.c b/drivers/char/selection.c index 85211a3a5811..75889cd9375f 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c @@ -319,8 +319,13 @@ int paste_selection(struct tty_struct *tty) poke_blanked_console(); release_console_sem(); - ld = tty_ldisc_ref_wait(tty); - + ld = tty_ldisc_ref(tty); + if (!ld) { + tty_unlock(); + ld = tty_ldisc_ref_wait(tty); + tty_lock(); + } + add_wait_queue(&vc->paste_wait, &wait); while (sel_buffer && sel_buffer_lth > pasted) { set_current_state(TASK_INTERRUPTIBLE); -- cgit v1.2.3