mirror of https://gitee.com/openkylin/linux.git
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_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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue