From: Mike Isely Date: Tue, 22 Apr 2008 17:45:45 +0000 (-0300) Subject: V4L/DVB (7320): pvrusb2: Eliminate timer race during tear-down X-Git-Tag: v2.6.26-rc1~1084^2~346 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f59100a42576c49e2170e9dc04f8b7ac922a74d;p=linux-2.6 V4L/DVB (7320): pvrusb2: Eliminate timer race during tear-down 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 Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index f2d2677936..1dff2d04a5 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -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;