Skip to content

Commit eedf7e4

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
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>
1 parent 6b55fc6 commit eedf7e4

File tree

1 file changed

+8
-10
lines changed

1 file changed

+8
-10
lines changed

net/bluetooth/rfcomm/core.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,11 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
101101
#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
102102
#define __get_rpn_parity(line) (((line) >> 3) & 0x7)
103103

104+
static DECLARE_WAIT_QUEUE_HEAD(rfcomm_wq);
105+
104106
static void rfcomm_schedule(void)
105107
{
106-
if (!rfcomm_thread)
107-
return;
108-
wake_up_process(rfcomm_thread);
108+
wake_up_all(&rfcomm_wq);
109109
}
110110

111111
/* ---- RFCOMM FCS computation ---- */
@@ -2086,24 +2086,22 @@ static void rfcomm_kill_listener(void)
20862086

20872087
static int rfcomm_run(void *unused)
20882088
{
2089+
DEFINE_WAIT_FUNC(wait, woken_wake_function);
20892090
BT_DBG("");
20902091

20912092
set_user_nice(current, -10);
20922093

20932094
rfcomm_add_listener(BDADDR_ANY);
20942095

2095-
while (1) {
2096-
set_current_state(TASK_INTERRUPTIBLE);
2097-
2098-
if (kthread_should_stop())
2099-
break;
2096+
add_wait_queue(&rfcomm_wq, &wait);
2097+
while (!kthread_should_stop()) {
21002098

21012099
/* Process stuff */
21022100
rfcomm_process_sessions();
21032101

2104-
schedule();
2102+
wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
21052103
}
2106-
__set_current_state(TASK_RUNNING);
2104+
remove_wait_queue(&rfcomm_wq, &wait);
21072105

21082106
rfcomm_kill_listener();
21092107

0 commit comments

Comments
 (0)