Bluetooth: Fix nested sleeps
authorPeter Hurley <peter@hurleysoftware.com>
Fri, 23 Jan 2015 17:16:53 +0000 (12:16 -0500)
committerJohan Hedberg <johan.hedberg@intel.com>
Fri, 23 Jan 2015 18:29:42 +0000 (20:29 +0200)
commitdfb2fae7cd0a1aa13610b11d54203bcd3893da07
tree3aa293285c349233441ae31661c72773992e603e
parenta1443f5a273713d4bfda360e45aa6e1d14fe7324
Bluetooth: Fix nested sleeps

l2cap/rfcomm/sco_sock_accept() are wait loops which may acquire
sleeping locks. Since both wait loops and sleeping locks use
task_struct.state to sleep and wake, the nested sleeping locks
destroy the wait loop state.

Use the newly-minted wait_woken() and DEFINE_WAIT_FUNC() for the
wait loop. DEFINE_WAIT_FUNC() allows an alternate wake function
to be specified; in this case, the predefined scheduler function,
woken_wake_function(). This wait construct ensures wakeups will
not be missed without requiring the wait loop to set the
task state before condition evaluation. How this works:

 CPU 0                            |  CPU 1
                                  |
                                  | is <condition> set?
                                  | no
set <condition>                   |
                                  |
wake_up_interruptible             |
  woken_wake_function             |
    set WQ_FLAG_WOKEN             |
    try_to_wake_up                |
                                  | wait_woken
                                  |   set TASK_INTERRUPTIBLE
                                  |   WQ_FLAG_WOKEN? yes
                                  |   set TASK_RUNNING
                                  |
                                  | - loop -
  |
  | is <condition> set?
                                  | yes - exit wait loop

Fixes "do not call blocking ops when !TASK_RUNNING" warnings
in l2cap_sock_accept(), rfcomm_sock_accept() and sco_sock_accept().

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c