Return-Path: Message-ID: <1324511784.1965.189.camel@aeonflux> Subject: Re: [PATCH] Bluetooth: Fix deadlocks with sock lock and L2CAP timers locks From: Marcel Holtmann To: Ulisses Furquim Cc: linux-bluetooth@vger.kernel.org, padovan@profusion.mobi Date: Wed, 21 Dec 2011 15:56:24 -0800 In-Reply-To: <1324504956-16840-1-git-send-email-ulisses@profusion.mobi> References: <1324504956-16840-1-git-send-email-ulisses@profusion.mobi> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org List-ID: Hi Ulisses, > When cancelling a delayed work (timer) in L2CAP we can not sleep holding > the sock mutex otherwise we might deadlock with an L2CAP timer handler. > This is possible because RX/TX and L2CAP timers run in different workqueues. > The scenario below illustrates the problem. Thus we are now avoiding to > sleep on the timers locks. > > ====================================================== > [ INFO: possible circular locking dependency detected ] > 3.1.0-05270-ga978dc7-dirty #239 > ------------------------------------------------------- > kworker/1:1/873 is trying to acquire lock: > (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}, at: [] l2cap_chan_timeout+0x3c/0xe0 [bluetooth] > > but task is already holding lock: > ((&(&chan->chan_timer)->work)){+.+...}, at: [] process_one_work+0x126/0x450 > > which lock already depends on the new lock. > > the existing dependency chain (in reverse order) is: > > -> #1 ((&(&chan->chan_timer)->work)){+.+...}: > [] check_prevs_add+0xf6/0x170 > [] validate_chain+0x613/0x790 > [] __lock_acquire+0x4be/0xac0 > [] lock_acquire+0x8d/0xb0 > [] wait_on_work+0x4f/0x160 > [] __cancel_work_timer+0x73/0x80 > [] cancel_delayed_work_sync+0xd/0x10 > [] l2cap_chan_connect+0x22d/0x470 [bluetooth] > [] l2cap_sock_connect+0xb1/0x140 [bluetooth] > [] kernel_connect+0xb/0x10 > [] rfcomm_session_create+0x12a/0x1c0 [rfcomm] > [] __rfcomm_dlc_open+0x1c7/0x240 [rfcomm] > [] rfcomm_dlc_open+0x42/0x70 [rfcomm] > [] rfcomm_sock_connect+0x103/0x150 [rfcomm] > [] sys_connect+0xae/0xc0 > [] compat_sys_socketcall+0xb2/0x220 > [] sysenter_dispatch+0x7/0x30 > > -> #0 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}: > [] check_prev_add+0x6cd/0x6e0 > [] check_prevs_add+0xf6/0x170 > [] validate_chain+0x613/0x790 > [] __lock_acquire+0x4be/0xac0 > [] lock_acquire+0x8d/0xb0 > [] lock_sock_nested+0x8a/0xa0 > [] l2cap_chan_timeout+0x3c/0xe0 [bluetooth] > [] process_one_work+0x184/0x450 > [] worker_thread+0x15e/0x340 > [] kthread+0x96/0xa0 > [] kernel_thread_helper+0x4/0x10 > > other info that might help us debug this: > > Possible unsafe locking scenario: > > CPU0 CPU1 > ---- ---- > lock((&(&chan->chan_timer)->work)); > lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); > lock((&(&chan->chan_timer)->work)); > lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); > > *** DEADLOCK *** > > 2 locks held by kworker/1:1/873: > #0: (events){.+.+.+}, at: [] process_one_work+0x126/0x450 > #1: ((&(&chan->chan_timer)->work)){+.+...}, at: [] process_one_work+0x126/0x450 > > stack backtrace: > Pid: 873, comm: kworker/1:1 Not tainted 3.1.0-05270-ga978dc7-dirty #239 > Call Trace: > [] print_circular_bug+0xd2/0xe3 > [] check_prev_add+0x6cd/0x6e0 > [] check_prevs_add+0xf6/0x170 > [] validate_chain+0x613/0x790 > [] __lock_acquire+0x4be/0xac0 > [] ? lock_sock_nested+0x66/0xa0 > [] ? lock_release_nested+0x100/0x110 > [] ? lock_sock_nested+0x66/0xa0 > [] lock_acquire+0x8d/0xb0 > [] ? l2cap_chan_timeout+0x3c/0xe0 [bluetooth] > [] lock_sock_nested+0x8a/0xa0 > [] ? l2cap_chan_timeout+0x3c/0xe0 [bluetooth] > [] ? process_one_work+0x126/0x450 > [] l2cap_chan_timeout+0x3c/0xe0 [bluetooth] > [] process_one_work+0x184/0x450 > [] ? process_one_work+0x126/0x450 > [] ? l2cap_security_cfm+0x4e0/0x4e0 [bluetooth] > [] worker_thread+0x15e/0x340 > [] ? manage_workers+0x110/0x110 > [] kthread+0x96/0xa0 > [] kernel_thread_helper+0x4/0x10 > [] ? retint_restore_args+0xe/0xe > [] ? __init_kthread_worker+0x70/0x70 > [] ? gs_change+0xb/0xb > > Signed-off-by: Ulisses Furquim > --- > include/net/bluetooth/l2cap.h | 29 +++++++++++++++++++++-------- > net/bluetooth/l2cap_core.c | 29 +++++++++-------------------- > 2 files changed, 30 insertions(+), 28 deletions(-) Acked-by: Marcel Holtmann Regards Marcel