summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2014-10-29 16:17:12 +0100
committerPeter Zijlstra <peterz@infradead.org>2014-11-04 15:54:11 +0100
commit41642dcaa1bbe60e5b1a01d6c00ec66fb0f9f757 (patch)
treee945f8690e964eb998089519a8aff192e090f494
parent7c5375fc8f5973fb86557eb419d6719cc9880e9e (diff)
rfcomm: 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. Cc: Marcel Holtmann <marcel@holtmann.org> Cc: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
-rw-r--r--net/bluetooth/rfcomm/core.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index af73bc3acb40..410dd5e76c41 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -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_parity(line) (((line) >> 3) & 0x7)
+static DECLARE_WAIT_QUEUE_HEAD(rfcomm_wq);
+
static void rfcomm_schedule(void)
{
- if (!rfcomm_thread)
- return;
- wake_up_process(rfcomm_thread);
+ wake_up_all(&rfcomm_wq);
}
/* ---- RFCOMM FCS computation ---- */
@@ -2086,24 +2086,22 @@ static void rfcomm_kill_listener(void)
static int rfcomm_run(void *unused)
{
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
BT_DBG("");
set_user_nice(current, -10);
rfcomm_add_listener(BDADDR_ANY);
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
-
- if (kthread_should_stop())
- break;
+ add_wait_queue(&rfcomm_wq, &wait);
+ while (!kthread_should_stop()) {
/* Process stuff */
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();