aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2014-10-29 11:17:12 -0400
committerIngo Molnar <mingo@kernel.org>2014-11-04 01:17:47 -0500
commiteedf7e47daa0b8530246a8c9107c007fbf8231bf (patch)
treee945f8690e964eb998089519a8aff192e090f494
parent6b55fc63f46ba299f3d84013e9232be4bd259eab (diff)
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>
-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);
101#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1) 101#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
102#define __get_rpn_parity(line) (((line) >> 3) & 0x7) 102#define __get_rpn_parity(line) (((line) >> 3) & 0x7)
103 103
104static DECLARE_WAIT_QUEUE_HEAD(rfcomm_wq);
105
104static void rfcomm_schedule(void) 106static void rfcomm_schedule(void)
105{ 107{
106 if (!rfcomm_thread) 108 wake_up_all(&rfcomm_wq);
107 return;
108 wake_up_process(rfcomm_thread);
109} 109}
110 110
111/* ---- RFCOMM FCS computation ---- */ 111/* ---- RFCOMM FCS computation ---- */
@@ -2086,24 +2086,22 @@ static void rfcomm_kill_listener(void)
2086 2086
2087static int rfcomm_run(void *unused) 2087static int rfcomm_run(void *unused)
2088{ 2088{
2089 DEFINE_WAIT_FUNC(wait, woken_wake_function);
2089 BT_DBG(""); 2090 BT_DBG("");
2090 2091
2091 set_user_nice(current, -10); 2092 set_user_nice(current, -10);
2092 2093
2093 rfcomm_add_listener(BDADDR_ANY); 2094 rfcomm_add_listener(BDADDR_ANY);
2094 2095
2095 while (1) { 2096 add_wait_queue(&rfcomm_wq, &wait);
2096 set_current_state(TASK_INTERRUPTIBLE); 2097 while (!kthread_should_stop()) {
2097
2098 if (kthread_should_stop())
2099 break;
2100 2098
2101 /* Process stuff */ 2099 /* Process stuff */
2102 rfcomm_process_sessions(); 2100 rfcomm_process_sessions();
2103 2101
2104 schedule(); 2102 wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
2105 } 2103 }
2106 __set_current_state(TASK_RUNNING); 2104 remove_wait_queue(&rfcomm_wq, &wait);
2107 2105
2108 rfcomm_kill_listener(); 2106 rfcomm_kill_listener();
2109 2107