From: Hans Verkuil <hans.verk...@cisco.com>

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.verk...@cisco.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to