[PATCH] cx88: Prevent general protection fault on rmmod

2009-03-07 Thread Jean Delvare
When unloading the cx8800 driver I sometimes get a general protection
fault. Analysis revealed a race in cx88_ir_stop(). It can be solved by
using a delayed work instead of a timer for infrared input polling.

Signed-off-by: Jean Delvare kh...@linux-fr.org
---
Thanks to Trent's compatibility patches, we can go without the bunch of
#ifdef's my initial patch had.

 linux/drivers/media/video/cx88/cx88-input.c |   27 ---
 1 file changed, 8 insertions(+), 19 deletions(-)

--- v4l-dvb.orig/linux/drivers/media/video/cx88/cx88-input.c2009-03-05 
10:36:23.0 +0100
+++ v4l-dvb/linux/drivers/media/video/cx88/cx88-input.c 2009-03-06 
13:59:56.0 +0100
@@ -49,8 +49,7 @@ struct cx88_IR {
 
/* poll external decoder */
int polling;
-   struct work_struct work;
-   struct timer_list timer;
+   struct delayed_work work;
u32 gpio_addr;
u32 last_gpio;
u32 mask_keycode;
@@ -144,13 +143,6 @@ static void cx88_ir_handle_key(struct cx
}
 }
 
-static void ir_timer(unsigned long data)
-{
-   struct cx88_IR *ir = (struct cx88_IR *)data;
-
-   schedule_work(ir-work);
-}
-
 #if LINUX_VERSION_CODE  KERNEL_VERSION(2,6,20)
 static void cx88_ir_work(void *data)
 #else
@@ -160,23 +152,22 @@ static void cx88_ir_work(struct work_str
 #if LINUX_VERSION_CODE  KERNEL_VERSION(2,6,20)
struct cx88_IR *ir = data;
 #else
-   struct cx88_IR *ir = container_of(work, struct cx88_IR, work);
+   struct cx88_IR *ir = container_of(work, struct cx88_IR, work.work);
 #endif
 
cx88_ir_handle_key(ir);
-   mod_timer(ir-timer, jiffies + msecs_to_jiffies(ir-polling));
+   schedule_delayed_work(ir-work, msecs_to_jiffies(ir-polling));
 }
 
 void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
 {
if (ir-polling) {
-   setup_timer(ir-timer, ir_timer, (unsigned long)ir);
 #if LINUX_VERSION_CODE  KERNEL_VERSION(2,6,20)
-   INIT_WORK(ir-work, cx88_ir_work, ir);
+   INIT_DELAYED_WORK(ir-work, cx88_ir_work, ir);
 #else
-   INIT_WORK(ir-work, cx88_ir_work);
+   INIT_DELAYED_WORK(ir-work, cx88_ir_work);
 #endif
-   schedule_work(ir-work);
+   schedule_delayed_work(ir-work, 0);
}
if (ir-sampling) {
core-pci_irqmask |= PCI_INT_IR_SMPINT;
@@ -192,10 +183,8 @@ void cx88_ir_stop(struct cx88_core *core
core-pci_irqmask = ~PCI_INT_IR_SMPINT;
}
 
-   if (ir-polling) {
-   del_timer_sync(ir-timer);
-   flush_scheduled_work();
-   }
+   if (ir-polling)
+   cancel_delayed_work_sync(ir-work);
 }
 
 /* -- */


-- 
Jean Delvare
--
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


Re: [PATCH] cx88: Prevent general protection fault on rmmod

2009-03-05 Thread Trent Piepho
On Thu, 5 Mar 2009, Jean Delvare wrote:
 +#if LINUX_VERSION_CODE  KERNEL_VERSION(2,6,20)
   struct work_struct work;
   struct timer_list timer;
 +#else
 + struct delayed_work work;
 +#endif

You don't need this compat stuff.  compat.h will take are of it for you.
Just code it like you would for the latest kernel.  The only thing you need
to worry about is the way the third argument of the work function went
away, but the ifdef that's already there takes care of it.
--
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


Re: [PATCH] cx88: Prevent general protection fault on rmmod

2009-03-05 Thread Jean Delvare
On Thu, 5 Mar 2009 01:43:55 -0800 (PST), Trent Piepho wrote:
 On Thu, 5 Mar 2009, Jean Delvare wrote:
  +#if LINUX_VERSION_CODE  KERNEL_VERSION(2,6,20)
  struct work_struct work;
  struct timer_list timer;
  +#else
  +   struct delayed_work work;
  +#endif
 
 You don't need this compat stuff.  compat.h will take are of it for you.
 Just code it like you would for the latest kernel.  The only thing you need
 to worry about is the way the third argument of the work function went
 away, but the ifdef that's already there takes care of it.

OK, thanks. I'll resend updated patches soon.

-- 
Jean Delvare
--
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