[PATCH 3/3] cec: correctly cancel delayed work when the CEC adapter is disabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hans Verkuil <hans.verkuil@xxxxxxxxx>

When cleaning up pending work from the wait_queue list, make sure to cancel the
delayed work. Otherwise nasty kernel oopses will occur when the timer goes off
and the cec_data struct has disappeared.

Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>
---
 drivers/staging/media/cec/cec.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/cec/cec.c b/drivers/staging/media/cec/cec.c
index 9a62aa2..c2a876e 100644
--- a/drivers/staging/media/cec/cec.c
+++ b/drivers/staging/media/cec/cec.c
@@ -393,13 +393,28 @@ static int cec_thread_func(void *_adap)
 							struct cec_data, list);
 				cec_data_cancel(data);
 			}
+			if (adap->transmitting)
+				cec_data_cancel(adap->transmitting);
+
+			/*
+			 * Cancel the pending timeout work. We have to unlock
+			 * the mutex when flushing the work since
+			 * cec_wait_timeout() will take it. This is OK since
+			 * no new entries can be added to wait_queue as long
+			 * as adap->transmitting is NULL, which it is due to
+			 * the cec_data_cancel() above.
+			 */
 			while (!list_empty(&adap->wait_queue)) {
 				data = list_first_entry(&adap->wait_queue,
 							struct cec_data, list);
+
+				if (!cancel_delayed_work(&data->work)) {
+					mutex_unlock(&adap->lock);
+					flush_scheduled_work();
+					mutex_lock(&adap->lock);
+				}
 				cec_data_cancel(data);
 			}
-			if (adap->transmitting)
-				cec_data_cancel(adap->transmitting);
 			goto unlock;
 		}
 
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux