From: Johan Hedberg Date: Thu, 2 Oct 2014 07:16:22 +0000 (+0300) Subject: Bluetooth: Fix lockdep warning with l2cap_chan_connect X-Git-Tag: fixes-against-v3.18-rc2~144^2~39^2~16^2~4 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=02e246aee868e982eecc25ee97d02acf2c2b8884;p=pandora-kernel.git Bluetooth: Fix lockdep warning with l2cap_chan_connect The L2CAP connection's channel list lock (conn->chan_lock) must never be taken while already holding a channel lock (chan->lock) in order to avoid lock-inversion and lockdep warnings. So far the l2cap_chan_connect function has acquired the chan->lock early in the function and then later called l2cap_chan_add(conn, chan) which will try to take the conn->chan_lock. This violates the correct order of taking the locks and may lead to the following type of lockdep warnings: -> #1 (&conn->chan_lock){+.+...}: [] lock_acquire+0x9d/0x140 [] mutex_lock_nested+0x6c/0x420 [] l2cap_chan_add+0x1e/0x40 [bluetooth] [] l2cap_chan_connect+0x348/0x8f0 [bluetooth] [] lowpan_control_write+0x221/0x2d0 [bluetooth_6lowpan] -> #0 (&chan->lock){+.+.+.}: [] __lock_acquire+0x1a18/0x1d20 [] lock_acquire+0x9d/0x140 [] mutex_lock_nested+0x6c/0x420 [] l2cap_connect_cfm+0x1dd/0x3f0 [bluetooth] [] hci_le_meta_evt+0x11a4/0x1260 [bluetooth] [] hci_event_packet+0x3ab/0x3120 [bluetooth] [] hci_rx_work+0x208/0x4a0 [bluetooth] CPU0 CPU1 ---- ---- lock(&conn->chan_lock); lock(&chan->lock); lock(&conn->chan_lock); lock(&chan->lock); Before calling l2cap_chan_add() the channel is not part of the conn->chan_l list, and can therefore only be accessed by the L2CAP user (such as l2cap_sock.c). We can therefore assume that it is the responsibility of the user to handle mutual exclusion until this point (which we can see is already true in l2cap_sock.c by it in many places touching chan members without holding chan->lock). Since the hci_conn and by exctension l2cap_conn creation in the l2cap_chan_connect() function depend on chan details we cannot simply add a mutex_lock(&conn->chan_lock) in the beginning of the function (since the conn object doesn't yet exist there). What we can do however is move the chan->lock taking later into the function where we already have the conn object and can that way take conn->chan_lock first. This patch implements the above strategy and does some other necessary changes such as using __l2cap_chan_add() which assumes conn->chan_lock is held, as well as adding a second needed label so the unlocking happens as it should. Reported-by: Jukka Rissanen Signed-off-by: Johan Hedberg Tested-by: Jukka Rissanen Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- Reading git-diff-tree failed