--- core.c.orig 2012-12-05 15:27:10.746932278 +0000 +++ core.c 2012-12-20 15:47:51.260273748 +0000 @@ -680,16 +680,19 @@ static int hidp_session(void *arg) struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; wait_queue_t ctrl_wait, intr_wait; + wait_queue_head_t *ctrl_waithead, *intr_waithead; BT_DBG("session %p", session); __module_get(THIS_MODULE); set_user_nice(current, -15); + ctrl_waithead = sk_sleep(ctrl_sk); + intr_waithead = sk_sleep(intr_sk); init_waitqueue_entry(&ctrl_wait, current); init_waitqueue_entry(&intr_wait, current); - add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); - add_wait_queue(sk_sleep(intr_sk), &intr_wait); + add_wait_queue(ctrl_waithead, &ctrl_wait); + add_wait_queue(intr_waithead, &intr_wait); session->waiting_for_startup = 0; wake_up_interruptible(&session->startup_queue); set_current_state(TASK_INTERRUPTIBLE); @@ -722,8 +725,8 @@ static int hidp_session(void *arg) set_current_state(TASK_INTERRUPTIBLE); } set_current_state(TASK_RUNNING); - remove_wait_queue(sk_sleep(intr_sk), &intr_wait); - remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); + remove_wait_queue(intr_waithead, &intr_wait); + remove_wait_queue(ctrl_waithead, &ctrl_wait); clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); @@ -751,8 +754,11 @@ static int hidp_session(void *arg) fput(session->intr_sock->file); - wait_event_timeout(*(sk_sleep(ctrl_sk)), - (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); + /* By now ctrl_sk might have been orphaned already */ + if (ctrl_waithead == sk_sleep(ctrl_sk)) { + wait_event_timeout(*(ctrl_waithead), + (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500), ctrl_sk); + } fput(session->ctrl_sock->file);