V4L/DVB (7320): pvrusb2: Eliminate timer race during tear-down
authorMike Isely <isely@pobox.com>
Tue, 22 Apr 2008 17:45:45 +0000 (14:45 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 24 Apr 2008 17:07:48 +0000 (14:07 -0300)
The pvrusb2 tear-down logic was clearing two timers before stopping
its internal work queue.  That left a tiny window open where the work
queue might run after the timers are stopped, possibly starting them
again.  This could lead to dangling pointers and an oops.  Solution:
Kill the work queue first, then delete the timers.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/pvrusb2/pvrusb2-hdw.c

index f2d2677936b31f51e02280fc5bbe429064f20195..1dff2d04a5d9ca4dc83669df275e8c5cddacb05f 100644 (file)
@@ -2114,13 +2114,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
 {
        if (!hdw) return;
        pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
-       del_timer_sync(&hdw->quiescent_timer);
-       del_timer_sync(&hdw->encoder_wait_timer);
        if (hdw->workqueue) {
                flush_workqueue(hdw->workqueue);
                destroy_workqueue(hdw->workqueue);
                hdw->workqueue = NULL;
        }
+       del_timer_sync(&hdw->quiescent_timer);
+       del_timer_sync(&hdw->encoder_wait_timer);
        if (hdw->fw_buffer) {
                kfree(hdw->fw_buffer);
                hdw->fw_buffer = NULL;