From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753534Ab3LRF0z (ORCPT ); Wed, 18 Dec 2013 00:26:55 -0500 Received: from mga09.intel.com ([134.134.136.24]:51715 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752650Ab3LRF0x (ORCPT ); Wed, 18 Dec 2013 00:26:53 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.95,505,1384329600"; d="scan'208";a="446106865" Subject: TTY/n_gsm: Removing the wrong tty_unlock/lock() in gsm_dlci_release() From: Chuansheng Liu To: gregkh@linuxfoundation.org, jslaby@suse.cz Cc: linux-kernel@vger.kernel.org, chao.bi@intel.com, chuansheng.liu@intel.com Content-Type: text/plain; charset="UTF-8" Date: Wed, 18 Dec 2013 13:30:11 +0800 Message-ID: <1387344611.3650.56.camel@cliu38-desktop-build> Mime-Version: 1.0 X-Mailer: Evolution 2.28.3 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit 4d9b109060f690f5c835(tty: Prevent deadlock in n_gsm driver) tried to close all the virtual ports synchronously before closing the phycial ports, so the tty_vhangup() is used. But the tty_unlock/lock() is wrong: tty_release tty_ldisc_release tty_lock_pair(tty, o_tty) < == Here the tty is for physical port tty_ldisc_kill gsmld_close gsm_cleanup_mux gsm_dlci_release tty = tty_port_tty_get(&dlci->port) < == Here the tty(s) are for virtual port They are different ttys, so before tty_vhangup(virtual tty), do not need to call the tty_unlock(virtual tty) at all which causes unbalanced unlock warning. When enabling mutex debugging option, we will hit the below warning also: [ 99.276903] ===================================== [ 99.282172] [ BUG: bad unlock balance detected! ] [ 99.287442] 3.10.20-261976-gaec5ba0 #44 Tainted: G O [ 99.293972] ------------------------------------- [ 99.299240] mmgr/152 is trying to release lock (&tty->legacy_mutex) at: [ 99.306693] [] mutex_unlock+0xd/0x10 [ 99.311669] but there are no more locks to release! [ 99.317131] [ 99.317131] other info that might help us debug this: [ 99.324440] 3 locks held by mmgr/152: [ 99.328542] #0: (&tty->legacy_mutex/1){......}, at: [] tty_lock_nested+0x40/0x90 [ 99.338116] #1: (&tty->ldisc_mutex){......}, at: [] tty_ldisc_kill+0x22/0xd0 [ 99.347284] #2: (&gsm->mutex){......}, at: [] gsm_cleanup_mux+0x73/0x170 [ 99.356060] [ 99.356060] stack backtrace: [ 99.360932] CPU: 0 PID: 152 Comm: mmgr Tainted: G O 3.10.20-261976-gaec5ba0 #44 [ 99.370086] ef4a4de0 ef4a4de0 ef4c1d98 c1b27b91 ef4c1db8 c1292655 c1dd10f5 c1b2dcad [ 99.378921] c1b2dcad ef4a4de0 ef4a528c ffffffff ef4c1dfc c12930dd 00000246 00000000 [ 99.387754] 00000000 00000000 c15e1926 00000000 00000001 ddfa7530 00000003 c1b2dcad [ 99.396588] Call Trace: [ 99.399326] [] dump_stack+0x16/0x18 [ 99.404307] [] print_unlock_imbalance_bug+0xe5/0xf0 [ 99.410840] [] ? mutex_unlock+0xd/0x10 [ 99.416110] [] ? mutex_unlock+0xd/0x10 [ 99.421382] [] lock_release_non_nested+0x1cd/0x210 [ 99.427818] [] ? gsm_destroy_network+0x36/0x130 [ 99.433964] [] ? mutex_unlock+0xd/0x10 [ 99.439235] [] lock_release+0x82/0x1c0 [ 99.444505] [] ? mutex_unlock+0xd/0x10 [ 99.449776] [] ? mutex_unlock+0xd/0x10 [ 99.455047] [] __mutex_unlock_slowpath+0x5f/0xd0 [ 99.461288] [] mutex_unlock+0xd/0x10 [ 99.466365] [] tty_unlock+0x21/0x50 [ 99.471345] [] gsm_cleanup_mux+0xc1/0x170 [ 99.476906] [] gsmld_close+0x52/0x90 [ 99.481983] [] tty_ldisc_close.isra.1+0x35/0x50 [ 99.488127] [] tty_ldisc_kill+0x2c/0xd0 [ 99.493494] [] tty_ldisc_release+0x2f/0x50 [ 99.499152] [] tty_release+0x37c/0x4b0 [ 99.504424] [] ? mutex_unlock+0xd/0x10 [ 99.509695] [] ? mutex_unlock+0xd/0x10 [ 99.514967] [] ? eventpoll_release_file+0x7e/0x90 [ 99.521307] [] __fput+0xd9/0x200 [ 99.525996] [] ____fput+0xd/0x10 [ 99.530685] [] task_work_run+0x81/0xb0 [ 99.535957] [] do_notify_resume+0x49/0x70 [ 99.541520] [] work_notifysig+0x29/0x31 [ 99.546897] ------------[ cut here ]------------ So here we can call tty_vhangup() directly which is for virtual port. Reviewed-by: Chao Bi Signed-off-by: Liu, Chuansheng --- drivers/tty/n_gsm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c0f76da..8187ae6 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1704,11 +1704,8 @@ static void gsm_dlci_release(struct gsm_dlci *dlci) gsm_destroy_network(dlci); mutex_unlock(&dlci->mutex); - /* tty_vhangup needs the tty_lock, so unlock and - relock after doing the hangup. */ - tty_unlock(tty); tty_vhangup(tty); - tty_lock(tty); + tty_port_tty_set(&dlci->port, NULL); tty_kref_put(tty); } -- 1.7.9.5