rfcomm, sched/wait: Fix broken wait construct
rfcomm_run() is a tad broken in that is has a nested wait loop. One cannot rely on p->state for the outer wait because the inner wait will overwrite it. Fix this using the new wait_woken() facility. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Peter Hurley <peter@hurleysoftware.com> Cc: Alexander Holler <holler@ahsoftware.de> Cc: David S. Miller <davem@davemloft.net> Cc: Gustavo Padovan <gustavo@padovan.org> Cc: Joe Perches <joe@perches.com> Cc: Johan Hedberg <johan.hedberg@gmail.com> Cc: Libor Pechacek <lpechacek@suse.cz> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Marcel Holtmann <marcel@holtmann.org> Cc: Seung-Woo Kim <sw0312.kim@samsung.com> Cc: Vignesh Raman <Vignesh_Raman@mentor.com> Cc: linux-bluetooth@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
6b55fc63f4
commit
eedf7e47da
@ -101,11 +101,11 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
|
|||||||
#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
|
#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
|
||||||
#define __get_rpn_parity(line) (((line) >> 3) & 0x7)
|
#define __get_rpn_parity(line) (((line) >> 3) & 0x7)
|
||||||
|
|
||||||
|
static DECLARE_WAIT_QUEUE_HEAD(rfcomm_wq);
|
||||||
|
|
||||||
static void rfcomm_schedule(void)
|
static void rfcomm_schedule(void)
|
||||||
{
|
{
|
||||||
if (!rfcomm_thread)
|
wake_up_all(&rfcomm_wq);
|
||||||
return;
|
|
||||||
wake_up_process(rfcomm_thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- RFCOMM FCS computation ---- */
|
/* ---- RFCOMM FCS computation ---- */
|
||||||
@ -2086,24 +2086,22 @@ static void rfcomm_kill_listener(void)
|
|||||||
|
|
||||||
static int rfcomm_run(void *unused)
|
static int rfcomm_run(void *unused)
|
||||||
{
|
{
|
||||||
|
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||||
BT_DBG("");
|
BT_DBG("");
|
||||||
|
|
||||||
set_user_nice(current, -10);
|
set_user_nice(current, -10);
|
||||||
|
|
||||||
rfcomm_add_listener(BDADDR_ANY);
|
rfcomm_add_listener(BDADDR_ANY);
|
||||||
|
|
||||||
while (1) {
|
add_wait_queue(&rfcomm_wq, &wait);
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
while (!kthread_should_stop()) {
|
||||||
|
|
||||||
if (kthread_should_stop())
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Process stuff */
|
/* Process stuff */
|
||||||
rfcomm_process_sessions();
|
rfcomm_process_sessions();
|
||||||
|
|
||||||
schedule();
|
wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
|
||||||
}
|
}
|
||||||
__set_current_state(TASK_RUNNING);
|
remove_wait_queue(&rfcomm_wq, &wait);
|
||||||
|
|
||||||
rfcomm_kill_listener();
|
rfcomm_kill_listener();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user